Created
March 3, 2009 21:38
-
-
Save greut/73542 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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