Skip to content

Instantly share code, notes, and snippets.

@greut
Created March 3, 2009 21:38
Show Gist options
  • Select an option

  • Save greut/73542 to your computer and use it in GitHub Desktop.

Select an option

Save greut/73542 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
__author__ = "Yoan Blanc <yoan at dosimple dot ch>"
# Declarative syntax
class Declarative(type):
def __init__(cls, name, bases, dict):
super(Declarative, cls).__init__(name, bases, dict)
cls._matchers = {}
cls._reverse_matchers = {}
for k, v in dict.iteritems():
if isinstance(v, Child):
if v.matcher is None:
v.matcher = k
v.klass._parent = cls
cls._matchers[v.matcher] = v.klass
cls._reverse_matchers[v.klass] = v.matcher
class Child(object):
def __init__(self, matcher, klass=None):
if klass is None and issubclass(matcher, Resource):
self.matcher = None
self.klass = matcher
else:
self.matcher = matcher
self.klass = klass
class Resource(object):
__metaclass__ = Declarative
@classmethod
def _parents(cls):
if hasattr(cls, "_parent"):
return cls._parent._parents() + [cls._parent]
else:
return []
@classmethod
def _url(cls):
if hasattr(cls, "_parent"):
return cls._parent._url() + [cls._parent._reverse_matchers.get(cls, None)]
else:
return []
def __call__(self, *args):
return self._matchers.get(args[0], None)()(*args[1:])
# Test case
class Blig(Resource):
def __call__(self):
return "abc ;-)"
class Blag(Resource):
a = Child("c", Blig)
class Blog(Resource):
a = Child("b", Blag)
class Root(Resource):
a = Child(Blog)
assert Root._matchers == {"a": Blog}, "root matchers: %r" % Root._matchers
assert Blog._matchers == {"b": Blag}, "blog matchers: %r" % Blog._matchers
assert Blag._matchers == {"c": Blig}, "blag matchers: %r" % Blag._matchers
assert Blig._matchers == {}, "blig matchers: {}"
assert Blog._parent == Root, "blog parent: %r" % Blog._parent
assert Blag._parent == Blog, "blag parent: %r" % Blag._parent
assert Blig._parent == Blag, "blig parent: %r" % Blig._parent
assert Root._parents() == [], Root._parents()
assert Blog._parents() == [Root,], Blog._parents()
assert Blag._parents() == [Root, Blog], Blag._parents()
assert Blig._parents() == [Root, Blog, Blag], Blig._parents()
assert Root._url() == [], Root._url()
assert Blog._url() == ["a"], Blog._url()
assert Blag._url() == ["a", "b"], Blag._url()
assert Blig._url() == ["a", "b", "c"], Blig._url()
r = Root()
assert r(*"a/b/c".split("/")) == "abc ;-)"
assert "/".join(Blig._url()) == "a/b/c"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment