From: Daniele Varrazzo Date: Fri, 13 Aug 2021 13:09:38 +0000 (+0100) Subject: Move the pool into a separate package X-Git-Tag: 3.0.dev2~4^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=95d75367eb6c6c6a6e433b83742c418d6f280a6d;p=thirdparty%2Fpsycopg.git Move the pool into a separate package This would allow different release cycles from the core adapter. --- diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 274cb95c9..b39dd58a1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -173,7 +173,7 @@ jobs: - name: Install and run tests (C implementation) if: ${{ matrix.impl == 'c' }} run: | - pip install ./psycopg/[test] + pip install ./psycopg/[test] ./psycopg_pool &"pip" install @(Get-ChildItem wheelhouse\*.whl) # Fix the path for the tests using ctypes $env:Path = "C:\Program Files\PostgreSQL\13\bin\;$env:Path" diff --git a/.gitignore b/.gitignore index 80f237f59..c32de56d1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ /build /dist *.pstats -/.mypy_cache +.mypy_cache __pycache__/ /docs/_build/ /docs/.venv/ diff --git a/.mypy.ini b/.mypy.ini index 0e8978fb3..06aa120de 100644 --- a/.mypy.ini +++ b/.mypy.ini @@ -3,7 +3,7 @@ files = psycopg/psycopg warn_unused_ignores = True show_error_codes = True strict = True -mypy_path = psycopg_c +mypy_path = psycopg_c, psycopg_pool [mypy-pytest] ignore_missing_imports = True diff --git a/README.rst b/README.rst index 25bfff861..0e595a620 100644 --- a/README.rst +++ b/README.rst @@ -65,8 +65,9 @@ requirements:: python -m venv .venv source .venv/bin/activate - pip install -e ./psycopg[dev,test] # for the base Python package - pip install -e ./psycopg_c # for the C extension module + pip install -e ./psycopg[dev,test] # for the base Python package + pip install -e ./psycopg_c # for the C extension module + pip install -e ./psycopg_pool --no-deps # for the connection pool .. __: https://pip.pypa.io/en/stable/reference/pip_install/#install-editable diff --git a/docs/advanced/pool.rst b/docs/advanced/pool.rst index 541a24cc3..ed232ac14 100644 --- a/docs/advanced/pool.rst +++ b/docs/advanced/pool.rst @@ -1,4 +1,4 @@ -.. currentmodule:: psycopg.pool +.. currentmodule:: psycopg_pool .. _connection-pools: diff --git a/docs/api/pool.rst b/docs/api/pool.rst index 140899e9b..5b1483ee7 100644 --- a/docs/api/pool.rst +++ b/docs/api/pool.rst @@ -4,7 +4,7 @@ .. index:: double: Connection; Pool -.. module:: psycopg.pool +.. module:: psycopg_pool The package contains two connection pool implementations. A connection pool creates and maintains a limited amount of PostgreSQL connections and allows a diff --git a/psycopg/psycopg/connection.py b/psycopg/psycopg/connection.py index 188736d33..9e6c016cb 100644 --- a/psycopg/psycopg/connection.py +++ b/psycopg/psycopg/connection.py @@ -36,7 +36,7 @@ from .server_cursor import ServerCursor if TYPE_CHECKING: from .pq.abc import PGconn, PGresult - from .pool.base import BasePool + from psycopg_pool.base import BasePool logger = logging.getLogger("psycopg") diff --git a/psycopg/setup.py b/psycopg/setup.py index 958e70e1d..cd3a1da5b 100644 --- a/psycopg/setup.py +++ b/psycopg/setup.py @@ -31,6 +31,10 @@ extras_require = { "binary": [ f"psycopg-binary == {version}", ], + # Install the connection pool + "pool": [ + "psycopg-pool", + ], # Requirements to run the test suite "test": [ "mypy >= 0.812", diff --git a/psycopg/tox.ini b/psycopg/tox.ini index 3166081f2..4ce96f6dd 100644 --- a/psycopg/tox.ini +++ b/psycopg/tox.ini @@ -8,6 +8,8 @@ commands = pytest {posargs} passenv = PG* PSYCOPG_TEST_DSN PYTEST_ADDOPTS PSYCOPG_IMPL extras = test +deps = + -e {toxinidir}/../psycopg_pool [flake8] max-line-length = 85 diff --git a/psycopg_c/tox.ini b/psycopg_c/tox.ini index 6b974ec3f..6cc1c1910 100644 --- a/psycopg_c/tox.ini +++ b/psycopg_c/tox.ini @@ -9,3 +9,4 @@ commands = passenv = PG* PSYCOPG_TEST_DSN PYTEST_ADDOPTS PSYCOPG_IMPL deps = -e {toxinidir}/../psycopg[test] + -e {toxinidir}/../psycopg_pool diff --git a/psycopg_pool/LICENSE.txt b/psycopg_pool/LICENSE.txt new file mode 100644 index 000000000..0a041280b --- /dev/null +++ b/psycopg_pool/LICENSE.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/psycopg_pool/README.rst b/psycopg_pool/README.rst new file mode 100644 index 000000000..15b46f8fe --- /dev/null +++ b/psycopg_pool/README.rst @@ -0,0 +1,18 @@ +Psycopg 3: PostgreSQL database adapter for Python - Connection Pool +=================================================================== + +This distribution contains the optional connection pool package +``psycopg_pool``. + +You can also install this package using:: + + pip install psycopg[pool] + +Please read `the project readme`__ and `the installation documentation`__ for +more details. + +.. __: https://github.com/psycopg/psycopg#readme +.. __: https://www.psycopg.org/psycopg3/docs/basic/install.html + + +Copyright (C) 2020-2021 The Psycopg Team diff --git a/psycopg/psycopg/pool/__init__.py b/psycopg_pool/psycopg_pool/__init__.py similarity index 87% rename from psycopg/psycopg/pool/__init__.py rename to psycopg_pool/psycopg_pool/__init__.py index d95d31485..529a99f3b 100644 --- a/psycopg/psycopg/pool/__init__.py +++ b/psycopg_pool/psycopg_pool/__init__.py @@ -7,6 +7,7 @@ psycopg connection pool package from .pool import ConnectionPool from .pool_async import AsyncConnectionPool from .errors import PoolClosed, PoolTimeout, TooManyRequests +from .version import __version__ # noqa: F401 __all__ = [ "AsyncConnectionPool", diff --git a/psycopg/psycopg/pool/base.py b/psycopg_pool/psycopg_pool/base.py similarity index 99% rename from psycopg/psycopg/pool/base.py rename to psycopg_pool/psycopg_pool/base.py index 55c25301c..0227b2e0d 100644 --- a/psycopg/psycopg/pool/base.py +++ b/psycopg_pool/psycopg_pool/base.py @@ -9,7 +9,7 @@ from typing import Any, Callable, Deque, Dict, Generic, Optional from typing import TYPE_CHECKING from collections import Counter, deque -from ..abc import ConnectionType +from psycopg.abc import ConnectionType if TYPE_CHECKING: from typing import Counter as TCounter diff --git a/psycopg/psycopg/pool/errors.py b/psycopg_pool/psycopg_pool/errors.py similarity index 76% rename from psycopg/psycopg/pool/errors.py rename to psycopg_pool/psycopg_pool/errors.py index a579bb21e..9e672adc0 100644 --- a/psycopg/psycopg/pool/errors.py +++ b/psycopg_pool/psycopg_pool/errors.py @@ -4,22 +4,22 @@ Connection pool errors. # Copyright (C) 2021 The Psycopg Team -from .. import errors as e +from psycopg import errors as e class PoolClosed(e.OperationalError): """Attempt to get a connection from a closed pool.""" - __module__ = "psycopg.pool" + __module__ = "psycopg_pool" class PoolTimeout(e.OperationalError): """The pool couldn't provide a connection in acceptable time.""" - __module__ = "psycopg.pool" + __module__ = "psycopg_pool" class TooManyRequests(e.OperationalError): """Too many requests in the queue waiting for a connection from the pool.""" - __module__ = "psycopg.pool" + __module__ = "psycopg_pool" diff --git a/psycopg/psycopg/pool/pool.py b/psycopg_pool/psycopg_pool/pool.py similarity index 99% rename from psycopg/psycopg/pool/pool.py rename to psycopg_pool/psycopg_pool/pool.py index 7ba7d3d01..e52b5e047 100644 --- a/psycopg/psycopg/pool/pool.py +++ b/psycopg_pool/psycopg_pool/pool.py @@ -16,9 +16,9 @@ from weakref import ref from contextlib import contextmanager from collections import deque -from .. import errors as e -from ..pq import TransactionStatus -from ..connection import Connection +from psycopg import errors as e +from psycopg import Connection +from psycopg.pq import TransactionStatus from .base import ConnectionAttempt, BasePool from .sched import Scheduler diff --git a/psycopg/psycopg/pool/pool_async.py b/psycopg_pool/psycopg_pool/pool_async.py similarity index 99% rename from psycopg/psycopg/pool/pool_async.py rename to psycopg_pool/psycopg_pool/pool_async.py index fca08195a..a8977583f 100644 --- a/psycopg/psycopg/pool/pool_async.py +++ b/psycopg_pool/psycopg_pool/pool_async.py @@ -15,10 +15,10 @@ from typing import Dict, List, Optional, Type from weakref import ref from collections import deque -from .. import errors as e -from ..pq import TransactionStatus -from ..compat import Task, asynccontextmanager, create_task -from ..connection_async import AsyncConnection +from psycopg import errors as e +from psycopg.pq import TransactionStatus +from psycopg.compat import Task, asynccontextmanager, create_task +from psycopg.connection_async import AsyncConnection from .base import ConnectionAttempt, BasePool from .sched import AsyncScheduler diff --git a/psycopg_pool/psycopg_pool/py.typed b/psycopg_pool/psycopg_pool/py.typed new file mode 100644 index 000000000..e69de29bb diff --git a/psycopg/psycopg/pool/sched.py b/psycopg_pool/psycopg_pool/sched.py similarity index 100% rename from psycopg/psycopg/pool/sched.py rename to psycopg_pool/psycopg_pool/sched.py diff --git a/psycopg_pool/psycopg_pool/version.py b/psycopg_pool/psycopg_pool/version.py new file mode 100644 index 000000000..8c795711f --- /dev/null +++ b/psycopg_pool/psycopg_pool/version.py @@ -0,0 +1,9 @@ +""" +psycopg pool version file. +""" + +# Copyright (C) 2021 The Psycopg Team + +# Use a versioning scheme as defined in +# https://www.python.org/dev/peps/pep-0440/ +__version__ = "3.0.dev2" diff --git a/psycopg_pool/setup.cfg b/psycopg_pool/setup.cfg new file mode 100644 index 000000000..a68d3162d --- /dev/null +++ b/psycopg_pool/setup.cfg @@ -0,0 +1,45 @@ +[metadata] +name = psycopg-pool +description = Connection Pool for Psycopg +url = https://psycopg.org/psycopg3/ +author = Daniele Varrazzo +author_email = daniele.varrazzo@gmail.com +license = GNU Lesser General Public License v3 (LGPLv3) + +project_urls = + Homepage = https://psycopg.org/ + Code = https://github.com/psycopg/psycopg + Issue Tracker = https://github.com/psycopg/psycopg/issues + Download = https://pypi.org/project/psycopg/ + +classifiers = + Development Status :: 3 - Alpha + Intended Audience :: Developers + License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3) + Operating System :: MacOS :: MacOS X + Operating System :: Microsoft :: Windows + Operating System :: POSIX + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Topic :: Database + Topic :: Database :: Front-Ends + Topic :: Software Development + Topic :: Software Development :: Libraries :: Python Modules + +long_description = file: README.rst +long_description_content_type = text/x-rst +license_file = LICENSE.txt + +[options] +python_requires = >= 3.6 +packages = find: +zip_safe = False +# Maybe it can be useful after release, now it gets in the way. +# install_requires = +# psycopg >= 3, < 4 + +[options.package_data] +psycopg_pool = py.typed diff --git a/psycopg_pool/setup.py b/psycopg_pool/setup.py new file mode 100644 index 000000000..7de7f4b44 --- /dev/null +++ b/psycopg_pool/setup.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +""" +PostgreSQL database adapter for Python - Connection Pool +""" + +# Copyright (C) 2020-2021 The Psycopg Team + +import os +import re +from setuptools import setup + +# Move to the directory of setup.py: executing this file from another location +# (e.g. from the project root) will fail +here = os.path.abspath(os.path.dirname(__file__)) +if os.path.abspath(os.getcwd()) != here: + os.chdir(here) + +with open("psycopg_pool/version.py") as f: + data = f.read() + m = re.search(r"""(?m)^__version__\s*=\s*['"]([^'"]+)['"]""", data) + if not m: + raise Exception(f"cannot find version in {f.name}") + version = m.group(1) + + +setup(version=version) diff --git a/tests/pool/test_pool.py b/tests/pool/test_pool.py index 15036aede..010e9483f 100644 --- a/tests/pool/test_pool.py +++ b/tests/pool/test_pool.py @@ -8,7 +8,7 @@ from collections import Counter import pytest import psycopg -from psycopg import pool +import psycopg_pool as pool from psycopg.pq import TransactionStatus @@ -669,7 +669,7 @@ def test_grow(dsn, monkeypatch, retries): @pytest.mark.timing def test_shrink(dsn, monkeypatch): - from psycopg.pool.pool import ShrinkPool + from psycopg_pool.pool import ShrinkPool results = [] diff --git a/tests/pool/test_pool_async.py b/tests/pool/test_pool_async.py index 7a1d333ce..4fdd0d77f 100644 --- a/tests/pool/test_pool_async.py +++ b/tests/pool/test_pool_async.py @@ -7,7 +7,7 @@ from collections import Counter import pytest import psycopg -from psycopg import pool +import psycopg_pool as pool from psycopg.pq import TransactionStatus from psycopg.compat import create_task @@ -681,7 +681,7 @@ async def test_grow(dsn, monkeypatch, retries): @pytest.mark.timing async def test_shrink(dsn, monkeypatch): - from psycopg.pool.pool_async import ShrinkPool + from psycopg_pool.pool_async import ShrinkPool results = [] diff --git a/tests/pool/test_sched.py b/tests/pool/test_sched.py index 9e3e1043b..fefef8212 100644 --- a/tests/pool/test_sched.py +++ b/tests/pool/test_sched.py @@ -5,7 +5,7 @@ from threading import Thread import pytest -from psycopg.pool.sched import Scheduler +from psycopg_pool.sched import Scheduler pytestmark = pytest.mark.timing diff --git a/tests/pool/test_sched_async.py b/tests/pool/test_sched_async.py index 0a5ff8f88..d18f7cb70 100644 --- a/tests/pool/test_sched_async.py +++ b/tests/pool/test_sched_async.py @@ -6,7 +6,7 @@ from functools import partial import pytest from psycopg.compat import create_task -from psycopg.pool.sched import AsyncScheduler +from psycopg_pool.sched import AsyncScheduler pytestmark = [pytest.mark.asyncio, pytest.mark.timing] diff --git a/tests/scripts/spiketest.py b/tests/scripts/spiketest.py index 1e7a52810..e26d91bf7 100644 --- a/tests/scripts/spiketest.py +++ b/tests/scripts/spiketest.py @@ -13,7 +13,8 @@ import sys import time import threading -import psycopg.pool +import psycopg +import psycopg_pool import logging @@ -28,7 +29,7 @@ def main(): logging.getLogger("psycopg2.pool").setLevel(loglevel) - with psycopg.pool.ConnectionPool( + with psycopg_pool.ConnectionPool( opt.dsn, min_size=opt.min_size, max_size=opt.max_size, diff --git a/tox.ini b/tox.ini index df240b322..65e9536f3 100644 --- a/tox.ini +++ b/tox.ini @@ -14,13 +14,16 @@ skip_install = true [testenv:mypy] commands = mypy -deps = mypy >= 0.800 +deps = + mypy >= 0.910 + types-backports; python_version < "3.9" skip_install = true [testenv:docs] commands = sphinx-build -W -T -b html docs docs/_build/html deps = ./psycopg[docs] + ./psycopg_pool skip_install = true [flake8]