diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-11-02 17:37:12 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-11-03 13:56:02 -0500 |
commit | f016c1ac7f93d2f759aff53ec1494658efd7b496 (patch) | |
tree | 83f3e05b83d30c93d1e0beaf175dac38d33f54c7 /lib/sqlalchemy/sql/visitors.py | |
parent | e34886f137a3daf594d34cf5aa9b427de2ad6b98 (diff) | |
download | sqlalchemy-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.py | 35 |
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 |