From 91091e4a963dd58986ff79f8ff277c7aa5b94249 Mon Sep 17 00:00:00 2001 From: abebus Date: Sat, 18 Oct 2025 19:53:26 +0300 Subject: [PATCH] fix some tests --- lib/sqlalchemy/engine/_row_cy.py | 87 ++++++++++++++++---------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/lib/sqlalchemy/engine/_row_cy.py b/lib/sqlalchemy/engine/_row_cy.py index 6fea91ceee..c957e5224d 100644 --- a/lib/sqlalchemy/engine/_row_cy.py +++ b/lib/sqlalchemy/engine/_row_cy.py @@ -79,14 +79,13 @@ else: from cython.cimports.cpython import PyTuple_SET_ITEM from cython.cimports.cpython import PySequence_Fast_GET_SIZE - obj_getattr = object.__getattribute__ @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) + @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) # TODO: would be nice to do this only on the fist row @@ -95,9 +94,11 @@ else: for i in range(proc_size): p = proc[i] if p is not None: - PyTuple_SET_ITEM(res, i, Py_INCREF(p(data[i]))) + value = p(data[i]) else: - PyTuple_SET_ITEM(res, i, Py_INCREF(data[i])) + value = data[i] + Py_INCREF(value) + PyTuple_SET_ITEM(res, i, value) return res @cython.inline @@ -105,11 +106,10 @@ else: def rowproxy_reconstructor( cls: Type[BaseRow], state: Dict[str, Any] ) -> BaseRow: - obj = cls.__new__(cls) + obj = cython.cast(BaseRow, cls.__new__(cls)) obj.__setstate__(state) return obj - @cython.cclass class BaseRow: __slots__ = ("_parent", "_data", "_key_to_index") @@ -121,10 +121,6 @@ class BaseRow: ) _data: Tuple[Any, ...] = cython.declare(tuple, visibility="readonly") - @cython.inline - @cython.cfunc - def _getstate_impl(self) -> dict: - return {"_parent": self._parent, "_data": self._data} def __init__( self, @@ -134,14 +130,13 @@ class BaseRow: data: Sequence[Any], ) -> None: """Row objects are constructed by CursorResult objects.""" - self._set_attrs( parent, key_to_index, ( _apply_processors(processors, data) if processors is not None - else (data if isinstance(data, tuple) else tuple(data)) + else data if isinstance(data, tuple) else tuple(data) ), ) @@ -153,27 +148,40 @@ class BaseRow: key_to_index: Dict[_KeyType, int], data: Tuple[Any, ...], ): - if cython.compiled: - # cython does not use __setattr__ - self._parent = parent - self._key_to_index = key_to_index - self._data = data - else: - # python does, so use object.__setattr__ - object.__setattr__(self, "_parent", parent) - object.__setattr__(self, "_key_to_index", key_to_index) - object.__setattr__(self, "_data", data) + self._parent = parent + self._key_to_index = key_to_index + self._data = data if cython.compiled: - + @cython.inline + @cython.cfunc + def _getstate_impl(self) -> dict: + self = cython.cast(BaseRow, self) + return {"_parent": self._parent, "_data": self._data} + def __getstate__(self) -> Dict[str, Any]: - return self._getstate_impl() + return cython.cast(BaseRow, self)._getstate_impl() def __reduce__(self) -> Tuple[Any, Any]: + self = cython.cast(BaseRow, self) return ( rowproxy_reconstructor, (self.__class__, self._getstate_impl()), ) + + + 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] != "_": + return self._get_by_key_impl(name, True) + return object.__getattribute__(self, name) else: @@ -190,13 +198,14 @@ class BaseRow: ) def __setstate__(self, state: Dict[str, Any]) -> None: + self = cython.cast(BaseRow, self) parent = 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(self._data) + return list(cython.cast(BaseRow, self)._data) def __iter__(self) -> Iterator[Any]: return iter(self._data) @@ -213,41 +222,31 @@ class BaseRow: return self._data[key] def _get_by_key_impl_mapping(self, key: _KeyType) -> object: - return self._get_by_key_impl(key, False) + return cython.cast(BaseRow, self)._get_by_key_impl(key, False) @cython.cfunc @cython.inline @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) if index != -1: return self._data[index] self._parent._key_not_found(key, attr_err) - def __getattr__(self, name: str) -> Any: + def __getattr__(self, name: _KeyType) -> Any: return self._get_by_key_impl(name, True) - def __setattr__(self, name: str, value: Any) -> NoReturn: - raise AttributeError("can't set attribute") + def __setattr__(self, name: str, value: Any): + if name not in {"_parent", "_data", "_key_to_index"}: + raise AttributeError("can't set attribute") + object.__setattr__(self, name, value) def __delattr__(self, name: str) -> NoReturn: raise AttributeError("can't delete attribute") - if cython.compiled: - - def __getattribute__(self, name: str) -> object: - 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] != "_": - return self._get_by_key_impl(name, True) - return obj_getattr(self, name) - def _to_tuple_instance(self) -> Tuple[Any, ...]: - return self._data + return cython.cast(BaseRow, self)._data - def __contains__(self, key: Any) -> cython.bint: + def __contains__(self, key: _KeyType) -> cython.bint: return key in self._data -- 2.47.3