diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-03-13 21:07:09 -0700 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-03-13 21:07:09 -0700 |
| commit | bc3ea419b63f59ca0d079c89a563e1d391199731 (patch) | |
| tree | fc1e2885824ab506e6b32a3a75d2bb639a0184d0 /lib/sqlalchemy/sql/visitors.py | |
| parent | bf57355feeb6f04d33ad778709f2fb39ad699aee (diff) | |
| parent | c280041477f385c5ddf1ed9587555aadc64346ce (diff) | |
| download | sqlalchemy-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.py | 36 |
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 |
