summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/visitors.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-11-02 17:37:12 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2020-11-03 13:56:02 -0500
commitf016c1ac7f93d2f759aff53ec1494658efd7b496 (patch)
tree83f3e05b83d30c93d1e0beaf175dac38d33f54c7 /lib/sqlalchemy/sql/visitors.py
parente34886f137a3daf594d34cf5aa9b427de2ad6b98 (diff)
downloadsqlalchemy-f016c1ac7f93d2f759aff53ec1494658efd7b496.tar.gz
Reduce import time overhead
* Fix subclass traversals to not run classes multiple times * switch compiler visitor to use an attrgetter, to avoid an eval() at startup time * don't pre-generate traversal functions, there's lots of these which are expensive to generate at once and most applications won't use them all; have it generate them on first use instead * Some ideas about removing asyncio imports, they don't seem to be too signficant, apply some more simplicity to the overall "greenlet fallback" situation Fixes: #5681 Change-Id: Ib564ddaddb374787ce3e11ff48026e99ed570933
Diffstat (limited to 'lib/sqlalchemy/sql/visitors.py')
-rw-r--r--lib/sqlalchemy/sql/visitors.py35
1 files changed, 17 insertions, 18 deletions
diff --git a/lib/sqlalchemy/sql/visitors.py b/lib/sqlalchemy/sql/visitors.py
index 27499b5f7..43b7cb4af 100644
--- a/lib/sqlalchemy/sql/visitors.py
+++ b/lib/sqlalchemy/sql/visitors.py
@@ -24,6 +24,7 @@ http://techspot.zzzeek.org/2008/01/23/expression-transformations/ .
"""
from collections import deque
+import operator
from .. import exc
from .. import util
@@ -63,26 +64,24 @@ def _generate_compiler_dispatch(cls):
% cls.__name__
)
- code = (
- "def _compiler_dispatch(self, visitor, **kw):\n"
- " try:\n"
- " meth = visitor.visit_%(name)s\n"
- " except AttributeError as err:\n"
- " util.raise_(\n"
- " exc.UnsupportedCompilationError(visitor, cls), \n"
- " replace_context=err)\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"
- )
+ name = "visit_%s" % visit_name
+ getter = operator.attrgetter(name)
+
+ def _compiler_dispatch(self, visitor, **kw):
+ """Look for an attribute named "visit_<visit_name>" on the
+ visitor, and call it with the same kw params.
- _compiler_dispatch.__doc__ = """Look for an attribute named "visit_"
- + self.__visit_name__ on the visitor, and call it with the same
- kw params.
"""
+ try:
+ meth = getter(visitor)
+ except AttributeError as err:
+ util.raise_(
+ exc.UnsupportedCompilationError(visitor, cls),
+ replace_context=err,
+ )
+ else:
+ return meth(self, **kw)
+
cls._compiler_dispatch = (
cls._original_compiler_dispatch
) = _compiler_dispatch