]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
done
authorabebus <anamaev263@gmail.com>
Mon, 20 Oct 2025 20:45:44 +0000 (23:45 +0300)
committerabebus <anamaev263@gmail.com>
Mon, 20 Oct 2025 20:45:44 +0000 (23:45 +0300)
lib/sqlalchemy/engine/_row_cy.py
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/util/cython.py
test/aaa_profiling/test_resultset.py

index cb9dfa9a28cf797a2ab89abf37a2518aac871b2b..1db2be4916f6ff92d055c9a65d1592fdad6351a2 100644 (file)
@@ -4,7 +4,9 @@
 #
 # This module is part of SQLAlchemy and is released under
 # the MIT License: https://www.opensource.org/licenses/mit-license.php
-# mypy: disable-error-code="misc"
+# mypy: disable-error-code="misc,no-redef,valid-type,no-untyped-call"
+# mypy: disable-error-code="index,no-any-return,arg-type,assignment"
+# cython: wraparound=False, boundscheck=False
 from __future__ import annotations
 
 from typing import Any
@@ -43,17 +45,6 @@ def _is_compiled() -> bool:
 
 
 if not cython.compiled:
-    if TYPE_CHECKING:
-
-        def PyTuple_New(n):  # type: ignore
-            # Actually produces list if not compiled
-            return [None] * n
-
-        def PyTuple_SET_ITEM(tup, idx, item):  # type: ignore
-            tup[idx] = item
-
-        PySequence_Fast_GET_SIZE = len
-        Py_INCREF = cython._no_op
 
     def _apply_processors(
         proc: _ProcessorsType, data: Sequence[Any]
@@ -72,20 +63,20 @@ else:
     from cython.cimports.cpython import PyTuple_New
     from cython.cimports.cpython import Py_INCREF
     from cython.cimports.cpython import PyTuple_SET_ITEM
-    from cython.cimports.cpython import PySequence_Fast_GET_SIZE
+
+    _SequenceLike = cython.fused_type(tuple, list, object)
 
     @cython.inline
     @cython.cfunc
-    @cython.wraparound(False)
-    @cython.boundscheck(False)
-    @cython.returns(tuple)
     @cython.locals(
         res=tuple, proc_size=cython.Py_ssize_t, p=object, value=object
     )
-    def _apply_processors(proc: object, data: object) -> Tuple[Any, ...]:
-        proc_size = PySequence_Fast_GET_SIZE(proc)
+    def _apply_processors(
+        proc: _SequenceLike, data: _SequenceLike
+    ) -> Tuple[Any, ...]:
+        proc_size = len(proc)
         # TODO: would be nice to do this only on the fist row
-        assert PySequence_Fast_GET_SIZE(data) == proc_size
+        assert len(data) == proc_size
         res = PyTuple_New(proc_size)
         for i in range(proc_size):
             p = proc[i]
@@ -109,6 +100,22 @@ class BaseRow:
         )
         _data: Tuple[Any, ...] = cython.declare(tuple, visibility="readonly")
 
+        def __getattribute__(self, name: _KeyType) -> object:
+            self = cython.cast(BaseRow, self)
+            if isinstance(name, str):
+                if name == "_data":
+                    return self._data
+                if name == "_key_to_index":
+                    return self._key_to_index
+                if name == "_parent":
+                    return self._parent
+            if name[0] != "_" and name[-1] != "_":
+                try:
+                    return self._get_by_key_impl(name, False)
+                except KeyError:
+                    pass
+            return object.__getattribute__(self, name)
+
     def __init__(
         self,
         parent: ResultMetaData,
@@ -139,65 +146,24 @@ class BaseRow:
         self._key_to_index = key_to_index
         self._data = data
 
-    if cython.compiled:
-
-        @cython.ccall
-        @cython.returns(dict)
-        def __getstate__(self) -> Dict[str, Any]:
-            self = cython.cast(BaseRow, self)
-            return {"_parent": self._parent, "_data": self._data}
-
-        @cython.ccall
-        @cython.returns(tuple)
-        def __reduce__(self) -> Tuple[Any, Any]:
-            self = cython.cast(BaseRow, self)
-            return (
-                rowproxy_reconstructor,
-                (
-                    self.__class__,
-                    {"_parent": self._parent, "_data": self._data},
-                ),
-            )
+    def __getstate__(self) -> Dict[str, Any]:
+        return {"_parent": self._parent, "_data": self._data}
 
-        def __getattribute__(self, name: _KeyType) -> object:
-            self = cython.cast(BaseRow, self)
-            if isinstance(name, str):
-                if name == "_data":
-                    return self._data
-                if name == "_key_to_index":
-                    return self._key_to_index
-                if name == "_parent":
-                    return self._parent
-            if name[0] != "_" and name[-1] != "_":
-                try:
-                    return self._get_by_key_impl(name, False)
-                except KeyError:
-                    pass
-            return object.__getattribute__(self, name)
-
-    else:
-
-        def __getstate__(self) -> Dict[str, Any]:
-            return {"_parent": self._parent, "_data": self._data}
-
-        def __reduce__(self) -> Tuple[Any, Any]:
-            return (
-                rowproxy_reconstructor,
-                (
-                    self.__class__,
-                    {"_parent": self._parent, "_data": self._data},
-                ),
-            )
+    def __reduce__(self) -> Tuple[Any, Any]:
+        return (
+            rowproxy_reconstructor,
+            (
+                self.__class__,
+                {"_parent": self._parent, "_data": self._data},
+            ),
+        )
 
     def __setstate__(self, state: Dict[str, Any]) -> None:
-        self = cython.cast(BaseRow, self)
-        parent = state["_parent"]
+        parent: ResultMetaData = state["_parent"]
         self._set_attrs(parent, parent._key_to_index, state["_data"])
 
-    @cython.wraparound(False)
-    @cython.boundscheck(False)
     def _values_impl(self) -> List[Any]:
-        return list(cython.cast(BaseRow, self)._data)
+        return list(self._data)
 
     def __iter__(self) -> Iterator[Any]:
         return iter(self._data)
@@ -218,12 +184,9 @@ class BaseRow:
 
     @cython.cfunc
     @cython.inline
-    @cython.wraparound(False)
-    @cython.boundscheck(False)
-    @cython.locals(index=cython.Py_ssize_t)
     def _get_by_key_impl(self, key: _KeyType, attr_err: cython.bint) -> object:
         self = cython.cast(BaseRow, self)
-        index = self._key_to_index.get(key, -1)
+        index: cython.Py_ssize_t = self._key_to_index.get(key, -1)
         if index != -1:
             return self._data[index]
         self._parent._key_not_found(key, attr_err)
@@ -231,7 +194,7 @@ class BaseRow:
     def __getattr__(self, name: _KeyType) -> Any:
         return self._get_by_key_impl(name, True)
 
-    def __setattr__(self, name: str, value: Any):
+    def __setattr__(self, name: str, value: Any) -> None:
         if name not in {"_parent", "_data", "_key_to_index"}:
             raise AttributeError("can't set attribute")
         object.__setattr__(self, name, value)
@@ -240,9 +203,9 @@ class BaseRow:
         raise AttributeError("can't delete attribute")
 
     def _to_tuple_instance(self) -> Tuple[Any, ...]:
-        return cython.cast(BaseRow, self)._data
+        return self._data
 
-    def __contains__(self, key: _KeyType) -> cython.bint:
+    def __contains__(self, key: Any) -> cython.bint:
         return key in self._data
 
 
index fb40c6f10a8fa53292e49aaa19c5a610a97454af..19381de87e9ce817d3bbe52615be760352584f59 100644 (file)
@@ -3408,7 +3408,7 @@ class Mapper(
 
         mapping: RowMapping
         if hasattr(row, "_mapping"):
-            mapping = row._mapping
+            mapping = row._mapping  # type: ignore[assignment]
         else:
             mapping = row  # type: ignore[assignment]
 
index 56ba0bf7b1b4af4825806d09fb9c91bfac60b9e3..3e74d8199d78d3ee072a1b17f31791338c3c3e66 100644 (file)
@@ -68,6 +68,3 @@ def returns(_: type) -> _NO_OP[_T]:
 
 def locals(**kwargs: Any) -> _NO_OP[_T]:  # noqa: A001
     return _no_op
-
-
-boundscheck = wraparound = annotation_typing
index 049e4a45e50064f352a21f57eab7322132e11103..5c6ef2b1dddc2e57fc03eaf0f2a1de198a44b40f 100644 (file)
@@ -266,4 +266,7 @@ class RowTest(fixtures.TestBase):
             def __iter__(self):
                 return iter(self.data)
 
+            def __len__(self):
+                return len(self.data)
+
         self._test_getitem_value_refcounts_new(CustomSeq)