From: Federico Caselli Date: Wed, 12 Jul 2023 20:58:24 +0000 (+0200) Subject: Rename Row t and tuples with underscored versions. X-Git-Tag: rel_2_0_19~1^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed1e2f4b3406499132a180f8d2c23b0fc935a117;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Rename Row t and tuples with underscored versions. Renamed :attr:`_result.Row.t` and :meth:`_result.Row.tuple` to :attr:`_result.Row._t` and :meth:`_result.Row._tuple`; this is to suit the policy that all methods and pre-defined attributes on :class:`.Row` should be in the style of Python standard library ``namedtuple`` where all fixed names have a leading underscore, to avoid name conflicts with existing column names. The previous method/attribute is now deprecated and will emit a deprecation warning. Fixes: #10093 Change-Id: Ibb0e9423b55590c9dda8ee554187abd9a9122590 --- diff --git a/doc/build/changelog/unreleased_20/10093.rst b/doc/build/changelog/unreleased_20/10093.rst new file mode 100644 index 0000000000..dd790a5756 --- /dev/null +++ b/doc/build/changelog/unreleased_20/10093.rst @@ -0,0 +1,11 @@ +.. change:: + :tags: bug, engine + :tickets: 10093 + + Renamed :attr:`_result.Row.t` and :meth:`_result.Row.tuple` to + :attr:`_result.Row._t` and :meth:`_result.Row._tuple`; this is to suit the + policy that all methods and pre-defined attributes on :class:`.Row` should + be in the style of Python standard library ``namedtuple`` where all fixed + names have a leading underscore, to avoid name conflicts with existing + column names. The previous method/attribute is now deprecated and will + emit a deprecation warning. diff --git a/doc/build/core/connections.rst b/doc/build/core/connections.rst index dc71fab28e..89d6df321d 100644 --- a/doc/build/core/connections.rst +++ b/doc/build/core/connections.rst @@ -2655,7 +2655,7 @@ Result Set API .. autoclass:: Row :members: - :private-members: _asdict, _fields, _mapping + :private-members: _asdict, _fields, _mapping, _t, _tuple .. autoclass:: RowMapping :members: diff --git a/lib/sqlalchemy/engine/result.py b/lib/sqlalchemy/engine/result.py index 250584c45b..1c9cc504b1 100644 --- a/lib/sqlalchemy/engine/result.py +++ b/lib/sqlalchemy/engine/result.py @@ -1243,7 +1243,7 @@ class Result(_WithKeys, ResultInternal[Row[_TP]]): :attr:`_engine.Result.t` - shorter synonym - :attr:`_engine.Row.t` - :class:`_engine.Row` version + :attr:`_engine.Row._t` - :class:`_engine.Row` version """ diff --git a/lib/sqlalchemy/engine/row.py b/lib/sqlalchemy/engine/row.py index 95789ddba9..9017537ab0 100644 --- a/lib/sqlalchemy/engine/row.py +++ b/lib/sqlalchemy/engine/row.py @@ -30,6 +30,7 @@ from typing import TypeVar from typing import Union from ..sql import util as sql_util +from ..util import deprecated from ..util._has_cy import HAS_CYEXTENSION if TYPE_CHECKING or not HAS_CYEXTENSION: @@ -82,7 +83,7 @@ class Row(BaseRow, Sequence[Any], Generic[_TP]): def __delattr__(self, name: str) -> NoReturn: raise AttributeError("can't delete attribute") - def tuple(self) -> _TP: + def _tuple(self) -> _TP: """Return a 'tuple' form of this :class:`.Row`. At runtime, this method returns "self"; the :class:`.Row` object is @@ -91,28 +92,67 @@ class Row(BaseRow, Sequence[Any], Generic[_TP]): ``Tuple`` datatype that contains typing information about individual elements, supporting typed unpacking and attribute access. - .. versionadded:: 2.0 + .. versionadded:: 2.0.19 - The :meth:`.Row._tuple` method supersedes + the previous :meth:`.Row.tuple` method, which is now underscored + to avoid name conflicts with column names in the same way as other + named-tuple methods on :class:`.Row`. .. seealso:: + :attr:`.Row._t` - shorthand attribute notation + :meth:`.Result.tuples` + """ return self # type: ignore - @property - def t(self) -> _TP: - """a synonym for :attr:`.Row.tuple` + @deprecated( + "2.0.19", + "The :meth:`.Row.tuple` method is deprecated in favor of " + ":meth:`.Row._tuple`; all :class:`.Row` " + "methods and library-level attributes are intended to be underscored " + "to avoid name conflicts. Please use :meth:`Row._tuple`.", + ) + def tuple(self) -> _TP: + """Return a 'tuple' form of this :class:`.Row`. .. versionadded:: 2.0 - .. seealso:: + """ + return self._tuple() - :meth:`.Result.t` + @property + def _t(self) -> _TP: + """A synonym for :meth:`.Row._tuple`. + .. versionadded:: 2.0.19 - The :attr:`.Row._t` attribute supersedes + the previous :attr:`.Row.t` attribute, which is now underscored + to avoid name conflicts with column names in the same way as other + named-tuple methods on :class:`.Row`. + + .. seealso:: + + :attr:`.Result.t` """ return self # type: ignore + @property + @deprecated( + "2.0.19", + "The :attr:`.Row.t` attribute is deprecated in favor of " + ":attr:`.Row._t`; all :class:`.Row` " + "methods and library-level attributes are intended to be underscored " + "to avoid name conflicts. Please use :attr:`Row._t`.", + ) + def t(self) -> _TP: + """A synonym for :meth:`.Row._tuple`. + + .. versionadded:: 2.0 + + """ + return self._t + @property def _mapping(self) -> RowMapping: """Return a :class:`.RowMapping` for this :class:`.Row`. diff --git a/test/sql/test_resultset.py b/test/sql/test_resultset.py index bf5e30e3ca..a5d1befa20 100644 --- a/test/sql/test_resultset.py +++ b/test/sql/test_resultset.py @@ -297,8 +297,20 @@ class CursorResultTest(fixtures.TablesTest): {"user_id": 9, "user_name": "fred"}, ], ) - r = connection.execute(users.select().order_by(users.c.user_id)) - eq_([row.t for row in r], [(7, "jack"), (8, "ed"), (9, "fred")]) + r = connection.execute(users.select().order_by(users.c.user_id)).all() + exp = [(7, "jack"), (8, "ed"), (9, "fred")] + eq_([row._t for row in r], exp) + eq_([row._tuple() for row in r], exp) + with assertions.expect_deprecated( + r"The Row.t attribute is deprecated in favor of Row._t" + ): + eq_([row.t for row in r], exp) + + with assertions.expect_deprecated( + r"The Row.tuple\(\) method is deprecated in " + r"favor of Row._tuple\(\)" + ): + eq_([row.tuple() for row in r], exp) def test_row_next(self, connection): users = self.tables.users