diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2022-12-08 00:25:34 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@ci3.zzzcomputing.com> | 2022-12-08 00:25:34 +0000 |
| commit | caccf151f2e1b357fa2a5d37135580ce9931eec2 (patch) | |
| tree | cb2f1bbe0cc4b49d0a99f3d3a48285a5ff4d4066 /lib/sqlalchemy/sql | |
| parent | 3d8d366e1b5e2f0caa728a741dad5e467b67c7ac (diff) | |
| parent | 66c6b8558a6b64820b790199816acc66deffdacc (diff) | |
| download | sqlalchemy-caccf151f2e1b357fa2a5d37135580ce9931eec2.tar.gz | |
Merge "disable polymorphic adaption in most cases" into main
Diffstat (limited to 'lib/sqlalchemy/sql')
| -rw-r--r-- | lib/sqlalchemy/sql/util.py | 51 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/visitors.py | 13 |
2 files changed, 40 insertions, 24 deletions
diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index d162428ec..bef4372ec 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -12,6 +12,7 @@ from __future__ import annotations from collections import deque +import copy from itertools import chain import typing from typing import AbstractSet @@ -1064,6 +1065,16 @@ class ClauseAdapter(visitors.ReplacingExternalTraversal): """ + __slots__ = ( + "__traverse_options__", + "selectable", + "include_fn", + "exclude_fn", + "equivalents", + "adapt_on_names", + "adapt_from_selectables", + ) + def __init__( self, selectable: Selectable, @@ -1136,6 +1147,11 @@ class ClauseAdapter(visitors.ReplacingExternalTraversal): # TODO: cython candidate + if self.include_fn and not self.include_fn(col): # type: ignore + return None + elif self.exclude_fn and self.exclude_fn(col): # type: ignore + return None + if isinstance(col, FromClause) and not isinstance( col, functions.FunctionElement ): @@ -1173,6 +1189,7 @@ class ClauseAdapter(visitors.ReplacingExternalTraversal): # however the logic to check this moved here as of #7154 so that # it is made specific to SQL rewriting and not all column # correspondence + return None if "adapt_column" in col._annotations: @@ -1191,14 +1208,9 @@ class ClauseAdapter(visitors.ReplacingExternalTraversal): if TYPE_CHECKING: assert isinstance(col, KeyedColumnElement) - if self.include_fn and not self.include_fn(col): - return None - elif self.exclude_fn and self.exclude_fn(col): - return None - else: - return self._corresponding_column( # type: ignore - col, require_embedded=True - ) + return self._corresponding_column( # type: ignore + col, require_embedded=True + ) class _ColumnLookup(Protocol): @@ -1253,6 +1265,14 @@ class ColumnAdapter(ClauseAdapter): """ + __slots__ = ( + "columns", + "adapt_required", + "allow_label_resolve", + "_wrap", + "__weakref__", + ) + columns: _ColumnLookup def __init__( @@ -1267,8 +1287,7 @@ class ColumnAdapter(ClauseAdapter): anonymize_labels: bool = False, adapt_from_selectables: Optional[AbstractSet[FromClause]] = None, ): - ClauseAdapter.__init__( - self, + super().__init__( selectable, equivalents, include_fn=include_fn, @@ -1301,8 +1320,7 @@ class ColumnAdapter(ClauseAdapter): return self.columns[key] def wrap(self, adapter): - ac = self.__class__.__new__(self.__class__) - ac.__dict__.update(self.__dict__) + ac = copy.copy(self) ac._wrap = adapter ac.columns = util.WeakPopulateDict(ac._locate_col) # type: ignore if ac.include_fn or ac.exclude_fn: @@ -1391,15 +1409,6 @@ class ColumnAdapter(ClauseAdapter): return c - def __getstate__(self): - d = self.__dict__.copy() - del d["columns"] - return d - - def __setstate__(self, state): - self.__dict__.update(state) - self.columns = util.WeakPopulateDict(self._locate_col) # type: ignore - def _offset_or_limit_clause( element: Union[int, _ColumnExpressionArgument[int]], diff --git a/lib/sqlalchemy/sql/visitors.py b/lib/sqlalchemy/sql/visitors.py index 737107844..b820cf9d1 100644 --- a/lib/sqlalchemy/sql/visitors.py +++ b/lib/sqlalchemy/sql/visitors.py @@ -656,7 +656,7 @@ class _TraverseTransformCallableType(Protocol[_ET]): _ExtT = TypeVar("_ExtT", bound="ExternalTraversal") -class ExternalTraversal: +class ExternalTraversal(util.MemoizedSlots): """Base class for visitor objects which can traverse externally using the :func:`.visitors.traverse` function. @@ -665,6 +665,8 @@ class ExternalTraversal: """ + __slots__ = ("_visitor_dict", "_next") + __traverse_options__: Dict[str, Any] = {} _next: Optional[ExternalTraversal] @@ -698,8 +700,9 @@ class ExternalTraversal: return traverse(obj, self.__traverse_options__, self._visitor_dict) - @util.memoized_property - def _visitor_dict(self) -> Dict[str, _TraverseCallableType[Any]]: + def _memoized_attr__visitor_dict( + self, + ) -> Dict[str, _TraverseCallableType[Any]]: visitors = {} for name in dir(self): @@ -737,6 +740,8 @@ class CloningExternalTraversal(ExternalTraversal): """ + __slots__ = () + def copy_and_process( self, list_: List[ExternallyTraversible] ) -> List[ExternallyTraversible]: @@ -773,6 +778,8 @@ class ReplacingExternalTraversal(CloningExternalTraversal): """ + __slots__ = () + def replace( self, elem: ExternallyTraversible ) -> Optional[ExternallyTraversible]: |
