-/psycopg3.egg-info
-/.tox
-/.eggs
+/*.egg-info/
+.tox
+/.eggs/
/build
/dist
*.pstats
matrix:
include:
- - env: TOXENV=black
+ - env:
+ - TOXENV=black
+ - TOXDIR=.
python: 3.6
- - env: TOXENV=flake8
+ - env:
+ - TOXENV=flake8
+ - TOXDIR=.
python: 3.6
- - env: TOXENV=mypy
+ - env:
+ - TOXENV=mypy
+ - TOXDIR=.
python: 3.6
- python: 3.6
- postgresql-client-9.5
env:
- TOXENV=py36
+ - TOXDIR=psycopg3_c
- PGVER=9.5
- PSYCOPG3_IMPL=c
- PGPORT=5432
- postgresql-client-9.6
env:
- TOXENV=py36
+ - TOXDIR=psycopg3
- PGVER=9.6
- PSYCOPG3_IMPL=ctypes
- PGPORT=5432
- postgresql-client-10
env:
- TOXENV=py37
+ - TOXDIR=psycopg3_c
- PGVER=10
- PSYCOPG3_IMPL=c
- PGPORT=5432
- postgresql-client-11
env:
- TOXENV=py37
+ - TOXDIR=psycopg3
- PGVER=11
- PSYCOPG3_IMPL=ctypes
- PGPORT=5433
- postgresql-client-12
env:
- TOXENV=py38
+ - TOXDIR=psycopg3_c
- PGVER=12
- PSYCOPG3_IMPL=c
- PGPORT=5433
- postgresql-client-12
env:
- TOXENV=py38
+ - TOXDIR=psycopg3
- PGVER=12
- PSYCOPG3_IMPL=ctypes
- PGPORT=5433
- test ${TOXENV:0:2} != py || psql -c 'create database psycopg3_test'
script:
- - tox
+ - tox -c $TOXDIR
+++ /dev/null
-include README.rst LICENSE.txt BACKERS.md tox.ini
-recursive-include psycopg3 *.pyx *.pxd
psycopg3 is a modern implementation of a PostgreSQL adapter for Python.
+The package is split in different parts, with different requirements.
+
+- The pure python package only depends on the **libpq**, the PostgreSQL client
+ library. The code is in the ``psycopg3`` directory.
+
+- The optional C optimization: in order to build it requires the **libpq-dev**
+ packages, a C compiler and Cython. The code is in the ``psycopg3_c``
+ directory.
+
Installation
------------
The library is still in early development stage. If you want to try it out you
can install it from source using::
- pip install -e git+https://github.com/psycopg/psycopg3.git#egg=psycopg3
+ git clone https://github.com/psycopg/psycopg3.git
+ cd psycopg3
+ python psycopg3/setup.py install # for the base Python package
+ python psycopg3_c/setup.py install # for the C extension module
Hacking
We assume you have built your virtualenv and ``pip`` just works and ``python``
refers to Python 3. You can set up a dev environment with::
- python setup.py develop
+ python psycopg3/setup.py develop # for the base Python pacakge
+ python psycopg3_c/setup.py develop # for the C extension module
-All the available tests and dev support are defined in ``tox.ini``: please
-refer to `tox documentation`__ for its usage. You can run all the tests with::
+All the available tests and dev support are defined in the ``tox.ini`` files
+in this directory and in the package directories: please refer to `tox
+documentation`__ for its usage. You can run all the tests with::
psql -c 'create database psycopg3_test'
export PSYCOPG3_TEST_DSN="dbname=psycopg3_test"
- tox -s
+ tox -c psycopg3 -s
+ tox -c psycopg3_c -s
+
+and validate the code before submission running::
-You can also install the test dependencies in your virtualenv to run tests
-faster: please look at the ``tox.ini`` comments for instructions.
+ tox -p4
.. __: https://tox.readthedocs.io/
-_psycopg3.c
-_psycopg3.*.so
-*.html
+/psycopg3.egg-info/
+/build
+/dist
warn_unused_ignores = True
show_error_codes = True
strict = True
+mypy_path = ../psycopg3_c
[mypy-pytest]
ignore_missing_imports = True
--- /dev/null
+../LICENSE.txt
\ No newline at end of file
--- /dev/null
+include README.rst LICENSE.txt
--- /dev/null
+PostgreSQL database adapter for Python
+======================================
+
+This distribution contains the pure Python package ``psycopg3``.
+
+Installation::
+
+ pip install psycopg3
+
+Even if the package is pure Python, the PostgreSQL client library libpq must
+be available in the system.
+
+Please read `the project readme`__ for more details.
+
+.. __: https://github.com/psycopg/psycopg3#readme
+
+Copyright (C) 2020 The Psycopg Team
+++ /dev/null
-"""
-psycopg3 package constants
-"""
-
-# Copyright (C) 2020 The Psycopg Team
-
-VERSION = "2.99.0"
+++ /dev/null
-pq_cython.c
-pq_cython.*.so
-pq_cython.html
# Copyright (C) 2020 The Psycopg Team
from . import pq
-from .consts import VERSION as __version__ # noqa
from .connection import AsyncConnection, Connection
from .errors import (
from .dbapi20 import Binary, Date, DateFromTicks, Time, TimeFromTicks
from .dbapi20 import Timestamp, TimestampFromTicks
+from .version import __version__ # noqa
+
# DBAPI compliancy
connect = Connection.connect
apilevel = "2.0"
# Override adapters with fast version if available
if pq.__impl__ == "c":
- from ._psycopg3 import register_builtin_c_loaders
+ from psycopg3_c._psycopg3 import register_builtin_c_loaders
register_builtin_c_loaders()
# Override it with fast object if available
if pq.__impl__ == "c":
- from . import _psycopg3
+ from psycopg3_c import _psycopg3
Transformer = _psycopg3.Transformer
else:
execute: Callable[[pq.proto.PGconn], proto.PQGen[List[pq.proto.PGresult]]]
if pq.__impl__ == "c":
- from . import _psycopg3
+ from psycopg3_c import _psycopg3
connect = _psycopg3.connect
execute = _psycopg3.execute
execute: Callable[[pq.proto.PGconn], PQGen[List[pq.proto.PGresult]]]
if pq.__impl__ == "c":
- from . import _psycopg3
+ from psycopg3_c import _psycopg3
execute = _psycopg3.execute
if not impl or impl == "c":
try:
# TODO: extension module not recognised by mypy?
- from . import pq_cython # type: ignore
+ from psycopg3_c import pq_cython # type: ignore
except Exception as e:
if not impl:
logger.debug("C pq wrapper not available: %s", e)
--- /dev/null
+"""
+psycopg3 distribution version file.
+"""
+
+# Copyright (C) 2020 The Psycopg Team
+
+__version__ = "2.99.0"
--- /dev/null
+[build-system]
+requires = ["setuptools>=49.2.0", "wheel>=0.34.2"]
+build-backend = "setuptools.build_meta"
+
+[tool.black]
+line-length = 79
--- /dev/null
+[metadata]
+name = psycopg3
+description = PostgreSQL database adapter for Python
+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/psycopg3
+ Issue Tracker = https://github.com/psycopg/psycopg3/issues
+ Download = https://pypi.org/project/psycopg3/
+
+classifiers =
+ Intended Audience :: Developers
+ Programming Language :: Python :: 3
+ License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
+ 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
+include_package_data = True
+install_requires =
+ typing_extensions
--- /dev/null
+#!/usr/bin/env python3
+"""
+PostgreSQL database adapter for Python - pure Python package
+"""
+
+# Copyright (C) 2020 The Psycopg Team
+
+import re
+import os
+
+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("psycopg3/version.py") as f:
+ data = f.read()
+ m = re.search(r"""(?m)^__version__\s*=\s*['"]([^'"]+)['"]""", data)
+ if m is None:
+ raise Exception(f"cannot find version in {f.name}")
+ version = m.group(1)
+
+setup(version=version)
--- /dev/null
+[tox]
+envlist = py{36,37,38}
+isolated_build = True
+
+[testenv:py{36,37,38}]
+commands =
+ pytest ../tests
+passenv = PG* PSYCOPG3_TEST_DSN PYTEST_ADDOPTS PSYCOPG3_IMPL
+deps =
+ pytest >= 5.3, < 6
+ pytest-asyncio >= 0.12.0, < 0.13
--- /dev/null
+/.eggs
+/build
+/dist
+/psycopg3_c.egg-info
--- /dev/null
+../LICENSE.txt
\ No newline at end of file
--- /dev/null
+include README.rst LICENSE.txt
--- /dev/null
+PostgreSQL database adapter for Python - optimisation package
+=============================================================
+
+This distribution contains the optional optimization package ``psycopg3_c``.
+
+Installation::
+
+ pip install psycopg3-c
+
+Installing this distribution requires the ``libpq-dev`` package and other
+packages normally used to build Python C extensions. If you cannot meet these
+dependencies, don't worry: you don't need the package: please install the
+``psycopg3`` package only.
+
+Please read `the project readme`__ for more details.
+
+.. __: https://github.com/psycopg/psycopg3#readme
+
+Copyright (C) 2020 The Psycopg Team
--- /dev/null
+/*.so
+_psycopg3.c
+pq_cython.c
--- /dev/null
+"""
+psycopg3 -- PostgreSQL database adapter for Python -- C optimization package
+"""
+
+# Copyright (C) 2020 The Psycopg Team
+
+from .version import __version__ # noqa
import codecs
from typing import Any, Iterable, List, Optional, Sequence, Tuple
-from .proto import AdaptContext, DumpFunc, DumpersMap, DumperType
-from .proto import LoadFunc, LoadersMap, LoaderType, MaybeOid, PQGen
-from .connection import BaseConnection
-from . import pq
+from psycopg3.proto import AdaptContext, DumpFunc, DumpersMap, DumperType
+from psycopg3.proto import LoadFunc, LoadersMap, LoaderType, MaybeOid, PQGen
+from psycopg3.connection import BaseConnection
+from psycopg3 import pq
class Transformer:
def __init__(self, context: AdaptContext = None): ...
# Copyright (C) 2020 The Psycopg Team
-from psycopg3.adapt cimport cloader_func, get_context_func
+from psycopg3_c.adapt cimport cloader_func, get_context_func
import logging
logger = logging.getLogger("psycopg3.adapt")
import logging
from typing import List
-from . import errors as e
-from .proto import PQGen
-from .waiting import Wait, Ready
+from psycopg3 import errors as e
+from psycopg3.proto import PQGen
+from psycopg3.waiting import Wait, Ready
from psycopg3 import pq
-from psycopg3.pq cimport libpq
-from psycopg3.pq.pq_cython cimport PGconn, PGresult
+from psycopg3_c cimport libpq
+from psycopg3_c.pq_cython cimport PGconn, PGresult
cdef object WAIT_W = Wait.W
cdef object WAIT_R = Wait.R
from posix.fcntl cimport pid_t
-from psycopg3.pq cimport libpq as impl
+from psycopg3_c cimport libpq as impl
ctypedef char *(*conn_bytes_f) (const impl.PGconn *)
ctypedef int(*conn_int_f) (const impl.PGconn *)
import logging
from typing import List, Optional, Sequence, Tuple
-from psycopg3.pq cimport libpq as impl
-from psycopg3.pq.libpq cimport Oid
-from psycopg3.errors import OperationalError
+from psycopg3_c cimport libpq as impl
+from psycopg3_c.libpq cimport Oid
from psycopg3.pq.misc import PGnotify, ConninfoOption, PQerror, PGresAttDesc
from psycopg3.pq.misc import error_message
import codecs
from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple
-from psycopg3.pq cimport libpq
-from psycopg3.pq.pq_cython cimport PGresult
+from psycopg3_c cimport libpq
+from psycopg3_c.pq_cython cimport PGresult
from psycopg3 import errors as e
from psycopg3.pq.enums import Format
-# from psycopg3.types.oids import builtins, INVALID_OID
TEXT_OID = 25
# Copyright (C) 2020 The Psycopg Team
from libc.stdint cimport *
-from psycopg3.types.endian cimport be16toh, be32toh, be64toh
+from psycopg3_c.endian cimport be16toh, be32toh, be64toh
from cpython.long cimport (
from cpython.mem cimport PyMem_Malloc
from cpython.object cimport PyObject
from cpython.unicode cimport PyUnicode_DecodeUTF8
-from psycopg3.pq cimport libpq
+from psycopg3_c cimport libpq
cdef struct TextContext:
--- /dev/null
+"""
+psycopg3-c distribution version file.
+"""
+
+# Copyright (C) 2020 The Psycopg Team
+
+__version__ = "2.99.0"
--- /dev/null
+[build-system]
+requires = ["setuptools>=49.2.0", "wheel>=0.34.2", "Cython>=3.0a5"]
+build-backend = "setuptools.build_meta"
+
+[tool.black]
+line-length = 79
--- /dev/null
+[metadata]
+name = psycopg3-c
+description = PostgreSQL database adapter for Python -- C optimisation distribution
+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/psycopg3
+ Issue Tracker = https://github.com/psycopg/psycopg3/issues
+ Download = https://pypi.org/project/psycopg3-c/
+
+# TODO: classifiers
+classifiers =
+ Intended Audience :: Developers
+ Programming Language :: Python :: 3
+ License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
+ 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
+setup_requires = Cython >= 3.0a5
+packages = find:
+zip_safe = False
+include_package_data = True
--- /dev/null
+#!/usr/bin/env python3
+"""
+PostgreSQL database adapter for Python - optimisation package
+"""
+
+# Copyright (C) 2020 The Psycopg Team
+
+
+import os
+import re
+import subprocess as sp
+
+from setuptools import setup, Extension
+from distutils.command.build_ext import build_ext
+from distutils import log
+
+# 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("psycopg3_c/version.py") as f:
+ data = f.read()
+ m = re.search(r"""(?m)^__version__\s*=\s*['"]([^'"]+)['"]""", data)
+ if m is None:
+ raise Exception(f"cannot find version in {f.name}")
+ version = m.group(1)
+
+
+class psycopg3_build_ext(build_ext):
+ def finalize_options(self) -> None:
+ self._setup_ext_build()
+ super().finalize_options()
+
+ def _setup_ext_build(self) -> None:
+ cythonize = None
+
+ # In the sdist there are not .pyx, only c, so we don't need Cython
+ # Otherwise Cython is a requirement and is be used to compile pyx to c
+ if os.path.exists("psycopg3_c/_psycopg3.pyx"):
+ from Cython.Build import cythonize
+
+ # Add the include dir for the libpq.
+ try:
+ out = sp.run(
+ ["pg_config", "--includedir"], stdout=sp.PIPE, check=True
+ )
+ except Exception as e:
+ log.error("cannot build C module: %s", e)
+ raise
+
+ includedir = out.stdout.strip().decode("utf8")
+ for ext in self.distribution.ext_modules:
+ ext.include_dirs.append(includedir)
+
+ if cythonize is not None:
+ for ext in self.distribution.ext_modules:
+ ext.sources[0] = os.path.splitext(ext.sources[0])[0] + ".pyx"
+
+ self.distribution.ext_modules = cythonize(
+ self.distribution.ext_modules,
+ language_level=3,
+ annotate=False, # enable to get an html view of the C module
+ )
+ else:
+ self.distribution.ext_modules = [pgext, pqext]
+
+
+# Some details missing, to be finished by psycopg3_build_ext.finalize_options
+pgext = Extension(
+ "psycopg3_c._psycopg3",
+ ["psycopg3_c/_psycopg3.c"],
+ libraries=["pq"],
+ include_dirs=[],
+)
+
+pqext = Extension(
+ "psycopg3_c.pq_cython",
+ ["psycopg3_c/pq_cython.c"],
+ libraries=["pq"],
+ include_dirs=[],
+)
+
+setup(
+ version=version,
+ # TODO: might use a range
+ install_requires=[f"psycopg3=={version}"],
+ ext_modules=[pgext, pqext],
+ cmdclass={"build_ext": psycopg3_build_ext},
+)
--- /dev/null
+[tox]
+envlist = py{36,37,38}
+isolated_build = True
+
+[testenv]
+commands =
+ python ../psycopg3/setup.py develop
+ pytest ../tests {posargs}
+passenv = PG* PSYCOPG3_TEST_DSN PYTEST_ADDOPTS PSYCOPG3_IMPL
+deps =
+ pytest >= 5.3, < 6
+ pytest-asyncio >= 0.12.0, < 0.13
+ -e {toxinidir}/../psycopg3
+[build-system]
+requires = ["setuptools>=49.2.0", "wheel>=0.34.2"]
+build-backend = "setuptools.build_meta"
+
[tool.black]
line-length = 79
+
+[tool.pytest.ini_options]
+testpaths=[
+ "tests",
+]
+++ /dev/null
-#!/usr/bin/env python3
-"""
-psycopg3 -- PostgreSQL database adapter for Python
-"""
-
-# Copyright (C) 2020 The Psycopg Team
-
-
-import re
-import os
-import subprocess as sp
-from setuptools import setup, find_packages, Extension
-from distutils.command.build_ext import build_ext
-from distutils import log
-
-try:
- from Cython.Build import cythonize
-except ImportError:
- cythonize = None
-
-# Grab the version without importing the module
-# or we will get import errors on install if prerequisites are still missing
-fn = os.path.join(os.path.dirname(__file__), "psycopg3/consts.py")
-with open(fn) as f:
- m = re.search(r"""(?mi)^VERSION\s*=\s*["']+([^'"]+)["']+""", f.read())
-if m:
- version = m.group(1)
-else:
- raise ValueError("cannot find VERSION in the consts module")
-
-# Read the description from the README
-with open("README.rst") as f:
- readme = f.read()
-
-# TODO: classifiers
-classifiers = """
-Intended Audience :: Developers
-Programming Language :: Python :: 3
-License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
-Topic :: Database
-Topic :: Database :: Front-Ends
-Topic :: Software Development
-Topic :: Software Development :: Libraries :: Python Modules
-"""
-
-
-class psycopg3_build_ext(build_ext):
- def finalize_options(self) -> None:
- self._setup_ext_build()
- super().finalize_options()
-
- def _setup_ext_build(self) -> None:
- # Clear the dummy so if we can't build it's no drama
- self.distribution.ext_modules = None
-
- try:
- from Cython.Build import cythonize
- except ImportError:
- log.warn("Cython is not available: the C module will not be built")
- return
-
- try:
- out = sp.run(
- ["pg_config", "--includedir"], stdout=sp.PIPE, check=True
- )
- except Exception as e:
- log.warn("cannot build C module: %s", e)
- return
-
- includedir = out.stdout.strip().decode("utf8")
-
- pgext = Extension(
- "psycopg3._psycopg3",
- ["psycopg3/_psycopg3.pyx"],
- libraries=["pq"],
- include_dirs=[includedir],
- )
- pqext = Extension(
- "psycopg3.pq.pq_cython",
- ["psycopg3/pq/pq_cython.pyx"],
- libraries=["pq"],
- include_dirs=[includedir],
- )
- self.distribution.ext_modules = cythonize(
- [pgext, pqext],
- language_level=3,
- # annotate=True, # enable to get an html view of the C module
- )
-
-
-setup(
- name="psycopg3",
- description=readme.splitlines()[0],
- long_description="\n".join(readme.splitlines()[2:]).lstrip(),
- author="Daniele Varrazzo",
- author_email="daniele.varrazzo@gmail.com",
- url="https://psycopg.org/psycopg3/",
- python_requires=">=3.6",
- packages=find_packages(exclude=["tests"]),
- classifiers=[x for x in classifiers.split("\n") if x],
- setup_requires=["Cython>=3.0a2"],
- install_requires=["typing_extensions"],
- zip_safe=False,
- include_package_data=True,
- version=version,
- project_urls={
- "Homepage": "https://psycopg.org/",
- "Code": "https://github.com/psycopg/psycopg3",
- "Issue Tracker": "https://github.com/psycopg/psycopg3/issues",
- "Download": "https://pypi.org/project/psycopg3/",
- },
- cmdclass={"build_ext": psycopg3_build_ext},
- # hack to run build_ext. It will be replaced by real the stuff
- ext_modules=[Extension("psycopg3.dummy", ["dummy.c"])],
-)
import os
import pytest
-from psycopg3 import pq
-
def pytest_addoption(parser):
parser.addoption(
@pytest.fixture
def pgconn(dsn):
"""Return a PGconn connection open to `--test-dsn`."""
+ from psycopg3 import pq
+
conn = pq.PGconn.connect(dsn.encode("utf8"))
if conn.status != pq.ConnStatus.OK:
pytest.fail(
import operator
import pytest
-from psycopg3 import pq
-
def pytest_report_header(config):
+ try:
+ from psycopg3 import pq
+ except ImportError:
+ return []
+
return [
f"libpq available: {pq.version()}",
f"libpq wrapper implementation: {pq.__impl__}",
def pytest_runtest_setup(item):
+ from psycopg3 import pq
+
for m in item.iter_markers(name="libpq"):
check_libpq_version(pq.version(), m.args)
pgconn.host
-# TODO: to implement in psycopg3.pq.pq_cython
+# TODO: to implement in pq_cython
@pytest.mark.xfail
@pytest.mark.libpq(">= 12")
def test_hostaddr(pgconn):
f.write(module)
env = dict(os.environ)
env["PYTHONPATH"] = dir + os.pathsep + env.get("PYTHONPATH", "")
+ # TODO: debug this. Importing c module fails on travis in this scenario
+ env.pop("PSYCOPG3_IMPL", None)
out = sp.check_output(
[sys.executable, "-c", script], stderr=sp.STDOUT, env=env
).decode("utf8", "replace")
-# Tox is nice, but rebuilding the environment every time is kinda slow.
-# If you want to install the test environments defined here into your current
-# virtualenv you can use:
-#
-# pip install tox tox-current-env
-# tox --print-deps-to-file /tmp/requirements.txt
-# pip install -r /tmp/requirements.txt
-#
-# After which you can run the tests with:
-#
-# tox --current-env -e ENV
-#
-# or just run manually the ``commands`` defined here.
-
[tox]
-envlist = py{36,37,38}, black, flake8, mypy
-
-[testenv]
-# run setup.py develop to build the c extension in place.
-# if this doesn't happen, psycopg3 will be imported from the root directory
-# anyway rather than from the tox environment, because pytest adds the
-# root dir to the pythonpath. It sucks but I don't see a way around.
-commands =
- python setup.py develop
- pytest {posargs}
-passenv = PG* PSYCOPG3_TEST_DSN PYTEST_ADDOPTS PSYCOPG3_IMPL
-deps =
- pytest >= 5.3, < 6
- pytest-asyncio >= 0.12.0, < 0.13
+envlist = black, flake8, mypy
+isolated_build = True
[testenv:black]
commands = black --check --diff .
deps = black
+skip_install = true
[testenv:flake8]
commands = flake8
deps = flake8 >= 3.8, < 3.9
+skip_install = true
[testenv:mypy]
commands = mypy
deps = mypy >= 0.782
+changedir = psycopg3
+skip_install = true
[flake8]
max-line-length = 85