]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
ensure ARRAY.__init__ documents before Comparator
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 21 Mar 2024 06:13:22 +0000 (02:13 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 21 Mar 2024 06:14:28 +0000 (02:14 -0400)
also add note for zero_indexes to generic and PG ARRAY
types

References: https://github.com/sqlalchemy/sqlalchemy/discussions/11100
Change-Id: I2087da695787a930f325cfb2fa4156d19c8e8f31
(cherry picked from commit 7c70ab8c6b7b9ce1c566862c4ca0438e0b0e9131)

doc/build/core/type_basics.rst
doc/build/dialects/postgresql.rst
lib/sqlalchemy/dialects/postgresql/array.py
lib/sqlalchemy/sql/sqltypes.py

index a8bb0f84afb983a034db41fe6a27f0ba4615e5b8..f3817fe0c9993221c236b6355d56069367d78b8c 100644 (file)
@@ -259,7 +259,9 @@ its exact name in DDL with ``CREATE TABLE`` is issued.
 
 
 .. autoclass:: ARRAY
-   :members:
+    :members: __init__, Comparator
+    :member-order: bysource
+
 
 .. autoclass:: BIGINT
 
index e822d069ce672f21ad77db295a6bd367092ec9bb..2d377e3623ea05d6917e60a314d3fec20e9c5ff3 100644 (file)
@@ -458,7 +458,7 @@ construction arguments, are as follows:
 
 .. autoclass:: ARRAY
     :members: __init__, Comparator
-
+    :member-order: bysource
 
 .. autoclass:: BIT
 
index e88c27d2de7874fefdd09487cad1af874f81df12..1d63655ee05aa3ff1dc87f4a7d79f574c746f1d4 100644 (file)
@@ -183,8 +183,9 @@ class ARRAY(sqltypes.ARRAY):
 
         mytable.c.data.contains([1, 2])
 
-    The :class:`_postgresql.ARRAY` type may not be supported on all
-    PostgreSQL DBAPIs; it is currently known to work on psycopg2 only.
+    Indexed access is one-based by default, to match that of PostgreSQL;
+    for zero-based indexed access, set
+    :paramref:`_postgresql.ARRAY.zero_indexes`.
 
     Additionally, the :class:`_postgresql.ARRAY`
     type does not work directly in
@@ -224,41 +225,6 @@ class ARRAY(sqltypes.ARRAY):
 
     """
 
-    class Comparator(sqltypes.ARRAY.Comparator):
-        """Define comparison operations for :class:`_types.ARRAY`.
-
-        Note that these operations are in addition to those provided
-        by the base :class:`.types.ARRAY.Comparator` class, including
-        :meth:`.types.ARRAY.Comparator.any` and
-        :meth:`.types.ARRAY.Comparator.all`.
-
-        """
-
-        def contains(self, other, **kwargs):
-            """Boolean expression.  Test if elements are a superset of the
-            elements of the argument array expression.
-
-            kwargs may be ignored by this operator but are required for API
-            conformance.
-            """
-            return self.operate(CONTAINS, other, result_type=sqltypes.Boolean)
-
-        def contained_by(self, other):
-            """Boolean expression.  Test if elements are a proper subset of the
-            elements of the argument array expression.
-            """
-            return self.operate(
-                CONTAINED_BY, other, result_type=sqltypes.Boolean
-            )
-
-        def overlap(self, other):
-            """Boolean expression.  Test if array has elements in common with
-            an argument array expression.
-            """
-            return self.operate(OVERLAP, other, result_type=sqltypes.Boolean)
-
-    comparator_factory = Comparator
-
     def __init__(
         self,
         item_type: _TypeEngineArgument[Any],
@@ -310,6 +276,41 @@ class ARRAY(sqltypes.ARRAY):
         self.dimensions = dimensions
         self.zero_indexes = zero_indexes
 
+    class Comparator(sqltypes.ARRAY.Comparator):
+        """Define comparison operations for :class:`_types.ARRAY`.
+
+        Note that these operations are in addition to those provided
+        by the base :class:`.types.ARRAY.Comparator` class, including
+        :meth:`.types.ARRAY.Comparator.any` and
+        :meth:`.types.ARRAY.Comparator.all`.
+
+        """
+
+        def contains(self, other, **kwargs):
+            """Boolean expression.  Test if elements are a superset of the
+            elements of the argument array expression.
+
+            kwargs may be ignored by this operator but are required for API
+            conformance.
+            """
+            return self.operate(CONTAINS, other, result_type=sqltypes.Boolean)
+
+        def contained_by(self, other):
+            """Boolean expression.  Test if elements are a proper subset of the
+            elements of the argument array expression.
+            """
+            return self.operate(
+                CONTAINED_BY, other, result_type=sqltypes.Boolean
+            )
+
+        def overlap(self, other):
+            """Boolean expression.  Test if array has elements in common with
+            an argument array expression.
+            """
+            return self.operate(OVERLAP, other, result_type=sqltypes.Boolean)
+
+    comparator_factory = Comparator
+
     @property
     def hashable(self):
         return self.as_tuple
index cdfd0a7c8adfad0435dec7772f9936b121e85fbd..1af3c5e339f65287ac5b0602e87ed769c44a6f03 100644 (file)
@@ -2766,23 +2766,23 @@ class ARRAY(
     dimension parameter will generally assume single-dimensional behaviors.
 
     SQL expressions of type :class:`_types.ARRAY` have support for "index" and
-    "slice" behavior.  The Python ``[]`` operator works normally here, given
-    integer indexes or slices.  Arrays default to 1-based indexing.
-    The operator produces binary expression
+    "slice" behavior.  The ``[]`` operator produces expression
     constructs which will produce the appropriate SQL, both for
     SELECT statements::
 
         select(mytable.c.data[5], mytable.c.data[2:7])
 
     as well as UPDATE statements when the :meth:`_expression.Update.values`
-    method
-    is used::
+    method is used::
 
         mytable.update().values({
             mytable.c.data[5]: 7,
             mytable.c.data[2:7]: [1, 2, 3]
         })
 
+    Indexed access is one-based by default;
+    for zero-based index conversion, set :paramref:`_types.ARRAY.zero_indexes`.
+
     The :class:`_types.ARRAY` type also provides for the operators
     :meth:`.types.ARRAY.Comparator.any` and
     :meth:`.types.ARRAY.Comparator.all`. The PostgreSQL-specific version of
@@ -2827,6 +2827,56 @@ class ARRAY(
     """If True, Python zero-based indexes should be interpreted as one-based
     on the SQL expression side."""
 
+    def __init__(
+        self,
+        item_type: _TypeEngineArgument[Any],
+        as_tuple: bool = False,
+        dimensions: Optional[int] = None,
+        zero_indexes: bool = False,
+    ):
+        """Construct an :class:`_types.ARRAY`.
+
+        E.g.::
+
+          Column('myarray', ARRAY(Integer))
+
+        Arguments are:
+
+        :param item_type: The data type of items of this array. Note that
+          dimensionality is irrelevant here, so multi-dimensional arrays like
+          ``INTEGER[][]``, are constructed as ``ARRAY(Integer)``, not as
+          ``ARRAY(ARRAY(Integer))`` or such.
+
+        :param as_tuple=False: Specify whether return results
+          should be converted to tuples from lists.  This parameter is
+          not generally needed as a Python list corresponds well
+          to a SQL array.
+
+        :param dimensions: if non-None, the ARRAY will assume a fixed
+         number of dimensions.   This impacts how the array is declared
+         on the database, how it goes about interpreting Python and
+         result values, as well as how expression behavior in conjunction
+         with the "getitem" operator works.  See the description at
+         :class:`_types.ARRAY` for additional detail.
+
+        :param zero_indexes=False: when True, index values will be converted
+         between Python zero-based and SQL one-based indexes, e.g.
+         a value of one will be added to all index values before passing
+         to the database.
+
+        """
+        if isinstance(item_type, ARRAY):
+            raise ValueError(
+                "Do not nest ARRAY types; ARRAY(basetype) "
+                "handles multi-dimensional arrays of basetype"
+            )
+        if isinstance(item_type, type):
+            item_type = item_type()
+        self.item_type = item_type
+        self.as_tuple = as_tuple
+        self.dimensions = dimensions
+        self.zero_indexes = zero_indexes
+
     class Comparator(
         Indexable.Comparator[Sequence[Any]],
         Concatenable.Comparator[Sequence[Any]],
@@ -2981,56 +3031,6 @@ class ARRAY(
 
     comparator_factory = Comparator
 
-    def __init__(
-        self,
-        item_type: _TypeEngineArgument[Any],
-        as_tuple: bool = False,
-        dimensions: Optional[int] = None,
-        zero_indexes: bool = False,
-    ):
-        """Construct an :class:`_types.ARRAY`.
-
-        E.g.::
-
-          Column('myarray', ARRAY(Integer))
-
-        Arguments are:
-
-        :param item_type: The data type of items of this array. Note that
-          dimensionality is irrelevant here, so multi-dimensional arrays like
-          ``INTEGER[][]``, are constructed as ``ARRAY(Integer)``, not as
-          ``ARRAY(ARRAY(Integer))`` or such.
-
-        :param as_tuple=False: Specify whether return results
-          should be converted to tuples from lists.  This parameter is
-          not generally needed as a Python list corresponds well
-          to a SQL array.
-
-        :param dimensions: if non-None, the ARRAY will assume a fixed
-         number of dimensions.   This impacts how the array is declared
-         on the database, how it goes about interpreting Python and
-         result values, as well as how expression behavior in conjunction
-         with the "getitem" operator works.  See the description at
-         :class:`_types.ARRAY` for additional detail.
-
-        :param zero_indexes=False: when True, index values will be converted
-         between Python zero-based and SQL one-based indexes, e.g.
-         a value of one will be added to all index values before passing
-         to the database.
-
-        """
-        if isinstance(item_type, ARRAY):
-            raise ValueError(
-                "Do not nest ARRAY types; ARRAY(basetype) "
-                "handles multi-dimensional arrays of basetype"
-            )
-        if isinstance(item_type, type):
-            item_type = item_type()
-        self.item_type = item_type
-        self.as_tuple = as_tuple
-        self.dimensions = dimensions
-        self.zero_indexes = zero_indexes
-
     @property
     def hashable(self):
         return self.as_tuple