]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Fix overlapping slots, base classes without slots
authorArie Bovenberg <a.c.bovenberg@gmail.com>
Tue, 1 Feb 2022 20:08:19 +0000 (15:08 -0500)
committersqla-tester <sqla-tester@sqlalchemy.org>
Tue, 1 Feb 2022 20:08:19 +0000 (15:08 -0500)
Some `__slots__` were not in order.

Fixes #7527

### Description

I'm fixing two types of slots mistakes:
- [x] remove overlapping slots (i.e. slots already defined on a base class)
- [x] fix broken inheritance (i.e. slots class inheriting from a non-slots class)
  - [x] slots added to base class `TransactionalContext`. It seemed to use two attributes, which I've added as slots.
  - [x] empty slots removed from `ORMOption`. Its base class explicitly makes use of `__dict__` so empty slots don't add anything.
  - [x] empty slots added to `PostLoader`. It doesn't appear to use any slots not already defined on its base classes.
  - [x] empty slots added to `IterateMappersMixin`. It doesn't appear to use any slots not already defined on its subclasses.
  - [x] empty slots added to `ImmutableContainer`. It doesn't use any fields.
  - [x] empty slots added to `OperatorType`. It's a protocol.
  - [x] empty slots added to `InternalTraversal`, `_HasTraversalDispatch`. They don't seem to use attributes on their own.

### Checklist

This pull request is:

- [x] A short code fix
- please include the issue number, and create an issue if none exists, which
  must include a complete example of the issue.  one line code fixes without an
  issue and demonstration will not be accepted.
- Please include: `Fixes: #<issue number>` in the commit message
- please include tests.   one line code fixes without tests will not be accepted.

**Have a nice day!**

Closes: #7589
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/7589
Pull-request-sha: 70a9c4d46916b7c6907eb1d3ad4f7033ec964191

Change-Id: I6c6e3e69c3c34d0f3bdda7f0684849834fdd1863

12 files changed:
lib/sqlalchemy/cyextension/immutabledict.pyx
lib/sqlalchemy/dialects/mysql/aiomysql.py
lib/sqlalchemy/dialects/sqlite/aiosqlite.py
lib/sqlalchemy/engine/base.py
lib/sqlalchemy/engine/row.py
lib/sqlalchemy/engine/util.py
lib/sqlalchemy/orm/properties.py
lib/sqlalchemy/orm/strategies.py
lib/sqlalchemy/orm/unitofwork.py
lib/sqlalchemy/sql/base.py
lib/sqlalchemy/sql/operators.py
lib/sqlalchemy/sql/visitors.py

index d07c81bd49031abb0efc5a0e12cf983dc3b35011..861e7574da12cb3d7d74242bc07668b0bfb420e5 100644 (file)
@@ -6,6 +6,9 @@ def _immutable_fn(obj):
 
 
 class ImmutableContainer:
+
+    __slots__ = ()
+
     def _immutable(self, *a,**kw):
         _immutable_fn(self)
 
index 975467c24f788fd62d071ebc69019b16ee28fe8d..df716346efa4a48733a4d99d48f4a4a68144ea6e 100644 (file)
@@ -179,7 +179,7 @@ class AsyncAdapt_aiomysql_ss_cursor(AsyncAdapt_aiomysql_cursor):
 
 class AsyncAdapt_aiomysql_connection(AdaptedConnection):
     await_ = staticmethod(await_only)
-    __slots__ = ("dbapi", "_connection", "_execute_mutex")
+    __slots__ = ("dbapi", "_execute_mutex")
 
     def __init__(self, dbapi, connection):
         self.dbapi = dbapi
index c73afc9d1c2eb33d6e66cc6373871970f09e6595..e88ab1a0fa80fe83085ee532b5799453b1243c07 100644 (file)
@@ -165,7 +165,7 @@ class AsyncAdapt_aiosqlite_ss_cursor(AsyncAdapt_aiosqlite_cursor):
 
 class AsyncAdapt_aiosqlite_connection(AdaptedConnection):
     await_ = staticmethod(await_only)
-    __slots__ = ("dbapi", "_connection")
+    __slots__ = ("dbapi",)
 
     def __init__(self, dbapi, connection):
         self.dbapi = dbapi
index b67a212c83c935a66a2eb80130f40613a817961a..4045eae907e7fc1b1416d4b2b9e2c2df7ee2a1a6 100644 (file)
@@ -2257,7 +2257,7 @@ class TwoPhaseTransaction(RootTransaction):
 
     """
 
-    __slots__ = ("connection", "is_active", "xid", "_is_prepared")
+    __slots__ = ("xid", "_is_prepared")
 
     def __init__(self, connection, xid):
         self._is_prepared = False
index 16215ccc47c0cee1ceb2c40afd3124f1adfd0df6..75c56450e2b7846c612d64e71d2e4d7cf99aa984 100644 (file)
@@ -194,10 +194,7 @@ class ROMappingView(
     collections_abc.ValuesView,
     collections_abc.ItemsView,
 ):
-    __slots__ = (
-        "_mapping",
-        "_items",
-    )
+    __slots__ = ("_items",)
 
     def __init__(self, mapping, items):
         self._mapping = mapping
index 7e41339bbb4c727dfced86f2cf716793ec3b6266..f74cd3f8471ea9f00e46aed08ff3a976b7bc461d 100644 (file)
@@ -43,7 +43,7 @@ class TransactionalContext:
 
     """
 
-    _trans_subject = None
+    __slots__ = ("_outer_trans_ctx", "_trans_subject", "__weakref__")
 
     def _transaction_is_active(self):
         raise NotImplementedError()
@@ -95,7 +95,7 @@ class TransactionalContext:
         return self
 
     def __exit__(self, type_, value, traceback):
-        subject = self._trans_subject
+        subject = getattr(self, "_trans_subject", None)
 
         # simplistically we could assume that
         # "subject._trans_context_manager is self".  However, any calling
index c4aac5a3851cce6ed55f06959a1f18d3a3d56934..b035dbef2f2b6fc13aad5793cbc92a3c05174a99 100644 (file)
@@ -64,7 +64,6 @@ class ColumnProperty(StrategizedProperty[_T]):
         "descriptor",
         "active_history",
         "expire_on_flush",
-        "info",
         "doc",
         "strategy_key",
         "_creation_order",
index beaf649b785bea708d3e13ba4aa44de092c43060..07e71d4c0b7da058674700a3b16f38dd6ca05baa 100644 (file)
@@ -1165,6 +1165,8 @@ class LoadLazyAttribute:
 class PostLoader(AbstractRelationshipLoader):
     """A relationship loader that emits a second SELECT statement."""
 
+    __slots__ = ()
+
     def _check_recursive_postload(self, context, path, join_depth=None):
         effective_path = (
             context.compile_state.current_path or orm_util.PathRegistry.root
index e6cf3ad6b5d60027ca43bddd166564a44a45174c..b478f427cc9e203e9edb9812ef12ea645a5e1f54 100644 (file)
@@ -456,6 +456,9 @@ class UOWTransaction:
 
 
 class IterateMappersMixin:
+
+    __slots__ = ()
+
     def _mappers(self, uow):
         if self.fromparent:
             return iter(
index 8ae8f8f65fcbc8ce88f41865aa0884edacc97580..f4fe7afab27c241c068e225c9c215edbdc87119e 100644 (file)
@@ -639,6 +639,8 @@ class _MetaOptions(type):
 class Options(metaclass=_MetaOptions):
     """A cacheable option dictionary with defaults."""
 
+    __slots__ = ()
+
     def __init_subclass__(cls) -> None:
         dict_ = cls.__dict__
         cls._cache_attrs = tuple(
index cf61f263768730cab833650f27859c30cc14b12d..255e77b7f975364d645a61fdbe996c2b9d3a5dc3 100644 (file)
@@ -57,6 +57,8 @@ _T = TypeVar("_T", bound=Any)
 class OperatorType(Protocol):
     """describe an op() function."""
 
+    __slots__ = ()
+
     __name__: str
 
     def __call__(
index 78384782b80c17e83c55125fed35ecccfcb3d6ee..640c07d6182dce4d5ff3559cd18a14153e2ae194 100644 (file)
@@ -184,6 +184,8 @@ class _HasTraversalDispatch:
 
     """
 
+    __slots__ = ()
+
     def __init_subclass__(cls) -> None:
         cls._generate_traversal_dispatch()
         super().__init_subclass__()
@@ -299,6 +301,8 @@ class InternalTraversal(_HasTraversalDispatch):
 
     """
 
+    __slots__ = ()
+
     dp_has_cache_key = symbol("HC")
     """Visit a :class:`.HasCacheKey` object."""
 
@@ -504,6 +508,8 @@ class ExtendedInternalTraversal(InternalTraversal):
 
     """
 
+    __slots__ = ()
+
     dp_ignore = symbol("IG")
     """Specify an object that should be ignored entirely.