changeset 1613:bc8a2546468b

Clean up registry code. Quite some boilerplate codes were removed. The signature of several `_factory` and `Entry.__call__` were changed a bit as well to make things a bit more uniform.
author Cheer Xiao <xiaqqaix@gmail.com>
date Wed, 01 Aug 2012 00:21:03 +0800
parents 707c7db1b645
children 5b5e7190452f
files MoinMoin/converter/__init__.py MoinMoin/items/__init__.py MoinMoin/items/content.py MoinMoin/util/registry.py
diffstat 4 files changed, 35 insertions(+), 109 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/converter/__init__.py	Sun Jul 29 18:26:20 2012 +0800
+++ b/MoinMoin/converter/__init__.py	Wed Aug 01 00:21:03 2012 +0800
@@ -19,31 +19,19 @@
 """
 
 
+from collections import namedtuple
+
 from ..util.registry import RegistryBase
 from ..util.pysupport import load_package_modules
 
 
 class RegistryConverter(RegistryBase):
-    class Entry(object):
-        def __init__(self, factory, type_input, type_output, priority):
-            self.factory = factory
-            self.type_input = type_input
-            self.type_output = type_output
-            self.priority = priority
-
-        def __call__(self, type_input, type_output, kw):
+    class Entry(namedtuple('Entry', 'factory type_input type_output priority')):
+        def __call__(self, type_input, type_output, **kw):
             if (self.type_output.issupertype(type_output) and
                 self.type_input.issupertype(type_input)):
                 return self.factory(type_input, type_output, **kw)
 
-        def __eq__(self, other):
-            if isinstance(other, self.__class__):
-                return (self.factory == other.factory and
-                        self.type_input == other.type_input and
-                        self.type_output == other.type_output and
-                        self.priority == other.priority)
-            return NotImplemented
-
         def __lt__(self, other):
             if isinstance(other, self.__class__):
                 if self.priority < other.priority:
@@ -55,19 +43,6 @@
                 return False
             return NotImplemented
 
-        def __repr__(self):
-            return '<{0}: input {1}, output {2}, prio {3} [{4!r}]>' % (self.__class__.__name__,
-                    self.type_input,
-                    self.type_output,
-                    self.priority,
-                    self.factory)
-
-    def get(self, type_input, type_output, **kw):
-        for entry in self._entries:
-            conv = entry(type_input, type_output, kw)
-            if conv is not None:
-                return conv
-
     def register(self, factory, type_input, type_output, priority=RegistryBase.PRIORITY_MIDDLE):
         """
         Register a factory
--- a/MoinMoin/items/__init__.py	Sun Jul 29 18:26:20 2012 +0800
+++ b/MoinMoin/items/__init__.py	Wed Aug 01 00:21:03 2012 +0800
@@ -20,6 +20,8 @@
 import re, time
 import itertools
 from StringIO import StringIO
+from collections import namedtuple
+from functools import partial
 
 from flatland import Form
 from flatland.validation import Validator
@@ -68,22 +70,10 @@
 
 
 class RegistryItem(RegistryBase):
-    class Entry(object):
-        def __init__(self, factory, itemtype, priority):
-            self.factory = factory
-            self.itemtype = itemtype
-            self.priority = priority
-
-        def __call__(self, name, itemtype, kw):
+    class Entry(namedtuple('Entry', 'factory itemtype priority')):
+        def __call__(self, itemtype, *args, **kw):
             if self.itemtype == itemtype:
-                return self.factory(name, itemtype, **kw)
-
-        def __eq__(self, other):
-            if isinstance(other, self.__class__):
-                return (self.factory == other.factory and
-                        self.itemtype == other.itemtype and
-                        self.priority == other.priority)
-            return NotImplemented
+                return self.factory(*args, **kw)
 
         def __lt__(self, other):
             if isinstance(other, self.__class__):
@@ -92,17 +82,6 @@
                 return self.itemtype == other.itemtype
             return NotImplemented
 
-        def __repr__(self):
-            return '<{0}: {1}, prio {2} [{3!r}]>'.format(self.__class__.__name__,
-                    self.itemtype,
-                    self.priority,
-                    self.factory)
-
-    def get(self, name, itemtype, **kw):
-        for entry in self._entries:
-            item = entry(name, itemtype, kw)
-            if item is not None:
-                return item
 
     def register(self, factory, itemtype, priority=RegistryBase.PRIORITY_MIDDLE):
         """
@@ -156,8 +135,8 @@
 class Item(object):
     """ Highlevel (not storage) Item, wraps around a storage Revision"""
     @classmethod
-    def _factory(cls, name=u'', itemtype=None, **kw):
-        return cls(name, **kw)
+    def _factory(cls, *args, **kw):
+        return cls(*args, **kw)
 
     # TODO split Content creation to Content.create
     @classmethod
@@ -214,13 +193,13 @@
 
         # XXX Cannot pass item=item to Content.__init__ via
         # content_registry.get yet, have to patch it later.
-        content = content_registry.get(name, Type(contenttype))
+        content = content_registry.get(contenttype)
         logging.debug("Content class {0!r} handles {1!r}".format(content.__class__, contenttype))
 
         itemtype = rev.meta.get(ITEMTYPE) or itemtype
         logging.debug("Item {0!r}, got itemtype {1!r} from revision meta".format(name, itemtype))
 
-        item = item_registry.get(name, itemtype, rev=rev, content=content)
+        item = item_registry.get(itemtype, name, rev=rev, content=content)
         logging.debug("Item class {0!r} handles {1!r}".format(item.__class__, itemtype))
 
         content.item = item
--- a/MoinMoin/items/content.py	Sun Jul 29 18:26:20 2012 +0800
+++ b/MoinMoin/items/content.py	Wed Aug 01 00:21:03 2012 +0800
@@ -23,6 +23,9 @@
 import tempfile
 from StringIO import StringIO
 from array import array
+from collections import namedtuple
+from functools import partial
+from types import TypeType
 
 from werkzeug import is_resource_modified
 
@@ -72,25 +75,11 @@
 ROWS_DATA = 20
 
 
-# XXX Too much boilerplate in Entry implementation. Maybe use namedtuple
-# as a starting point?
 class RegistryContent(RegistryBase):
-    class Entry(object):
-        def __init__(self, factory, content_type, priority):
-            self.factory = factory
-            self.content_type = content_type
-            self.priority = priority
-
-        def __call__(self, name, content_type, kw):
-            if self.content_type.issupertype(content_type):
-                return self.factory(name, content_type, **kw)
-
-        def __eq__(self, other):
-            if isinstance(other, self.__class__):
-                return (self.factory == other.factory and
-                        self.content_type == other.content_type and
-                        self.priority == other.priority)
-            return NotImplemented
+    class Entry(namedtuple('Entry', 'factory content_type priority')):
+        def __call__(self, content_type, *args, **kw):
+            if self.content_type.issupertype(Type(content_type)):
+                return self.factory(content_type, *args, **kw)
 
         def __lt__(self, other):
             if isinstance(other, self.__class__):
@@ -101,17 +90,7 @@
                 return False
             return NotImplemented
 
-        def __repr__(self):
-            return '<{0}: {1}, prio {2} [{3!r}]>'.format(self.__class__.__name__,
-                    self.content_type,
-                    self.priority,
-                    self.factory)
 
-    def get(self, name, content_type, **kw):
-        for entry in self._entries:
-            item = entry(name, content_type, kw)
-            if item is not None:
-                return item
 
     def register(self, factory, content_type, priority=RegistryBase.PRIORITY_MIDDLE):
         """
@@ -140,15 +119,16 @@
     data.
     """
     @classmethod
-    def _factory(cls, name=u'', contenttype=None, **kw):
-        return cls(name, contenttype=unicode(contenttype), **kw)
+    def _factory(cls, *args, **kw):
+        return cls(*args, **kw)
 
-    def __init__(self, item, contenttype=None):
+    def __init__(self, contenttype, item=None):
+        # We need to keep the exact contenttype since contents may be handled
+        # by a Content subclass with wildcard contenttype (eg. an unknown
+        # contenttype some/type gets handled by Binary)
+        # TODO use Type instead of strings?
+        self.contenttype = contenttype
         self.item = item
-        # TODO gradually remove self.contenttype as theoretically there is
-        # one-to-one correspondance of contenttype and Content type
-        # (pun intended :)
-        self.contenttype = contenttype
 
     # XXX For backward-compatibility (so code can be moved from Item
     # untouched), remove soon
--- a/MoinMoin/util/registry.py	Sun Jul 29 18:26:20 2012 +0800
+++ b/MoinMoin/util/registry.py	Wed Aug 01 00:21:03 2012 +0800
@@ -10,6 +10,9 @@
 """
 
 
+from collections import namedtuple
+
+
 class RegistryBase(object):
     PRIORITY_REALLY_FIRST = -20
     PRIORITY_FIRST = -10
@@ -17,26 +20,15 @@
     PRIORITY_LAST = 10
     PRIORITY_REALLY_LAST = 20
 
-    class Entry(object):
-        def __init__(self, factory, priority):
-            self.factory, self.priority = factory, priority
-
-        def __eq__(self, other):
-            if isinstance(other, self.__class__):
-                return (self.factory == other.factory and
-                        self.priority == other.priority)
-            return NotImplemented
+    class Entry(namedtuple('Entry', 'factory priority')):
+        def __call__(self, *args, **kw):
+            return self.factory(*args, **kw)
 
         def __lt__(self, other):
             if isinstance(other, self.__class__):
                 return self.priority < other.priority
             return NotImplemented
 
-        def __repr__(self):
-            return '<{0}: prio {1} [{2!r}]>'.format(self.__class__.__name__,
-                    self.priority,
-                    self.factory)
-
     def __init__(self):
         self._entries = []
 
@@ -51,7 +43,7 @@
         the first matching wins.
         """
         for entry in self._entries:
-            conv = entry.factory(*args, **kw)
+            conv = entry(*args, **kw)
             if conv is not None:
                 return conv