summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/visitors.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-02-28 14:56:25 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2020-03-01 19:32:48 -0500
commitca2e4f385802799c2584782a8528e19a9e5513bc (patch)
tree0846dd8618b2bc7263cd8c0a309801a94d06f92a /lib/sqlalchemy/sql/visitors.py
parent132006ba8a714199d4f761b0e66fc2e516e46ba3 (diff)
downloadsqlalchemy-ca2e4f385802799c2584782a8528e19a9e5513bc.tar.gz
Discontinue dynamic __visit_name__
Removed very antiquated logic that checks if __visit_name__ is a property. There's no need for this as the compiler can handle switching between implementations. Convert _compile_dispatch() to be fully inlined. Change-Id: Ic0c7247c2d7dfed93a27f09250a8ed6352370764
Diffstat (limited to 'lib/sqlalchemy/sql/visitors.py')
-rw-r--r--lib/sqlalchemy/sql/visitors.py47
1 files changed, 20 insertions, 27 deletions
diff --git a/lib/sqlalchemy/sql/visitors.py b/lib/sqlalchemy/sql/visitors.py
index c946bb4ab..77e6b53a8 100644
--- a/lib/sqlalchemy/sql/visitors.py
+++ b/lib/sqlalchemy/sql/visitors.py
@@ -24,7 +24,6 @@ http://techspot.zzzeek.org/2008/01/23/expression-transformations/ .
"""
from collections import deque
-import operator
from .. import exc
from .. import util
@@ -53,32 +52,26 @@ def _generate_compiler_dispatch(cls):
"""
visit_name = cls.__visit_name__
- if isinstance(visit_name, util.compat.string_types):
- # 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):
- try:
- meth = getter(visitor)
- except AttributeError:
- raise exc.UnsupportedCompilationError(visitor, cls)
- else:
- return meth(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):
- visit_attr = "visit_%s" % self.__visit_name__
- try:
- meth = getattr(visitor, visit_attr)
- except AttributeError:
- raise exc.UnsupportedCompilationError(visitor, cls)
- else:
- return meth(self, **kw)
+ if not isinstance(visit_name, util.compat.string_types):
+ raise exc.InvalidRequestError(
+ "__visit_name__ on class %s must be a string at the class level"
+ % cls.__name__
+ )
+
+ code = (
+ "def _compiler_dispatch(self, visitor, **kw):\n"
+ " try:\n"
+ " meth = visitor.visit_%(name)s\n"
+ " except AttributeError:\n"
+ " util.raise_from_cause(\n"
+ " exc.UnsupportedCompilationError(visitor, cls))\n"
+ " else:\n"
+ " return meth(self, **kw)\n"
+ ) % {"name": visit_name}
+
+ _compiler_dispatch = langhelpers._exec_code_in_env(
+ code, {"exc": exc, "cls": cls, "util": util}, "_compiler_dispatch"
+ )
_compiler_dispatch.__doc__ = """Look for an attribute named "visit_"
+ self.__visit_name__ on the visitor, and call it with the same