diff options
| author | Brad Allen <bradallen137@gmail.com> | 2011-03-16 22:55:10 -0400 |
|---|---|---|
| committer | Brad Allen <bradallen137@gmail.com> | 2011-03-16 22:55:10 -0400 |
| commit | b0af89284800af0f8c103b2ef8b2a94fda85bb4f (patch) | |
| tree | e86b0399a61544b279f3dac75cddda73b2fcaa6c /lib | |
| parent | 2b070a20c2ecf5bfcb85199467e07736f8988e81 (diff) | |
| download | sqlalchemy-b0af89284800af0f8c103b2ef8b2a94fda85bb4f.tar.gz | |
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.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/sqlalchemy/sql/visitors.py | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/lib/sqlalchemy/sql/visitors.py b/lib/sqlalchemy/sql/visitors.py index 0c6be97d7..2480341c5 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 |
