From: Ran Benita Date: Tue, 24 Jan 2023 20:59:55 +0000 (+0200) Subject: refactor(pool): make constructor configuration parameters type-safe X-Git-Tag: pool-3.2.0~133^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=186d3a44a75fd878bc7694c9bcb13d99064066f9;p=thirdparty%2Fpsycopg.git refactor(pool): make constructor configuration parameters type-safe Previously, arguments to ConnectionPool and friends would be forwarded using `**kwargs` to `BasePool`. This is however not type-safe, and prevents code editors from auto-completing the parameters. Drop the `**kwargs`, duplicate the parameters instead. Fixes #493. --- diff --git a/psycopg_pool/psycopg_pool/base.py b/psycopg_pool/psycopg_pool/base.py index 298ea6837..c081419e7 100644 --- a/psycopg_pool/psycopg_pool/base.py +++ b/psycopg_pool/psycopg_pool/base.py @@ -41,18 +41,18 @@ class BasePool(Generic[ConnectionType]): self, conninfo: str = "", *, - kwargs: Optional[Dict[str, Any]] = None, - min_size: int = 4, - max_size: Optional[int] = None, - open: bool = True, - name: Optional[str] = None, - timeout: float = 30.0, - max_waiting: int = 0, - max_lifetime: float = 60 * 60.0, - max_idle: float = 10 * 60.0, - reconnect_timeout: float = 5 * 60.0, - reconnect_failed: Optional[Callable[["BasePool[ConnectionType]"], None]] = None, - num_workers: int = 3, + kwargs: Optional[Dict[str, Any]], + min_size: int, + max_size: Optional[int], + open: bool, + name: Optional[str], + timeout: float, + max_waiting: int, + max_lifetime: float, + max_idle: float, + reconnect_timeout: float, + reconnect_failed: Optional[Callable[["BasePool[ConnectionType]"], None]], + num_workers: int, ): min_size, max_size = self._check_size(min_size, max_size) diff --git a/psycopg_pool/psycopg_pool/null_pool.py b/psycopg_pool/psycopg_pool/null_pool.py index c0a77c246..20f9811b7 100644 --- a/psycopg_pool/psycopg_pool/null_pool.py +++ b/psycopg_pool/psycopg_pool/null_pool.py @@ -6,11 +6,12 @@ Psycopg null connection pools import logging import threading -from typing import Any, Optional, Tuple +from typing import Any, Callable, Dict, Optional, Tuple, Type from psycopg import Connection from psycopg.pq import TransactionStatus +from .base import BasePool from .pool import ConnectionPool, AddConnection from .errors import PoolTimeout, TooManyRequests from ._compat import ConnectionTimeout @@ -19,13 +20,6 @@ logger = logging.getLogger("psycopg.pool") class _BaseNullConnectionPool: - def __init__( - self, conninfo: str = "", min_size: int = 0, *args: Any, **kwargs: Any - ): - super().__init__( # type: ignore[call-arg] - conninfo, *args, min_size=min_size, **kwargs - ) - def _check_size(self, min_size: int, max_size: Optional[int]) -> Tuple[int, int]: if max_size is None: max_size = min_size @@ -48,6 +42,46 @@ class _BaseNullConnectionPool: class NullConnectionPool(_BaseNullConnectionPool, ConnectionPool): + def __init__( + self, + conninfo: str = "", + *, + open: bool = True, + connection_class: Type[Connection[Any]] = Connection, + configure: Optional[Callable[[Connection[Any]], None]] = None, + reset: Optional[Callable[[Connection[Any]], None]] = None, + kwargs: Optional[Dict[str, Any]] = None, + # Note: default value changed to 0. + min_size: int = 0, + max_size: Optional[int] = None, + name: Optional[str] = None, + timeout: float = 30.0, + max_waiting: int = 0, + max_lifetime: float = 60 * 60.0, + max_idle: float = 10 * 60.0, + reconnect_timeout: float = 5 * 60.0, + reconnect_failed: Optional[Callable[[BasePool[Connection[Any]]], None]] = None, + num_workers: int = 3, + ): + super().__init__( + conninfo, + open=open, + connection_class=connection_class, + configure=configure, + reset=reset, + kwargs=kwargs, + min_size=min_size, + max_size=max_size, + name=name, + timeout=timeout, + max_waiting=max_waiting, + max_lifetime=max_lifetime, + max_idle=max_idle, + reconnect_timeout=reconnect_timeout, + reconnect_failed=reconnect_failed, + num_workers=num_workers, + ) + def wait(self, timeout: float = 30.0) -> None: """ Create a connection for test. diff --git a/psycopg_pool/psycopg_pool/null_pool_async.py b/psycopg_pool/psycopg_pool/null_pool_async.py index ae9d207bc..9f566c663 100644 --- a/psycopg_pool/psycopg_pool/null_pool_async.py +++ b/psycopg_pool/psycopg_pool/null_pool_async.py @@ -6,11 +6,12 @@ psycopg asynchronous null connection pool import asyncio import logging -from typing import Any, Optional +from typing import Any, Awaitable, Callable, Dict, Optional, Type from psycopg import AsyncConnection from psycopg.pq import TransactionStatus +from .base import BasePool from .errors import PoolTimeout, TooManyRequests from ._compat import ConnectionTimeout from .null_pool import _BaseNullConnectionPool @@ -20,6 +21,48 @@ logger = logging.getLogger("psycopg.pool") class AsyncNullConnectionPool(_BaseNullConnectionPool, AsyncConnectionPool): + def __init__( + self, + conninfo: str = "", + *, + open: bool = True, + connection_class: Type[AsyncConnection[Any]] = AsyncConnection, + configure: Optional[Callable[[AsyncConnection[Any]], Awaitable[None]]] = None, + reset: Optional[Callable[[AsyncConnection[Any]], Awaitable[None]]] = None, + kwargs: Optional[Dict[str, Any]] = None, + # Note: default value changed to 0. + min_size: int = 0, + max_size: Optional[int] = None, + name: Optional[str] = None, + timeout: float = 30.0, + max_waiting: int = 0, + max_lifetime: float = 60 * 60.0, + max_idle: float = 10 * 60.0, + reconnect_timeout: float = 5 * 60.0, + reconnect_failed: Optional[ + Callable[[BasePool[AsyncConnection[None]]], None] + ] = None, + num_workers: int = 3, + ): + super().__init__( + conninfo, + open=open, + connection_class=connection_class, + configure=configure, + reset=reset, + kwargs=kwargs, + min_size=min_size, + max_size=max_size, + name=name, + timeout=timeout, + max_waiting=max_waiting, + max_lifetime=max_lifetime, + max_idle=max_idle, + reconnect_timeout=reconnect_timeout, + reconnect_failed=reconnect_failed, + num_workers=num_workers, + ) + async def wait(self, timeout: float = 30.0) -> None: self._check_open_getconn() diff --git a/psycopg_pool/psycopg_pool/pool.py b/psycopg_pool/psycopg_pool/pool.py index 609d95dfe..05cfc8fea 100644 --- a/psycopg_pool/psycopg_pool/pool.py +++ b/psycopg_pool/psycopg_pool/pool.py @@ -36,7 +36,17 @@ class ConnectionPool(BasePool[Connection[Any]]): connection_class: Type[Connection[Any]] = Connection, configure: Optional[Callable[[Connection[Any]], None]] = None, reset: Optional[Callable[[Connection[Any]], None]] = None, - **kwargs: Any, + kwargs: Optional[Dict[str, Any]] = None, + min_size: int = 4, + max_size: Optional[int] = None, + name: Optional[str] = None, + timeout: float = 30.0, + max_waiting: int = 0, + max_lifetime: float = 60 * 60.0, + max_idle: float = 10 * 60.0, + reconnect_timeout: float = 5 * 60.0, + reconnect_failed: Optional[Callable[[BasePool[Connection[Any]]], None]] = None, + num_workers: int = 3, ): self.connection_class = connection_class self._configure = configure @@ -53,7 +63,21 @@ class ConnectionPool(BasePool[Connection[Any]]): self._tasks: "Queue[MaintenanceTask]" = Queue() self._workers: List[threading.Thread] = [] - super().__init__(conninfo, **kwargs) + super().__init__( + conninfo, + kwargs=kwargs, + min_size=min_size, + max_size=max_size, + open=open, + name=name, + timeout=timeout, + max_waiting=max_waiting, + max_lifetime=max_lifetime, + max_idle=max_idle, + reconnect_timeout=reconnect_timeout, + reconnect_failed=reconnect_failed, + num_workers=num_workers, + ) if open: self.open() diff --git a/psycopg_pool/psycopg_pool/pool_async.py b/psycopg_pool/psycopg_pool/pool_async.py index 0ea6e9a40..1cffcce68 100644 --- a/psycopg_pool/psycopg_pool/pool_async.py +++ b/psycopg_pool/psycopg_pool/pool_async.py @@ -35,7 +35,19 @@ class AsyncConnectionPool(BasePool[AsyncConnection[Any]]): connection_class: Type[AsyncConnection[Any]] = AsyncConnection, configure: Optional[Callable[[AsyncConnection[Any]], Awaitable[None]]] = None, reset: Optional[Callable[[AsyncConnection[Any]], Awaitable[None]]] = None, - **kwargs: Any, + kwargs: Optional[Dict[str, Any]] = None, + min_size: int = 4, + max_size: Optional[int] = None, + name: Optional[str] = None, + timeout: float = 30.0, + max_waiting: int = 0, + max_lifetime: float = 60 * 60.0, + max_idle: float = 10 * 60.0, + reconnect_timeout: float = 5 * 60.0, + reconnect_failed: Optional[ + Callable[[BasePool[AsyncConnection[Any]]], None] + ] = None, + num_workers: int = 3, ): self.connection_class = connection_class self._configure = configure @@ -54,7 +66,21 @@ class AsyncConnectionPool(BasePool[AsyncConnection[Any]]): self._sched_runner: Optional[Task[None]] = None self._workers: List[Task[None]] = [] - super().__init__(conninfo, **kwargs) + super().__init__( + conninfo, + kwargs=kwargs, + min_size=min_size, + max_size=max_size, + open=open, + name=name, + timeout=timeout, + max_waiting=max_waiting, + max_lifetime=max_lifetime, + max_idle=max_idle, + reconnect_timeout=reconnect_timeout, + reconnect_failed=reconnect_failed, + num_workers=num_workers, + ) if open: self._open()