From: Brad Allen Date: Thu, 17 Mar 2011 02:55:10 +0000 (-0400) Subject: Slight sanity/clarity improvement to the way VisitableType binds the X-Git-Tag: rel_0_7_6~14^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b0af89284800af0f8c103b2ef8b2a94fda85bb4f;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Slight sanity/clarity improvement to the way VisitableType binds the _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. --- diff --git a/lib/sqlalchemy/sql/visitors.py b/lib/sqlalchemy/sql/visitors.py index 0c6be97d78..2480341c56 100644 --- a/lib/sqlalchemy/sql/visitors.py +++ b/lib/sqlalchemy/sql/visitors.py @@ -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