]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Slight sanity/clarity improvement to the way VisitableType binds the
authorBrad Allen <bradallen137@gmail.com>
Thu, 17 Mar 2011 02:55:10 +0000 (22:55 -0400)
committerBrad Allen <bradallen137@gmail.com>
Thu, 17 Mar 2011 02:55:10 +0000 (22:55 -0400)
_compiler_dispatch. This code change has no functional or performance
implications, but it helps make the docstring easier to write.

Mostly this commit is about docstring improvements and comments
to explain optimizations.

lib/sqlalchemy/sql/visitors.py

index 0c6be97d78a72d06824ac039cc5812795c8f963d..2480341c560c2cdeca8e74eca19e6b579f3a9d26 100644 (file)
@@ -34,34 +34,55 @@ __all__ = ['VisitableType', 'Visitable', 'ClauseVisitor',
     'cloned_traverse', 'replacement_traverse']
 
 class VisitableType(type):
-    """Metaclass which checks for a `__visit_name__` attribute and
-    applies `_compiler_dispatch` method to classes.
-
+    """Metaclass which assigns a `_compiler_dispatch` method to classes
+    having a `__visit_name__` attribute.
+    
+    The _compiler_dispatch attribute becomes an instance method which
+    looks approximately like this:
+    
+        def _compiler_dispatch (self, visitor, **kw):
+            '''Look for an attribute named "visit_" + self.__visit_name__
+            on the visitor, and call it with the same kw params.'''
+            return getattr(visitor, 'visit_%s' % self.__visit_name__)(self, **kw)
+
+    Classes having no __visit_name__ attribute will remain unaffected.
     """
-
     def __init__(cls, clsname, bases, clsdict):
         if cls.__name__ == 'Visitable' or not hasattr(cls, '__visit_name__'):
             super(VisitableType, cls).__init__(clsname, bases, clsdict)
             return
 
-        _generate_dispatch(cls)
+        cls._compiler_dispatch = _generate_dispatch(cls)
 
         super(VisitableType, cls).__init__(clsname, bases, clsdict)
 
+
 def _generate_dispatch(cls):
-    # set up an optimized visit dispatch function
-    # for use by the compiler
+    """Return an optimized visit dispatch function for the cls
+    for use by the compiler.
+    """
     if '__visit_name__' in cls.__dict__:
         visit_name = cls.__visit_name__
         if isinstance(visit_name, str):
+            # There is an optimization opportunity here because the
+            # the string name of is known at this early stage (import time)
+            # so it can be pre-constructed.
             getter = operator.attrgetter("visit_%s" % visit_name)
             def _compiler_dispatch(self, visitor, **kw):
                 return getter(visitor)(self, **kw)
         else:
+            # The optimization opportunity is lost for this case because the
+            # __visit_name__ is not yet a string. As a result, the visit
+            # string has to be recalculated with each compilation.
             def _compiler_dispatch(self, visitor, **kw):
                 return getattr(visitor, 'visit_%s' % self.__visit_name__)(self, **kw)
-
-        cls._compiler_dispatch = _compiler_dispatch
+        # build a nicely formatted docstring and attach to _compiler_dispatch
+        def docstring_container():
+            """Look for an attribute named "visit_" + self.__visit_name__
+            on the visitor, and call it with the same kw params.
+            """
+        _compiler_dispatch.__doc__ = docstring_container.__doc__
+        return _compiler_dispatch
 
 class Visitable(object):
     """Base class for visitable objects, applies the