summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/visitors.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-03-13 21:07:09 -0700
committerMike Bayer <mike_mp@zzzcomputing.com>2012-03-13 21:07:09 -0700
commitbc3ea419b63f59ca0d079c89a563e1d391199731 (patch)
treefc1e2885824ab506e6b32a3a75d2bb639a0184d0 /lib/sqlalchemy/sql/visitors.py
parentbf57355feeb6f04d33ad778709f2fb39ad699aee (diff)
parentc280041477f385c5ddf1ed9587555aadc64346ce (diff)
downloadsqlalchemy-bc3ea419b63f59ca0d079c89a563e1d391199731.tar.gz
add most of Brad Allen's doc updates, [ticket:2434]
Diffstat (limited to 'lib/sqlalchemy/sql/visitors.py')
-rw-r--r--lib/sqlalchemy/sql/visitors.py36
1 files changed, 28 insertions, 8 deletions
diff --git a/lib/sqlalchemy/sql/visitors.py b/lib/sqlalchemy/sql/visitors.py
index cdcf40aa8..59ad29077 100644
--- a/lib/sqlalchemy/sql/visitors.py
+++ b/lib/sqlalchemy/sql/visitors.py
@@ -34,34 +34,54 @@ __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 the following::
+
+ 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 the class's __visit_name__ 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
+ _compiler_dispatch.__doc__ = \
+ """Look for an attribute named "visit_" + self.__visit_name__
+ on the visitor, and call it with the same kw params.
+ """
+ return _compiler_dispatch
class Visitable(object):
"""Base class for visitable objects, applies the