]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Drop AnyCursor from public interface
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 1 Aug 2021 20:33:44 +0000 (22:33 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 1 Aug 2021 20:37:31 +0000 (22:37 +0200)
Name repurposed internally for the generic to represent the type of
"self" in cursors.

docs/advanced/rows.rst
psycopg/psycopg/__init__.py
psycopg/psycopg/_column.py
psycopg/psycopg/cursor.py
psycopg/psycopg/rows.py
psycopg/psycopg/server_cursor.py
tests/test_typing.py

index 5781429c4098ee264037dd6f9b5d7a8002d664bc..01e3d3672dc9616a0d74931ad471c8c1219726f3 100644 (file)
@@ -38,8 +38,6 @@ callable (formally the `~psycopg.rows.RowMaker` protocol) accepting a
 Note that it's easy to implement an object implementing both `!RowFactory` and
 `!AsyncRowFactory`: usually, everything you need to implement a row factory is
 to access `~Cursor.description`, which is provided by both the cursor flavours.
-The `psycopg` module also exposes a class `AnyCursor` which you may use if you
-want to use the same row factory for both sync and async cursors.
 
 `~RowFactory` objects can be implemented as a class, for instance:
 
@@ -90,13 +88,13 @@ The module `psycopg.rows` provides the implementation for a few row factories:
 
 .. currentmodule:: psycopg.rows
 
-.. autofunction:: tuple_row(cursor: AnyCursor[TupleRow])
+.. autofunction:: tuple_row
 .. autodata:: TupleRow
 
-.. autofunction:: dict_row(cursor: AnyCursor[DictRow])
+.. autofunction:: dict_row
 .. autodata:: DictRow
 
-.. autofunction:: namedtuple_row(cursor: AnyCursor[NamedTuple])
+.. autofunction:: namedtuple_row
 
 
 Use with a static analyzer
index 5706794f49e802a253ed04c99f1fe41b8184754e..6d275db47cc9dfe683fe2a20a2df8dbb15332d85 100644 (file)
@@ -11,7 +11,7 @@ from . import types
 from . import postgres
 from .copy import Copy, AsyncCopy
 from ._enums import IsolationLevel
-from .cursor import AnyCursor, AsyncCursor, Cursor
+from .cursor import AsyncCursor, Cursor
 from .errors import Warning, Error, InterfaceError, DatabaseError
 from .errors import DataError, OperationalError, IntegrityError
 from .errors import InternalError, ProgrammingError, NotSupportedError
@@ -51,7 +51,6 @@ adapters.register_dumper(Binary, BinaryBinaryDumper)  # dbapi20
 # so that function signatures are consistent with the documentation.
 __all__ = [
     "__version__",
-    "AnyCursor",
     "AsyncConnection",
     "AsyncCopy",
     "AsyncCursor",
index ac0f6f6781837eb7cc850f5b23694b2a7ef48fe1..4e6a75b044000789c26b04098cc808da2f747d8b 100644 (file)
@@ -10,7 +10,7 @@ from operator import attrgetter
 from . import errors as e
 
 if TYPE_CHECKING:
-    from .cursor import AnyCursor
+    from .cursor import BaseCursor
 
 
 class ColumnData(NamedTuple):
@@ -23,7 +23,7 @@ class Column(Sequence[Any]):
 
     __module__ = "psycopg"
 
-    def __init__(self, cursor: "AnyCursor[Any]", index: int):
+    def __init__(self, cursor: "BaseCursor[Any, Any]", index: int):
         res = cursor.pgresult
         assert res
 
index 739fba3b32bfd605b760fb5bd829b1dbe20e313f..df48cd3ac1fc82f201924889448eab2eb613fd23 100644 (file)
@@ -28,8 +28,7 @@ from ._preparing import Prepare
 if TYPE_CHECKING:
     from .abc import Transformer
     from .pq.abc import PGconn, PGresult
-    from .connection import BaseConnection  # noqa: F401
-    from .connection import Connection, AsyncConnection  # noqa: F401
+    from .connection import Connection, AsyncConnection
 
 execute: Callable[["PGconn"], PQGen[List["PGresult"]]]
 
@@ -452,10 +451,7 @@ class BaseCursor(Generic[ConnectionType, Row]):
         self._closed = True
 
 
-AnyCursor = BaseCursor[Any, Row]
-
-
-C = TypeVar("C", bound="BaseCursor[Any, Any]")
+AnyCursor = TypeVar("AnyCursor", bound="BaseCursor[Any, Any]")
 
 
 class Cursor(BaseCursor["Connection[Any]", Row]):
@@ -468,7 +464,7 @@ class Cursor(BaseCursor["Connection[Any]", Row]):
         super().__init__(connection)
         self._row_factory = row_factory
 
-    def __enter__(self: C) -> C:
+    def __enter__(self: AnyCursor) -> AnyCursor:
         return self
 
     def __exit__(
@@ -500,12 +496,12 @@ class Cursor(BaseCursor["Connection[Any]", Row]):
         return self._row_factory(self)
 
     def execute(
-        self: C,
+        self: AnyCursor,
         query: Query,
         params: Optional[Params] = None,
         *,
         prepare: Optional[bool] = None,
-    ) -> C:
+    ) -> AnyCursor:
         """
         Execute a query or command to the database.
         """
@@ -642,7 +638,7 @@ class AsyncCursor(BaseCursor["AsyncConnection[Any]", Row]):
         super().__init__(connection)
         self._row_factory = row_factory
 
-    async def __aenter__(self: C) -> C:
+    async def __aenter__(self: AnyCursor) -> AnyCursor:
         return self
 
     async def __aexit__(
@@ -670,12 +666,12 @@ class AsyncCursor(BaseCursor["AsyncConnection[Any]", Row]):
         return self._row_factory(self)
 
     async def execute(
-        self: C,
+        self: AnyCursor,
         query: Query,
         params: Optional[Params] = None,
         *,
         prepare: Optional[bool] = None,
-    ) -> C:
+    ) -> AnyCursor:
         try:
             async with self._conn.lock:
                 await self._conn.wait(
index 5e4927e7f5dab593b26ce60edf759e974221e77c..21a7912f06d7f1e9c5017c885405d42875216df4 100644 (file)
@@ -7,14 +7,14 @@ psycopg row factories
 import functools
 import re
 from collections import namedtuple
-from typing import Any, Callable, Dict, NamedTuple, Sequence, Tuple, Type
-from typing import TypeVar, TYPE_CHECKING
+from typing import Any, Dict, NamedTuple, Sequence, Tuple, Type, TypeVar
+from typing import TYPE_CHECKING
 
 from . import errors as e
 from .compat import Protocol
 
 if TYPE_CHECKING:
-    from .cursor import AnyCursor, Cursor, AsyncCursor
+    from .cursor import BaseCursor, Cursor, AsyncCursor
 
 # Row factories
 
@@ -72,14 +72,13 @@ An alias for the type returned by `tuple_row()` (i.e. a tuple of any content).
 
 
 def tuple_row(
-    cursor: "AnyCursor[TupleRow]",
-) -> Callable[[Sequence[Any]], TupleRow]:
+    cursor: "BaseCursor[Any, TupleRow]",
+) -> RowMaker[TupleRow]:
     r"""Row factory to represent rows as simple tuples.
 
     This is the default factory.
 
-    :param cursor: The cursor where the rows are read.
-    :rtype: `RowMaker`\ [`TupleRow`]
+    :param cursor: The cursor where to read from.
     """
     # Implementation detail: make sure this is the tuple type itself, not an
     # equivalent function, because the C code fast-paths on it.
@@ -96,15 +95,14 @@ database.
 
 
 def dict_row(
-    cursor: "AnyCursor[DictRow]",
-) -> Callable[[Sequence[Any]], DictRow]:
+    cursor: "BaseCursor[Any, DictRow]",
+) -> RowMaker[DictRow]:
     r"""Row factory to represent rows as dicts.
 
     Note that this is not compatible with the DBAPI, which expects the records
     to be sequences.
 
-    :param cursor: The cursor where the rows are read.
-    :rtype: `RowMaker`\ [`DictRow`]
+    :param cursor: The cursor where to read from.
     """
 
     def make_row(values: Sequence[Any]) -> Dict[str, Any]:
@@ -118,12 +116,11 @@ def dict_row(
 
 
 def namedtuple_row(
-    cursor: "AnyCursor[NamedTuple]",
-) -> Callable[[Sequence[Any]], NamedTuple]:
+    cursor: "BaseCursor[Any, NamedTuple]",
+) -> RowMaker[NamedTuple]:
     r"""Row factory to represent rows as `~collections.namedtuple`.
 
-    :param cursor: The cursor where the rows are read.
-    :rtype: `RowMaker`\ [`NamedTuple`]
+    :param cursor: The cursor where to read from.
     """
 
     def make_row(values: Sequence[Any]) -> NamedTuple:
index ae58261edb7acc161c3f8e39932f2d500ece1d1a..fc10fbd1ca606208d4411c710cb9f9e3ea274f0c 100644 (file)
@@ -13,11 +13,10 @@ from . import sql
 from . import errors as e
 from .abc import ConnectionType, Query, Params, PQGen
 from .rows import Row, RowFactory, AsyncRowFactory
-from .cursor import C, BaseCursor, Cursor, AsyncCursor, execute
+from .cursor import AnyCursor, BaseCursor, Cursor, AsyncCursor, execute
 
 if TYPE_CHECKING:
-    from .connection import BaseConnection  # noqa: F401
-    from .connection import Connection, AsyncConnection  # noqa: F401
+    from .connection import Connection, AsyncConnection
 
 DEFAULT_ITERSIZE = 100
 
@@ -235,11 +234,11 @@ class ServerCursor(Cursor[Row]):
             super().close()
 
     def execute(
-        self: C,
+        self: AnyCursor,
         query: Query,
         params: Optional[Params] = None,
         **kwargs: Any,
-    ) -> C:
+    ) -> AnyCursor:
         """
         Open a cursor to execute a query to the database.
         """
@@ -351,11 +350,11 @@ class AsyncServerCursor(AsyncCursor[Row]):
             await super().close()
 
     async def execute(
-        self: C,
+        self: AnyCursor,
         query: Query,
         params: Optional[Params] = None,
         **kwargs: Any,
-    ) -> C:
+    ) -> AnyCursor:
         if kwargs:
             raise TypeError(f"keyword not supported: {list(kwargs)[0]}")
         helper = cast(AsyncServerCursor[Row], self)._helper
index 3ef42067384b9486f2ff8e56e84d2400b6fd2ecc..aa66f6fc057a11793c79df01b41111221fbdea01 100644 (file)
@@ -284,7 +284,8 @@ def _test_reveal(stmts, type, mypy, tmpdir):
     stmts = "\n".join(f"    {line}" for line in stmts.splitlines())
 
     src = f"""\
-from typing import Any, Callable, Dict, List, NamedTuple, Optional, Sequence, Tuple
+from typing import Any, Callable, Dict, List, NamedTuple, Optional, Sequence
+from typing import Tuple, Union
 import psycopg
 from psycopg import rows
 
@@ -293,7 +294,7 @@ class Thing:
         self.kwargs = kwargs
 
 def thing_row(
-    cur: psycopg.AnyCursor[Thing],
+    cur: Union[psycopg.Cursor[Thing], psycopg.AsyncCursor[Thing]],
 ) -> Callable[[Sequence[Any]], Thing]:
     assert cur.description
     names = [d.name for d in cur.description]