summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r--lib/sqlalchemy/sql/__init__.py11
-rw-r--r--lib/sqlalchemy/sql/annotation.py6
-rw-r--r--lib/sqlalchemy/sql/traversals.py7
-rw-r--r--lib/sqlalchemy/sql/visitors.py35
4 files changed, 26 insertions, 33 deletions
diff --git a/lib/sqlalchemy/sql/__init__.py b/lib/sqlalchemy/sql/__init__.py
index 8cfd20054..645189e76 100644
--- a/lib/sqlalchemy/sql/__init__.py
+++ b/lib/sqlalchemy/sql/__init__.py
@@ -55,10 +55,10 @@ from .expression import literal_column # noqa
from .expression import modifier # noqa
from .expression import not_ # noqa
from .expression import null # noqa
-from .expression import nullsfirst # noqa; deprecated 1.4; see #5435
-from .expression import nullslast # noqa; deprecated 1.4; see #5435
from .expression import nulls_first # noqa
from .expression import nulls_last # noqa
+from .expression import nullsfirst # noqa
+from .expression import nullslast # noqa
from .expression import or_ # noqa
from .expression import outerjoin # noqa
from .expression import outparam # noqa
@@ -106,7 +106,8 @@ def __go(lcls):
from .elements import AnnotatedColumnElement
from .elements import ClauseList # noqa
from .selectable import AnnotatedFromClause # noqa
- from .traversals import _preconfigure_traversals
+
+ # from .traversals import _preconfigure_traversals
from . import base
from . import coercions
@@ -133,7 +134,9 @@ def __go(lcls):
_prepare_annotations(FromClause, AnnotatedFromClause)
_prepare_annotations(ClauseList, Annotated)
- _preconfigure_traversals(ClauseElement)
+ # this is expensive at import time; elements that are used can create
+ # their traversals on demand
+ # _preconfigure_traversals(ClauseElement)
_sa_util.preloaded.import_prefix("sqlalchemy.sql")
diff --git a/lib/sqlalchemy/sql/annotation.py b/lib/sqlalchemy/sql/annotation.py
index 8a0d6ec28..94d37573c 100644
--- a/lib/sqlalchemy/sql/annotation.py
+++ b/lib/sqlalchemy/sql/annotation.py
@@ -354,9 +354,5 @@ def _new_annotation_type(cls, base_cls):
def _prepare_annotations(target_hierarchy, base_cls):
- stack = [target_hierarchy]
- while stack:
- cls = stack.pop()
- stack.extend(cls.__subclasses__())
-
+ for cls in util.walk_subclasses(target_hierarchy):
_new_annotation_type(cls, base_cls)
diff --git a/lib/sqlalchemy/sql/traversals.py b/lib/sqlalchemy/sql/traversals.py
index cb38df6af..a24d010cd 100644
--- a/lib/sqlalchemy/sql/traversals.py
+++ b/lib/sqlalchemy/sql/traversals.py
@@ -33,12 +33,7 @@ def compare(obj1, obj2, **kw):
def _preconfigure_traversals(target_hierarchy):
-
- stack = [target_hierarchy]
- while stack:
- cls = stack.pop()
- stack.extend(cls.__subclasses__())
-
+ for cls in util.walk_subclasses(target_hierarchy):
if hasattr(cls, "_traverse_internals"):
cls._generate_cache_attrs()
_copy_internals.generate_dispatch(
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