]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Rename Row t and tuples with underscored versions.
authorFederico Caselli <cfederico87@gmail.com>
Wed, 12 Jul 2023 20:58:24 +0000 (22:58 +0200)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 14 Jul 2023 18:32:59 +0000 (14:32 -0400)
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

doc/build/changelog/unreleased_20/10093.rst [new file with mode: 0644]
doc/build/core/connections.rst
lib/sqlalchemy/engine/result.py
lib/sqlalchemy/engine/row.py
test/sql/test_resultset.py

diff --git a/doc/build/changelog/unreleased_20/10093.rst b/doc/build/changelog/unreleased_20/10093.rst
new file mode 100644 (file)
index 0000000..dd790a5
--- /dev/null
@@ -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.
index dc71fab28e9afa12c3414076f22859a522566c50..89d6df321dadfa86a7125963da293fb2a42be549 100644 (file)
@@ -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:
index 250584c45b67783c4e0e00d494f40c6b75294d8f..1c9cc504b1162cc5b7336f775fa270d7e125510f 100644 (file)
@@ -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
 
         """
 
index 95789ddba9fb7ed56f5438d38433d15fb8e47beb..9017537ab09f4ce0a88077a55bc6c055d2d5c776 100644 (file)
@@ -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`.
index bf5e30e3cad9552baf0219d8c52ad77ba967873d..a5d1befa206e105f150e445bc304f5585a178856 100644 (file)
@@ -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