Calling the package psycopg3 doesn't allow to apply semver.
postgres: 13
env:
- PSYCOPG3_IMPL: python
+ PSYCOPG_IMPL: python
PGHOST: 127.0.0.1
PGUSER: postgres
PGPASSWORD: password
- PSYCOPG3_TEST_DSN: "dbname=postgres"
+ PSYCOPG_TEST_DSN: "dbname=postgres"
services:
postgresql:
- name: Install tox
run: pip install tox
- name: Run tests
- run: tox -c psycopg3 -e ${{ matrix.python }} -- --color yes
+ run: tox -c psycopg -e ${{ matrix.python }} -- --color yes
c:
name: C implementation
postgres: 10
env:
- PSYCOPG3_IMPL: c
+ PSYCOPG_IMPL: c
PGHOST: 127.0.0.1
PGUSER: postgres
PGPASSWORD: password
- PSYCOPG3_TEST_DSN: "dbname=postgres"
- # skip tests failing on importing psycopg3_c.pq on subprocess
+ PSYCOPG_TEST_DSN: "dbname=postgres"
+ # skip tests failing on importing psycopg_c.pq on subprocess
# they only fail on Travis, work ok locally under tox too.
PYTEST_ADDOPTS: "-m 'not subprocess'"
- name: Install tox
run: pip install tox
- name: Run tests
- run: tox -c psycopg3_c -e ${{ matrix.python }} -- --color yes
+ run: tox -c psycopg_c -e ${{ matrix.python }} -- --color yes
[mypy]
-files = psycopg3/psycopg3
+files = psycopg/psycopg
warn_unused_ignores = True
show_error_codes = True
strict = True
-mypy_path = psycopg3_c
+mypy_path = psycopg_c
[mypy-pytest]
ignore_missing_imports = True
-psycopg3 -- PostgreSQL database adapter for Python
+Psycopg 3 -- PostgreSQL database adapter for Python
==================================================
-psycopg3 is a modern implementation of a PostgreSQL adapter for Python.
+Psycopg 3 is a modern implementation of a PostgreSQL adapter for Python.
Installation
the form of packages yet. You can install it directly `from the GitHub
project`__::
- $ pip install git+https://github.com/psycopg/psycopg3.git#subdirectory=psycopg3
+ $ pip install git+https://github.com/psycopg/psycopg.git#subdirectory=psycopg
$ python3
- >>> import psycopg3
+ >>> import psycopg
-.. __: https://github.com/psycopg/psycopg3
+.. __: https://github.com/psycopg/psycopg
You are required to have the ``libpq``, the PostgreSQL client library, already
-installed in the system before using ``psycopg3``. On Debian system you can
+installed in the system before using ``psycopg``. On Debian system you can
obtain it by running::
sudo apt-get install libpq5
Hacking
-------
-In order to work on the ``psycopg3`` source code you should clone this
-repository::
+In order to work on the Psycopg source code you should clone this repository::
- git clone https://github.com/psycopg/psycopg3.git
- cd psycopg3
+ git clone https://github.com/psycopg/psycopg.git
+ cd psycopg
Please note that the repository contains the source code of several Python
packages: that's why you don't see a ``setup.py`` here. The packages may have
different requirements:
-- The ``psycopg3`` directory contains the pure python implementation of
- ``psycopg3``. The package has only a runtime dependency on the ``libpq``,
+- The ``psycopg`` directory contains the pure python implementation of
+ ``psycopg``. The package has only a runtime dependency on the ``libpq``,
the PostgreSQL client library, which should have been already installed in
your system.
-- The ``psycopg3_c`` directory contains an optimization module written in
+- The ``psycopg_c`` directory contains an optimization module written in
C/Cython. In order to build it you will need a few development tools: please
look at `Local installation`__ in the docs for the details.
- .. __: https://www.psycopg.org/psycopg3/docs/install.html#local-installation
+ .. __: https://www.psycopg.org/psycopg/docs/install.html#local-installation
You can create a local virtualenv and install there the packages `in
development mode`__, together with their development and testing
python -m venv .venv
source .venv/bin/activate
- pip install -e ./psycopg3[dev,test] # for the base Python package
- pip install -e ./psycopg3_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
.. __: https://pip.pypa.io/en/stable/reference/pip_install/#install-editable
and to run the tests::
- psql -c 'create database psycopg3_test'
- export PSYCOPG3_TEST_DSN="dbname=psycopg3_test"
- tox -c psycopg3 -s
- tox -c psycopg3_c -s
+ psql -c 'create database psycopg_test'
+ export PSYCOPG_TEST_DSN="dbname=psycopg_test"
+ tox -c psycopg -s
+ tox -c psycopg_c -s
Please look at the commands definitions in the ``tox.ini`` files if you want
to run some of them interactively: the dependency should be already in your
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) || true
serve:
- PSYCOPG3_IMPL=python sphinx-autobuild . _build/html/
+ PSYCOPG_IMPL=python sphinx-autobuild . _build/html/
.PHONY: help serve env Makefile
.venv: requirements.txt
$(PYTHON) -m venv .venv
- ./.venv/bin/pip install -e ../psycopg3
+ ./.venv/bin/pip install -e ../psycopg
./.venv/bin/pip install -r requirements.txt
# Catch-all target: route all unknown targets to Sphinx using the new
-.. currentmodule:: psycopg3.adapt
+.. currentmodule:: psycopg.adapt
.. _adaptation:
Data adaptation configuration
=============================
-The adaptation system is at the core of psycopg3 and allows to customise the
+The adaptation system is at the core of Psycopg and allows to customise the
way Python objects are converted to PostgreSQL when a query is performed and
how PostgreSQL values are converted to Python objects when query results are
returned.
described in this page is useful if you intend to *customise* the
adaptation rules.
-- The `~psycopg3.types.TypeInfo` object allows to query type information from
+- The `~psycopg.types.TypeInfo` object allows to query type information from
a database, which can be used by the adapters: for instance to make them
able to decode arrays of base types or composite types.
`!bytes` string from PostgreSQL and create a Python object.
`!Dumper` and `!Loader` are abstract classes: concrete classes must implement
-the `~Dumper.dump()` and `~Loader.load()` methods. `!psycopg3` provides
+the `~Dumper.dump()` and `~Loader.load()` methods. Psycopg provides
implementation for several builtin Python and PostgreSQL types.
Psycopg provides adapters for several builtin types, which can be used as the
-base to build more complex ones: they all live in the `psycopg3.types`
+base to build more complex ones: they all live in the `psycopg.types`
package.
---------------------------------
Dumpers and loaders can be registered on different scopes: globally, per
-`~psycopg3.Connection`, per `~psycopg3.Cursor`, so that adaptation rules can
+`~psycopg.Connection`, per `~psycopg.Cursor`, so that adaptation rules can
be customised for specific needs within the same application: in order to do
so you can use the *context* parameter of `Dumper.register()` and
`Loader.register()`.
>>> conn.execute("'infinity'::date").fetchone()
Traceback (most recent call last):
...
- psycopg3.DataError: Python date doesn't support years after 9999: got infinity
+ psycopg.DataError: Python date doesn't support years after 9999: got infinity
One possibility would be to store Python's `datetime.date.max` to PostgreSQL
infinity. For this, let's create a subclass for the dumper and the loader and
from datetime import date
- from psycopg3.oids import postgres_types as builtins
- from psycopg3.types.datetime import DateLoader, DateDumper
+ from psycopg.oids import postgres_types as builtins
+ from psycopg.types.datetime import DateLoader, DateDumper
class InfDateDumper(DateDumper):
def dump(self, obj):
Dumpers and loaders life cycle
------------------------------
-Registering dumpers and loaders will instruct `!psycopg3` to use them
+Registering dumpers and loaders will instruct `!psycopg` to use them
in the queries to follow, in the context where they have been registered.
When a query is performed on a `!Cursor`, a `Transformer` object is created
(for instance, a Python `int` might be better dumped as a PostgreSQL
:sql:`integer`, :sql:`bigint`, :sql:`smallint` according to its value).
-- According to the placeholder used (``%s``, ``%b``, ``%t``), psycopg3 may
+- According to the placeholder used (``%s``, ``%b``, ``%t``), Psycopg may
pick a binary or a text dumper. When using the ``%s`` "`~Format.AUTO`"
format, if the same type has both a text and a binary dumper registered, the
last one registered (using `Dumper.register()`) will be selected.
for each value to convert.
Querying will fail if a Python object for which there isn't a `!Dumper`
-registered (for the right `~psycopg3.pq.Format`) is used as query parameter.
+registered (for the right `~psycopg.pq.Format`) is used as query parameter.
If the query returns a data type whose OID doesn't have a `!Loader`, the
value will be returned as a string (or bytes string for binary types).
:param context: The context where the transformation is performed. If not
specified the conversion might be inaccurate, for instance it will not
be possible to know the connection encoding or the server date format.
- :type context: `~psycopg3.Connection`, `~psycopg3.Cursor`, or `Transformer`
+ :type context: `~psycopg.Connection`, `~psycopg.Cursor`, or `Transformer`
.. attribute:: format
:type: pq.Format
.. tip::
- This method will be used by `~psycopg3.sql.Literal` to convert a
+ This method will be used by `~psycopg.sql.Literal` to convert a
value client-side.
This method only makes sense for text dumpers; the result of calling
:type cls: `!type` or `!str`
:param context: Where the dumper should be used. If `!None` the dumper
will be used globally.
- :type context: `~psycopg3.Connection`, `~psycopg3.Cursor`, or `Transformer`
+ :type context: `~psycopg.Connection`, `~psycopg.Cursor`, or `Transformer`
If *cls* is specified as string it will be lazy-loaded, so that it
will be possible to register it without importing it before. In this
:param context: The context where the transformation is performed. If not
specified the conversion might be inaccurate, for instance it will not
be possible to know the connection encoding or the server date format.
- :type context: `~psycopg3.Connection`, `~psycopg3.Cursor`, or `Transformer`
+ :type context: `~psycopg.Connection`, `~psycopg.Cursor`, or `Transformer`
.. attribute:: format
:type: Format
:type oid: `!int`
:param context: Where the loader should be used. If `!None` the loader
will be used globally.
- :type context: `~psycopg3.Connection`, `~psycopg3.Cursor`, or `Transformer`
+ :type context: `~psycopg.Connection`, `~psycopg.Cursor`, or `Transformer`
.. autoclass:: Transformer(context=None)
:param context: The context where the transformer should operate.
- :type context: `~psycopg3.Connection`, `~psycopg3.Cursor`, or `Transformer`
+ :type context: `~psycopg.Connection`, `~psycopg.Cursor`, or `Transformer`
TODO: finalise the interface of this object
-.. currentmodule:: psycopg3
+.. currentmodule:: psycopg
.. index:: asyncio
Async operations
================
-psycopg3 `~Connection` and `~Cursor` have counterparts `~AsyncConnection` and
+Psycopg `~Connection` and `~Cursor` have counterparts `~AsyncConnection` and
`~AsyncCursor` supporting an `asyncio` interface.
The design of the asynchronous objects is pretty much the same of the sync
.. code:: python
- async with await psycopg3.AsyncConnection.connect(
+ async with await psycopg.AsyncConnection.connect(
"dbname=test user=postgres") as aconn:
async with aconn.cursor() as acur:
await acur.execute(
.. code:: python
- with psycopg3.connect("dbname=test user=postgres") as conn:
+ with psycopg.connect("dbname=test user=postgres") as conn:
with conn.cursor() as cur:
cur.execute(...)
# the cursor is closed upon leaving the context
.. code:: python
- aconn = await psycopg3.AsyncConnection.connect():
+ aconn = await psycopg.AsyncConnection.connect():
async with aconn:
async with aconn.cursor() as cur:
await cur.execute(...)
.. code:: python
- async with await psycopg3.AsyncConnection.connect() as aconn:
+ async with await psycopg.AsyncConnection.connect() as aconn:
async with aconn.cursor() as cur:
await cur.execute(...)
.. code:: python
- import psycopg3
- conn = psycopg3.connect("", autocommit=True)
+ import psycopg
+ conn = psycopg.connect("", autocommit=True)
conn.cursor().execute("LISTEN mychan")
gen = conn.notifies()
for notify in gen:
# Activity detected. Is the connection still ok?
try:
conn.execute("select 1")
- except psycopg3.OperationalError:
+ except psycopg.OperationalError:
# You were disconnected: do something useful such as panicking
logger.error("we lost our database!")
sys.exit(1)
# Activity detected. Is the connection still ok?
try:
await conn.execute("select 1")
- except psycopg3.OperationalError:
+ except psycopg.OperationalError:
# Guess what happened
...
-.. currentmodule:: psycopg3
+.. currentmodule:: psycopg
.. index::
pair: COPY; SQL command
Using COPY TO and COPY FROM
===========================
-`psycopg3` allows to operate with `PostgreSQL COPY protocol`__. :sql:`COPY` is
+Psycopg allows to operate with `PostgreSQL COPY protocol`__. :sql:`COPY` is
one of the most efficient ways to load data into the database (and to modify
it, with some SQL creativity).
# pass data to the 'copy' object using write()/write_row()
You can compose a COPY statement dynamically by using objects from the
-`psycopg3.sql` module:
+`psycopg.sql` module:
.. code:: python
-.. currentmodule:: psycopg3
+.. currentmodule:: psycopg
.. index::
single: Cursor
Cursor types
============
-`!psycopg3` can manage kinds of "cursors" which differ in where the state of a
+Psycopg can manage kinds of "cursors" which differ in where the state of a
query being processed is stored: :ref:`client-side-cursors` and
:ref:`server-side-cursors`.
Client-side cursors
-------------------
-Client-side cursors are what `!psycopg3` uses in its normal querying process.
+Client-side cursors are what Psycopg uses in its normal querying process.
They are implemented by the `Cursor` and `AsyncCursor` classes. In such
querying pattern, after a cursor sends a query to the server (usually calling
`~Cursor.execute()`), the server replies transferring to the client the whole
The downside is that the server needs to keep track of the partially
processed results, so it uses more memory and resources on the server.
-`!psycopg3` allows the use of server-side cursors using the classes
+Psycopg allows the use of server-side cursors using the classes
`ServerCursor` and `AsyncServerCursor`. They are usually created by passing
the *name* parameter to the `~Connection.cursor()` method (in `!psycopg2` they
are also called *named cursors*). The use of these classes is similar to their
"Stealing" an existing cursor
-----------------------------
-A `!psycopg3` `ServerCursor` can be also used to consume a cursor that the
+A Psycopg `ServerCursor` can be also used to consume a cursor that the
:sql:`DECLARE` generated by its `~ServerCursor.execute()` method can produce.
For instance if you have a PL/pgSQL function creating a cursor:
-.. currentmodule:: psycopg3.pool
+.. currentmodule:: psycopg.pool
.. _connection-pools:
.. __: https://en.wikipedia.org/wiki/Connection_pool
-This page explains a few basic concepts of `!psycopg3` connection pool's
+This page explains a few basic concepts of Psycopg connection pool's
behaviour. Please refer to the `ConnectionPool` object API for details about
the pool operations.
connection is ready.
The main way to use the pool is to obtain a connection using the
-`~ConnectionPool.connection()` context, which returns a `~psycopg3.Connection`
+`~ConnectionPool.connection()` context, which returns a `~psycopg.Connection`
or subclass::
with my_pool.connection() as conn:
-.. currentmodule:: psycopg3
+.. currentmodule:: psycopg
.. index::
single: Prepared statements
Prepared statements
===================
-`!psycopg3` uses an automatic system to manage *prepared statements*. When a
+Psycopg uses an automatic system to manage *prepared statements*. When a
query is prepared, its parsing and planning is stored in the server session,
so that further executions of the same query on the same connection (even with
different parameters) are optimised.
A query is prepared automatically after it is executed more than
-`~Connection.prepare_threshold` times on a connection. `!psycopg3` will make
+`~Connection.prepare_threshold` times on a connection. `!psycopg` will make
sure that no more than `~Connection.prepared_max` statements are planned: if
further queries are executed, the least recently used ones are deallocated and
the associated resources freed.
The `PREPARE`__ PostgreSQL documentation contains plenty of details about
prepared statements in PostgreSQL.
- Note however that `!psycopg3` doesn't use SQL statements such as
+ Note however that Psycopg doesn't use SQL statements such as
:sql:`PREPARE` and :sql:`EXECUTE`, but protocol level commands such as the
ones exposed by :pq:`PQsendPrepare`, :pq:`PQsendQueryPrepared`.
-.. currentmodule:: psycopg3
+.. currentmodule:: psycopg
.. index:: row factories
be changed to adapt the needs of the programmer by using custom *row
factories*.
-A row factory (formally implemented by the `~psycopg3.rows.RowFactory`
+A row factory (formally implemented by the `~psycopg.rows.RowFactory`
protocol) is a callable that accepts a `Cursor` object and returns another
-callable (formally the `~psycopg3.rows.RowMaker` protocol) accepting a
+callable (formally the `~psycopg.rows.RowMaker` protocol) accepting a
`values` tuple and returning a row in the desired form.
-.. autoclass:: psycopg3.rows.RowMaker()
+.. autoclass:: psycopg.rows.RowMaker()
.. method:: __call__(values: Sequence[Any]) -> Row
Convert a sequence of values from the database to a finished object.
-.. autoclass:: psycopg3.rows.RowFactory()
+.. autoclass:: psycopg.rows.RowFactory()
.. method:: __call__(cursor: AnyCursor[Row]) -> RowMaker[Row]
Inspect the result on a cursor and return a `RowMaker` to convert rows.
- `!AnyCursor` may be either a `~psycopg3.Cursor` or an
- `~psycopg3.AsyncCursor`.
+ `!AnyCursor` may be either a `~psycopg.Cursor` or an
+ `~psycopg.AsyncCursor`.
`~RowFactory` objects can be implemented as a class, for instance:
.. code:: python
from typing import Any, Sequence
- from psycopg3 import AnyCursor
+ from psycopg import AnyCursor
class DictRowFactory:
def __init__(self, cursor: AnyCursor[dict[str, Any]]):
.. code:: python
- conn = psycopg3.connect(row_factory=DictRowFactory)
+ conn = psycopg.connect(row_factory=DictRowFactory)
cur = conn.execute("SELECT first_name, last_name, age FROM persons")
person = cur.fetchone()
print(f"{person['first_name']} {person['last_name']}")
Available row factories
-----------------------
-The module `psycopg3.rows` provides the implementation for a few row factories:
+The module `psycopg.rows` provides the implementation for a few row factories:
-.. currentmodule:: psycopg3.rows
+.. currentmodule:: psycopg.rows
.. autofunction:: tuple_row(cursor: AnyCursor[TupleRow])
.. autodata:: TupleRow
Use with a static analyzer
--------------------------
-The `~psycopg3.Connection` and `~psycopg3.Cursor` classes are `generic
+The `~psycopg.Connection` and `~psycopg.Cursor` classes are `generic
types`__: the parameter `!Row` is passed by the ``row_factory`` argument (of
the `~Connection.connect()` and the `~Connection.cursor()` method) and it
controls what type of record is returned by the fetch methods of the cursors.
.. code:: python
- conn = psycopg3.connect()
- # conn type is psycopg3.Connection[Tuple[Any, ...]]
+ conn = psycopg.connect()
+ # conn type is psycopg.Connection[Tuple[Any, ...]]
- dconn = psycopg3.connect(row_factory=dict_row)
- # dconn type is psycopg3.Connection[Dict[str, Any]]
+ dconn = psycopg.connect(row_factory=dict_row)
+ # dconn type is psycopg.Connection[Dict[str, Any]]
cur = conn.cursor()
- # cur type is psycopg3.Cursor[Tuple[Any, ...]]
+ # cur type is psycopg.Cursor[Tuple[Any, ...]]
dcur = conn.cursor(row_factory=dict_row)
dcur = dconn.cursor()
- # dcur type is psycopg3.Cursor[Dict[str, Any]] in both cases
+ # dcur type is psycopg.Cursor[Dict[str, Any]] in both cases
rec = cur.fetchone()
# rec type is Optional[Tuple[Any, ...]]
from datetime import date
from typing import Any, Optional, Sequence
- import psycopg3
+ import psycopg
from pydantic import BaseModel
class Person(BaseModel):
dob: Optional[date]
class PersonFactory:
- def __init__(self, cur: psycopg3.AnyCursor[Person]):
+ def __init__(self, cur: psycopg.AnyCursor[Person]):
assert cur.description
self.fields = [c.name for c in cur.description]
return Person(**dict(zip(self.fields, values)))
def fetch_person(id: int) -> Person:
- conn = psycopg3.connect()
+ conn = psycopg.connect()
cur = conn.cursor(row_factory=PersonFactory)
cur.execute(
"""
-.. currentmodule:: psycopg3
+.. currentmodule:: psycopg
Connection classes
==================
See `transactions` for details.
:param row_factory: The row factory specifying what type of records
to create fetching data (default:
- `~psycopg3.rows.tuple_row()`). See
+ `~psycopg.rows.tuple_row()`). See
:ref:`row-factories` for details.
.. __: https://www.postgresql.org/docs/current/libpq-connect.html
#LIBPQ-CONNSTRING
- This method is also aliased as `psycopg3.connect()`.
+ This method is also aliased as `psycopg.connect()`.
.. seealso::
.. automethod:: add_notice_handler
- :param callback: a callable taking a `~psycopg3.errors.Diagnostic`
+ :param callback: a callable taking a `~psycopg.errors.Diagnostic`
object containing all the details about the notice.
.. automethod:: remove_notice_handler
.. autoattribute:: hostaddr
Only available if the libpq used is at least from PostgreSQL 12.
- Raise `~psycopg3.NotSupportedError` otherwise.
+ Raise `~psycopg.NotSupportedError` otherwise.
.. autoattribute:: port
.. autoattribute:: dbname
-.. currentmodule:: psycopg3
+.. currentmodule:: psycopg
Cursor classes
==============
The property affects the objects returned by the `fetchone()`,
`fetchmany()`, `fetchall()` methods. The default
- (`~psycopg3.rows.tuple_row`) returns a tuple for each record fetched.
+ (`~psycopg.rows.tuple_row`) returns a tuple for each record fetched.
See :ref:`row-factories` for details.
.. automethod:: nextset
.. automethod:: scroll
.. attribute:: pgresult
- :type: Optional[psycopg3.pq.PGresult]
+ :type: Optional[psycopg.pq.PGresult]
The result returned by the last query and currently exposed by the
cursor, if available, else `!None`.
.. index::
single: Error; Class
-.. module:: psycopg3
+.. module:: psycopg
This module exposes objects to represent and examine database errors.
.. autoattribute:: diag
-.. module:: psycopg3.errors
+.. module:: psycopg.errors
.. autoclass:: Diagnostic()
The object is returned by the `Error.diag` attribute and is passed to the
callback functions registered with
- `~psycopg3.Connection.add_notice_handler()`.
+ `~psycopg.Connection.add_notice_handler()`.
All the information available from the :pq:`PQresultErrorField()` function
are exposed as attributes by the object. For instance the `!severity`
server versions.
-.. currentmodule:: psycopg3
+.. currentmodule:: psycopg
.. index::
single: Exceptions; DB-API
DB-API exceptions
-----------------
-In compliance with the DB-API, all the exceptions raised by ``psycopg3``
+In compliance with the DB-API, all the exceptions raised by Psycopg
derive from the following classes:
.. parsed-literal::
\|__ `ProgrammingError`
\|__ `NotSupportedError`
-These classes are also exposed both by the `!psycopg3` and the
-`!psycopg3.errors` module.
+These classes are also exposed both by the Psycopg and the
+`!psycopg.errors` module.
.. autoexception:: Warning()
.. autoexception:: InterfaceError()
.. autoexception:: NotSupportedError()
-.. currentmodule:: psycopg3.errors
+.. currentmodule:: psycopg.errors
.. index::
single: Exceptions; PostgreSQL
called SQLSTATE (available in the `~Diagnostic.sqlstate` attribute of
`Error.diag`).
-``psycopg3`` exposes a different class for each SQLSTATE value, allowing to
+Psycopg exposes a different class for each SQLSTATE value, allowing to
write idiomatic error handling code according to specific conditions happening
in the database:
try:
cur.execute("LOCK TABLE mytable IN ACCESS EXCLUSIVE MODE NOWAIT")
- except psycopg3.errors.LockNotAvailable:
+ except psycopg.errors.LockNotAvailable:
locked = True
The exception names are generated from the PostgreSQL source code and includes
try:
cur.execute("LOCK TABLE mytable IN ACCESS EXCLUSIVE MODE NOWAIT")
- except psycopg3.errors.lookup("55P03"):
+ except psycopg.errors.lookup("55P03"):
locked = True
These are all the classes defined and the DBAPI exception they derive from:
-``psycopg3`` API
-================
+Psycopg 3 API
+=============
.. toctree::
:maxdepth: 1
.. index::
double: Connection; Pool
-.. module:: psycopg3.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
details and usage pattern.
There package implement two connection pools: `ConnectionPool` is a
-synchronous connection pool yielding `~psycopg3.Connection` objects and can be
+synchronous connection pool yielding `~psycopg.Connection` objects and can be
used by multithread applications. `AsyncConnectionPool` has a similar
interface, but with `asyncio` functions replacing blocking functions, and
-yields `~psycopg3.AsyncConnection` instances.
+yields `~psycopg.AsyncConnection` instances.
The intended use (but not mandatory) is to create a single connection pool, as
a global object exposed by a module in your application, and use the same
required.
:param conninfo: The connection string. See
- `~psycopg3.Connection.connect()` for details.
+ `~psycopg.Connection.connect()` for details.
:type conninfo: `!str`
:param min_size: The minimum number of connection the pool will hold. The
:param connection_class: The class of the connections to serve. It should
be a `!Connection` subclass.
- :type connection_class: `!type`, default: `~psycopg3.Connection`
+ :type connection_class: `!type`, default: `~psycopg.Connection`
:param configure: A callback to configure a connection after creation.
Useful, for instance, to configure its adapters. If the
.. autoclass:: PoolTimeout()
- Subclass of `~psycopg3.OperationalError`
+ Subclass of `~psycopg.OperationalError`
.. autoclass:: PoolClosed()
- Subclass of `~psycopg3.OperationalError`
+ Subclass of `~psycopg.OperationalError`
.. autoclass:: TooManyRequests()
- Subclass of `~psycopg3.OperationalError`
+ Subclass of `~psycopg.OperationalError`
The `!AsyncConnectionPool` class
:param connection_class: The class of the connections to serve. It should
be an `!AsyncConnection` subclass.
- :type connection_class: `!type`, default: `~psycopg3.AsyncConnection`
+ :type connection_class: `!type`, default: `~psycopg.AsyncConnection`
:param configure: A callback to configure a connection after creation.
:type configure: `async Callable[[AsyncConnection], None]`
-.. _psycopg3.pq:
+.. _psycopg.pq:
`pq` -- libpq wrapper module
============================
.. index::
single: libpq
-.. module:: psycopg3.pq
+.. module:: psycopg.pq
-``psycopg3`` is built around the libpq_, the PostgreSQL client library, which
+Psycopg is built around the libpq_, the PostgreSQL client library, which
performs most of the network communications and returns query results in C
structures.
.. _libpq: https://www.postgresql.org/docs/current/libpq.html
The low-level functions of the library are exposed by the objects in the
-`!psycopg3.pq` module.
+`!psycopg.pq` module.
.. _pq-impl:
in Cython_). It is much better performing than the ``python``
implementation, however it requires development packages installed on the
client machine. It can be installed using the ``c`` extra, i.e. running
- ``pip install psycopg3[c]``.
+ ``pip install psycopg[c]``.
- ``binary``: a pre-compiled C implementation, bundled with all the required
libraries. It is the easiest option to deal with, fast to install and it
should require no development tool or client library, however it may be not
available for every platform. You can install it using the ``binary`` extra,
- i.e. running ``pip install psycopg3[binary]``.
+ i.e. running ``pip install psycopg[binary]``.
.. _Cython: https://cython.org/
-The implementation currently used is available in the `~psycopg3.pq.__impl__`
+The implementation currently used is available in the `~psycopg.pq.__impl__`
module constant.
-At import, ``psycopg3`` will try to use the best implementation available and
+At import, Psycopg 3 will try to use the best implementation available and
will fail if none is usable. You can force the use of a specific
-implementation by exporting the env var :envvar:`PSYCOPG3_IMPL`: importing the
+implementation by exporting the env var :envvar:`PSYCOPG_IMPL`: importing the
library will fail if the requested implementation is not available.
.. autodata:: __impl__
The choice of implementation is automatic but can be forced setting the
- :envvar:`PSYCOPG3_IMPL` env var.
+ :envvar:`PSYCOPG_IMPL` env var.
.. autofunction:: version
.. index::
double: Binding; Client-Side
-.. module:: psycopg3.sql
+.. module:: psycopg.sql
The module contains objects and functions useful to generate SQL dynamically,
in a convenient and safe way. SQL identifiers (e.g. names of tables and
-fields) cannot be passed to the `~psycopg3.Cursor.execute()` method like query
+fields) cannot be passed to the `~psycopg.Cursor.execute()` method like query
arguments::
# This will not work
This sort of works, but it is an accident waiting to happen: the table name
may be an invalid SQL literal and need quoting; even more serious is the
security problem in case the table name comes from an untrusted source. The
-name should be escaped using `~psycopg3.pq.Escaping.escape_identifier()`::
+name should be escaped using `~psycopg.pq.Escaping.escape_identifier()`::
- from psycopg3.pq import Escaping
+ from psycopg.pq import Escaping
# This works, but it is not optimal
table_name = 'my_table'
containing characters to escape, or will present a potentially exploitable
weakness.
-The objects exposed by the `!psycopg3.sql` module allow generating SQL
+The objects exposed by the `!psycopg.sql` module allow generating SQL
statements on the fly, separating clearly the variable parts of the statement
from the query parameters::
- from psycopg3 import sql
+ from psycopg import sql
cur.execute(
sql.SQL("insert into {} values (%s, %s)")
with ``{}``\-style placeholders and use `~SQL.format()` to merge the variable
parts into them, all of which must be `Composable` subclasses. You can still
have ``%s``\-style placeholders in your query and pass values to
-`~psycopg3.Cursor.execute()`: such value placeholders will be untouched by
+`~psycopg.Cursor.execute()`: such value placeholders will be untouched by
`!format()`::
query = sql.SQL("select {field} from {table} where {pkey} = %s").format(
pkey=sql.Identifier('id'))
The resulting object is meant to be passed directly to cursor methods such as
-`~psycopg3.Cursor.execute()`, `~psycopg3.Cursor.executemany()`,
-`~psycopg3.Cursor.copy()`, but can also be used to compose a query as a Python
+`~psycopg.Cursor.execute()`, `~psycopg.Cursor.executemany()`,
+`~psycopg.Cursor.copy()`, but can also be used to compose a query as a Python
string, using the `~Composable.as_string()` method::
cur.execute(query, (42,))
| ``|__`` `SQL`: a literal snippet of an SQL query
| ``|__`` `Identifier`: a PostgreSQL identifier or dot-separated sequence of identifiers
| ``|__`` `Literal`: a value hardcoded into a query
-| ``|__`` `Placeholder`: a `%s`\ -style placeholder whose value will be added later e.g. by `~psycopg3.Cursor.execute()`
+| ``|__`` `Placeholder`: a `%s`\ -style placeholder whose value will be added later e.g. by `~psycopg.Cursor.execute()`
| ``|__`` `Composed`: a sequence of `!Composable` instances.
-.. currentmodule:: psycopg3.types
+.. currentmodule:: psycopg.types
-.. _psycopg3.types:
+.. _psycopg.types:
`!types` -- types mapping and adaptation
========================================
-.. module:: psycopg3.types
+.. module:: psycopg.types
-The `!psycopg3.types` package exposes the concrete implementation of `Loader`
+The `!psycopg.types` package exposes the concrete implementation of `Loader`
and `Dumper` to manage builtin objects, together with objects to describe
PostgreSQL types and wrappers to help or customise the types conversion.
database for custom data types: this allows for instance to load automatically
arrays of a custom type, once a loader for the base type has been registered.
-The `!TypeInfo` object doesn't instruct `!psycopg3` to convert a PostgreSQL
+The `!TypeInfo` object doesn't instruct Psycopg to convert a PostgreSQL
type into a Python type: this is the role of a `Loader`. However it can extend
the behaviour of the adapters: if you create a loader for `!MyType`, using
`TypeInfo` you will be able to manage seamlessly arrays of `!MyType` or ranges
.. code:: python
- from psycopg3.adapt import Loader
- from psycopg3.types import TypeInfo
+ from psycopg.adapt import Loader
+ from psycopg.types import TypeInfo
t = TypeInfo.fetch(conn, "mytype")
t.register(conn)
.. automethod:: fetch_async
.. automethod:: register
- The *context* can be a `~psycopg3.Connection` or `~psycopg3.Cursor`.
+ The *context* can be a `~psycopg.Connection` or `~psycopg.Cursor`.
Specifying no context will register the `!TypeInfo` globally.
Registering the `TypeInfo` in a context allows the adapters of that
specialised adapters configurations.
-.. autoclass:: psycopg3.types.composite.CompositeInfo
+.. autoclass:: psycopg.types.composite.CompositeInfo
.. automethod:: register
custom object if *factory* is specified.
-.. autoclass:: psycopg3.types.range.RangeInfo
+.. autoclass:: psycopg.types.range.RangeInfo
.. automethod:: register
JSON adapters
-------------
-.. currentmodule:: psycopg3.types.json
+.. currentmodule:: psycopg.types.json
.. autoclass:: Json
.. autoclass:: Jsonb
.. autoclass:: JsonbDumper
.. autoclass:: JsonbBinaryDumper
-`~psycopg3.adapt.Dumper` subclasses using the function provided by
+`~psycopg.adapt.Dumper` subclasses using the function provided by
`set_json_dumps()` function to serialize the Python object wrapped by
`Json`/`Jsonb`.
If you need to specify different `!dumps()` functions in different contexts
you can subclass one/some of these functions to override the
-`~JsonDumper.get_dumps()` method and `~psycopg3.adapt.Dumper.register()` them
+`~JsonDumper.get_dumps()` method and `~psycopg.adapt.Dumper.register()` them
on the right connection or cursor.
.. autoclass:: JsonLoader
.. autoclass:: JsonbLoader
.. autoclass:: JsonbBinaryLoader
-`~psycopg3.adapt.Loader` subclasses using the function provided by
+`~psycopg.adapt.Loader` subclasses using the function provided by
`set_json_loads()` function to de-serialize :sql:`json`/:sql:`jsonb`
PostgreSQL values to Python objects.
If you need to specify different `!loads()` functions in different contexts
you can subclass one/some of these functions to override the
-`~JsonLoader.get_loads()` method and `~psycopg3.adapt.Loader.register()` them
+`~JsonLoader.get_loads()` method and `~psycopg.adapt.Loader.register()` them
on the right connection or cursor.
-.. currentmodule:: psycopg3
+.. currentmodule:: psycopg
.. index::
single: Adaptation
# UndefinedFunction: operator does not exist: date + bigint
In this case you should add an :sql:`::int` cast to your query or use the
- `~psycopg3.types.Int4` wrapper::
+ `~psycopg.types.numeric.Int4` wrapper::
cur.execute("select current_date + %s::int", [1])
.. code:: python
- conn = psycopg3.connect()
+ conn = psycopg.connect()
conn.execute(
"insert into strtest (id, data) values (%s, %s)",
(1, "Crème Brûlée at 4.99€"))
JSON adaptation
---------------
-`!psycopg3` can map between Python objects and PostgreSQL `json/jsonb
+Psycopg can map between Python objects and PostgreSQL `json/jsonb
types`__, allowing to customise the load and dump function used.
.. __: https://www.postgresql.org/docs/current/datatype-json.html
Because several Python objects could be considered JSON (dicts, lists,
scalars, even date/time if using a dumps function customised to use them),
-`!psycopg3` requires you to wrap what you want to dump as JSON into a wrapper:
-either `psycopg3.types.Json` or `~psycopg3.types.Jsonb`.
+Psycopg requires you to wrap what you want to dump as JSON into a wrapper:
+either `psycopg.types.json.Json` or `~psycopg.types.json.Jsonb`.
.. code:: python
- from psycopg3.types.json import Jsonb
+ from psycopg.types.json import Jsonb
thing = {"foo": ["bar", 42]}
conn.execute("insert into mytable values (%s)", [Jsonb(thing)])
-By default `!psycopg3` uses the standard library `json.dumps()`__ and
+By default Psycopg uses the standard library `json.dumps()`__ and
`json.loads()`__ functions to serialize and de-serialize Python objects to
JSON. If you want to customise globally how serialization happens, for
instance changing serialization parameters or using a different JSON library,
you can specify your own functions using the
-`psycopg3.types.json.set_json_dumps()` and
-`~psycopg3.types.json.set_json_loads()` functions.
+`psycopg.types.json.set_json_dumps()` and
+`~psycopg.types.json.set_json_loads()` functions.
..
weird: intersphinx doesn't work
.. code:: python
from functools import partial
- from psycopg3.types.json import Jsonb, set_json_dumps, set_json_loads
+ from psycopg.types.json import Jsonb, set_json_dumps, set_json_loads
import ujson
# Use a faster dump function
-Getting started with ``psycopg3``
-=================================
+Getting started with Psycopg 3
+==============================
.. toctree::
:maxdepth: 1
Installing the development state
--------------------------------
-``psycopg3`` packages have not been released yet, but you can try it out
+Psycopg 3 packages have not been released yet, but you can try it out
already by installing it `from the GitHub project`__:
.. code:: bash
- $ pip install git+https://github.com/psycopg/psycopg3.git#subdirectory=psycopg3
+ $ pip install git+https://github.com/psycopg/psycopg.git#subdirectory=psycopg
$ python3
- >>> import psycopg3
+ >>> import psycopg
-.. __: https://github.com/psycopg/psycopg3
+.. __: https://github.com/psycopg/psycopg
.. _binary-install:
.. warning::
- `!psycopg3` is still in a development phase: packages haven't been
+ Psycopg 3 is still in a development phase: packages haven't been
released yet on PyPI.
Please refer to `the README`__ for the current installation state, and
please know that things may change.
- .. __: https://github.com/psycopg/psycopg3#readme
+ .. __: https://github.com/psycopg/psycopg#readme
The following is how it will be *supposed* to work, once it is released...
-The quickest way to start developing with psycopg3 is to install the binary
+The quickest way to start developing with Psycopg 3 is to install the binary
packages by running::
- pip install psycopg3[binary]
+ pip install psycopg[binary]
This will install a self-contained package with all the libraries needed.
.. seealso::
- Did ``psycopg3`` install ok? Great! You can now move on to the :ref:`basic
+ Did Psycopg 3 install ok? Great! You can now move on to the :ref:`basic
module usage <module-usage>` to learn how it works.
You can come back here if you the above method didn't work and you need a
- way to install ``psycopg3`` past the basic one.
+ way to install Psycopg 3 past the basic one.
.. _local-installation:
A "Local installation" means obtaining a performing and maintainable library.
The library will include a performing C module and will be bound to the system
libraries (``libpq``, ``libssl``...) so that system upgrade of libraries will
-upgrade the libraries used by ``psycopg3`` too.
+upgrade the libraries used by Psycopg 3 too.
In order to perform a local installation you need some prerequisites:
If your build prerequisites are in place you can run::
- pip install psycopg3[c]
+ pip install psycopg[c]
.. _pure-python-installation:
If you simply install::
- pip install psycopg3
+ pip install psycopg
without ``[c]`` or ``[binary]`` extras you will obtain a pure Python
implementation. This is particularly handy to debug and hack, but it still
-``psycopg3`` and the ``libpq``
-------------------------------
+Psycopg 3 and the ``libpq``
+---------------------------
.. admonition:: TODO
-.. currentmodule:: psycopg3
+.. currentmodule:: psycopg
.. index::
pair: Query; Parameters
- The variables placeholder *must always be a* ``%s``, even if a different
placeholder (such as a ``%d`` for integers or ``%f`` for floats) may look
more appropriate for the type. You may find other placeholders used in
- `~psycopg3` queries (``%b`` and ``%t``) but they are not related to the
+ Psycopg queries (``%b`` and ``%t``) but they are not related to the
type of the argument: see :ref:`binary-data` if you want to read more::
cur.execute("INSERT INTO numbers VALUES (%d)", (10,)) # WRONG
- Only query values should be bound via this method: it shouldn't be used to
merge table or field names to the query. If you need to generate SQL queries
dynamically (for instance choosing a table name at runtime) you can use the
- functionalities provided in the `psycopg3.sql` module::
+ functionalities provided in the `psycopg.sql` module::
cur.execute("INSERT INTO %s VALUES (%s)", ('numbers', 10)) # WRONG
cur.execute( # correct
.. seealso::
Now that you know how to pass parameters to queries, you can take a look
- at :ref:`how psycopg3 converts data types <types-adaptation>`.
+ at :ref:`how Psycopg converts data types <types-adaptation>`.
.. index::
-----------------------------
PostgreSQL has two different ways to represent data type on the wire:
-`~psycopg3.pq.Format.TEXT`, always available, and
-`~psycopg3.pq.Format.BINARY`, available most of the times. Usually the binary
+`~psycopg.pq.Format.TEXT`, always available, and
+`~psycopg.pq.Format.BINARY`, available most of the times. Usually the binary
format is more efficient to use.
-`~psycopg3` can support both the formats of each data type. Whenever a value
+Psycopg can support both the formats of each data type. Whenever a value
is passed to a query using the normal ``%s`` placeholder, the best format
available is chosen (often, but not always, the binary format is picked as the
best choice).
If you have a reason to select explicitly the binary format or the text format
for a value you can use respectively a ``%b`` placeholder or a ``%t``
placeholder instead. `~Cursor.execute()` will fail if a
-`~psycopg3.adapt.Dumper` for the right parameter type and format is not
+`~psycopg.adapt.Dumper` for the right parameter type and format is not
available.
The same two formats, text or binary, are used by PostgreSQL to return data
from a query to the client. Unlike with parameters, where you can choose the
format value-by-value, all the columns returned by a query will have the same
format. For each of the types returned by the query, a
-`~psycopg3.adapt.Loader` must be available, otherwise the data will be
+`~psycopg.adapt.Loader` must be available, otherwise the data will be
returned as unparsed `!str` or buffer.
.. warning::
Currently the default is to return values from database queries in textual
type, for the simple reason that not all the PostgreSQL data types have a
binary `!Loader` implemented. The plan is to support the binary format for
- all PostgreSQL builtins before the first `psycopg3` released: TODO!
+ all PostgreSQL builtins before the first Psycopg 3 released: TODO!
By default the data will be returned in text format. In order to return data
in binary format you can create the cursor using `Connection.cursor`\
-.. currentmodule:: psycopg3
+.. currentmodule:: psycopg
.. index:: Transactions management
.. index:: InFailedSqlTransaction
Transaction management
======================
-`!psycopg3` has a behaviour that may result surprising compared to
+Psycopg has a behaviour that may result surprising compared to
:program:`psql`: by default, any database operation will start a new
transaction. As a consequence, changes made by any cursor of the connection
will not be visible until `Connection.commit()` is called, and will be
-----------------------
The manual commit requirement can be suspended using `~Connection.autocommit`,
-either as connection attribute or as `~psycopg3.Connection.connect()`
+either as connection attribute or as `~psycopg.Connection.connect()`
parameter. This may be required to run operations that cannot be executed
inside a transaction, such as :sql:`CREATE DATABASE`, :sql:`VACUUM`,
:sql:`CALL` on `stored procedures`__ using transaction control.
.. code:: python
- from psycopg3 import Rollback
+ from psycopg import Rollback
with conn.transaction() as outer_tx:
for command in commands():
-.. currentmodule:: psycopg3
+.. currentmodule:: psycopg
.. _module-usage:
.. _usage:
-Main objects in ``psycopg3``
-----------------------------
+Main objects in Psycopg 3
+-------------------------
Here is an interactive session showing some of the basic commands:
.. code:: python
- import psycopg3
+ import psycopg
# Connect to an existing database
- with psycopg3.connect("dbname=test user=postgres") as conn:
+ with psycopg.connect("dbname=test user=postgres") as conn:
# Open a cursor to perform database operations
with conn.cursor() as cur:
Connection context
------------------
-`!psycopg3` `Connection` can be used as a context manager:
+Psycopg 3 `Connection` can be used as a context manager:
.. code:: python
- with psycopg3.connect() as conn:
+ with psycopg.connect() as conn:
... # use the connection
# the connection is now closed
# -- Project information -----------------------------------------------------
-project = "psycopg3"
+project = "psycopg"
copyright = "2020-2021, Daniele Varrazzo and The Psycopg Team"
author = "Daniele Varrazzo"
release = "UNRELEASED"
Differences from ``psycopg2``
=============================
-`!psycopg3` uses the common DBAPI structure of many other database adapter and
+Psycopg 3 uses the common DBAPI structure of many other database adapter and
tries to behave as close as possible to `!psycopg2`. There are however a few
differences to be aware of.
Server-side binding
-------------------
-`!psycopg3` sends the query and the parameters to the server separately,
+Psycopg 3 sends the query and the parameters to the server separately,
instead of merging them client-side. PostgreSQL may behave slightly
differently in this case, usually throwing an error and suggesting to use an
explicit cast.
PostgreSQL will also reject the execution of several queries at once
(separated by semicolon), if they contain parameters. If parameters are used
you should use distinct `execute()` calls; otherwise you may consider merging
-the query client-side, using `psycopg3.sql` module.
+the query client-side, using `psycopg.sql` module.
Certain commands cannot be used with server-side binding, for instance
:sql:`SET` or :sql:`NOTIFY`::
>>> cur.execute("SET timezone TO %s", ["utc"])
...
- psycopg3.errors.SyntaxError: syntax error at or near "$1"
+ psycopg.errors.SyntaxError: syntax error at or near "$1"
Sometimes PostgreSQL offers an alternative (e.g. :sql:`SELECT set_config()`,
-:sql:`SELECT pg_notify()`). If no alternative exist you can use `psycopg3.sql`
+:sql:`SELECT pg_notify()`). If no alternative exist you can use `psycopg.sql`
to compose the query client-side.
You cannot use :sql:`IN %s` and pass a tuple, because `IN ()` is an SQL
PostgreSQL :sql:`COPY`. The interface doesn't make easy to load
dynamically-generated data to the database.
-There is now a single `~psycopg3.Cursor.copy()` method, which is similar to
+There is now a single `~psycopg.Cursor.copy()` method, which is similar to
`!psycopg2` `!copy_expert()` in accepting a free-form :sql:`COPY` command and
returns an object to read/write data, block-wise or record-wise. The different
usage pattern also enables :sql:`COPY` to be used in async interactions.
`cursor.callproc()` is not implemented. The method has a simplistic
semantic which doesn't account for PostgreSQL positional parameters,
procedures, set-returning functions. Use a normal
-`~psycopg3.Cursor.execute()` with :sql:`SELECT function_name(...)` or
+`~psycopg.Cursor.execute()` with :sql:`SELECT function_name(...)` or
:sql:`CALL procedure_name(...)` instead.
-What's new in psycopg3
-----------------------
+What's new in Psycopg 3
+-----------------------
.. admonition:: TODO
Psycopg 3 -- PostgreSQL database adapter for Python
===================================================
-`!psycopg3` is a newly designed PostgreSQL_ database adapter for the Python_
+Psycopg 3 is a newly designed PostgreSQL_ database adapter for the Python_
programming language.
-`!psycopg3` presents a familiar interface for everyone who has used
-`!psycopg2` or any other `DB-API 2.0`__ database adapter, but allows to use
+Psycopg 3 presents a familiar interface for everyone who has used
+Psycopg 2 or any other `DB-API 2.0`__ database adapter, but allows to use
more modern PostgreSQL and Python features, such as:
- Strict Strong Typing
- :ref:`server-side parameters binding <server-side-binding>`
- :ref:`binary communication <binary-data>`
- :ref:`a great integration of the COPY support <copy>`
-- :ref:`direct access to the libpq functionalities <psycopg3.pq>`
+- :ref:`direct access to the libpq functionalities <psycopg.pq>`
.. _Python: https://www.python.org/
.. _PostgreSQL: https://www.postgresql.org/
app.connect("autodoc-process-signature", process_signature)
app.connect("autodoc-before-process-signature", before_process_signature)
- import psycopg3 # type: ignore
+ import psycopg # type: ignore
- recover_defined_module(psycopg3)
+ recover_defined_module(psycopg)
monkeypatch_autodoc()
# Disable warnings in sphinx_autodoc_typehints because it doesn't seem that
Replace a docstring such as::
.. py:attribute:: ConnectionInfo.dbname
- :module: psycopg3
+ :module: psycopg
The database name of the connection.
.. py:attribute:: ConnectionInfo.dbname
:type: str
- :module: psycopg3
+ :module: psycopg
The database name of the connection.
s = re.sub(r":[^`]*:`~?([^`]*)`", r"\1", s) # drop role
s = re.sub(r"\\(.)", r"\1", s) # drop escape
- # note that ~psycopg3.pq.ConnStatus is converted to pq.ConnStatus
+ # note that ~psycopg.pq.ConnStatus is converted to pq.ConnStatus
# which should be interpreted well if currentmodule is set ok.
- s = re.sub(r"(?:typing|psycopg3)\.", "", s) # drop unneeded modules
+ s = re.sub(r"(?:typing|psycopg)\.", "", s) # drop unneeded modules
s = re.sub(r"~", "", s) # drop the tilde
return s
# Used for Vim ALE integration, which doesn't honur the top-level config file
[flake8]
per-file-ignores =
- psycopg3/__init__.py: F401
- psycopg3/types/__init__.py: F401
+ psycopg/__init__.py: F401
+ psycopg/types/__init__.py: F401
--- /dev/null
+Psycopg 3: PostgreSQL database adapter for Python
+=================================================
+
+This distribution contains the pure Python package ``psycopg``.
+
+Installation::
+
+ pip install psycopg
+
+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/psycopg#readme
+
+Copyright (C) 2020-2021 The Psycopg Team
"""
-psycopg3 -- PostgreSQL database adapter for Python
+psycopg -- PostgreSQL database adapter for Python
"""
# Copyright (C) 2020-2021 The Psycopg Team
from .version import __version__
# Set the logger to a quiet default, can be enabled if needed
-logger = logging.getLogger("psycopg3")
+logger = logging.getLogger("psycopg")
if logger.level == logging.NOTSET:
logger.setLevel(logging.WARNING)
class Column(Sequence[Any]):
- __module__ = "psycopg3"
+ __module__ = "psycopg"
def __init__(self, cursor: "AnyCursor[Any]", index: int):
res = cursor.pgresult
"""
-Enum values for psycopg3
+Enum values for psycopg
These values are defined by us and are not necessarily dependent on
libpq-defined enums.
"""
Enum representing the format wanted for a query argument.
- The value `AUTO` allows psycopg3 to choose the best value for a certain
+ The value `AUTO` allows psycopg to choose the best value for a certain
value.
"""
- __module__ = "psycopg3.adapt"
+ __module__ = "psycopg.adapt"
AUTO = "s"
"""Automatically chosen (``%s`` placeholder)."""
state so adapting several values of the same type can be optimised.
"""
- __module__ = "psycopg3.adapt"
+ __module__ = "psycopg.adapt"
_adapters: "AdaptersMap"
_pgresult: Optional["PGresult"] = None
- configure a composite type adaptation using `register()`
"""
- __module__ = "psycopg3.types"
+ __module__ = "psycopg.types"
def __init__(
self,
class RangeInfo(TypeInfo):
"""Manage information about a range type."""
- __module__ = "psycopg3.types"
+ __module__ = "psycopg.types.range"
def __init__(self, name: str, oid: int, array_oid: int, subtype_oid: int):
super().__init__(name, oid, array_oid)
class CompositeInfo(TypeInfo):
"""Manage information about a composite type."""
- __module__ = "psycopg3.types"
+ __module__ = "psycopg.types.composite"
def __init__(
self,
from .compat import ZoneInfo
from .pq.proto import PGconn
-logger = logging.getLogger("psycopg3")
+logger = logging.getLogger("psycopg")
_timezones: Dict[Union[None, bytes], tzinfo] = {
None: timezone.utc,
except KeyError:
pass
- # Check if the class comes from psycopg3.types and there is a class
- # with the same name in psycopg3_c._psycopg3.
- from psycopg3 import types
- from psycopg3_c import _psycopg3
+ # Check if the class comes from psycopg.types and there is a class
+ # with the same name in psycopg_c._psycopg.
+ from psycopg import types
+ from psycopg_c import _psycopg
if cls.__module__.startswith(types.__name__):
- new = cast(Type[RV], getattr(_psycopg3, cls.__name__, None))
+ new = cast(Type[RV], getattr(_psycopg, cls.__name__, None))
if new:
self._optimised[cls] = new
return new
# Override it with fast object if available
if pq.__impl__ == "c":
- from psycopg3_c import _psycopg3
+ from psycopg_c import _psycopg
- Transformer = _psycopg3.Transformer
+ Transformer = _psycopg.Transformer
else:
from . import _transform
"""
-psycopg3 connection objects
+psycopg connection objects
"""
# Copyright (C) 2020-2021 The Psycopg Team
from .transaction import Transaction, AsyncTransaction
from .server_cursor import ServerCursor, AsyncServerCursor
-logger = logging.getLogger("psycopg3")
+logger = logging.getLogger("psycopg")
connect: Callable[[str], PQGenConn["PGconn"]]
execute: Callable[["PGconn"], PQGen[List["PGresult"]]]
from .pool.base import BasePool
if pq.__impl__ == "c":
- from psycopg3_c import _psycopg3
+ from psycopg_c import _psycopg
- connect = _psycopg3.connect
- execute = _psycopg3.execute
+ connect = _psycopg.connect
+ execute = _psycopg.execute
else:
from . import generators
"""The PID of the backend process which sent the notification."""
-Notify.__module__ = "psycopg3"
+Notify.__module__ = "psycopg"
NoticeHandler = Callable[[e.Diagnostic], None]
NotifyHandler = Callable[[Notify], None]
Wrapper for a connection to the database.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
def __init__(self, pgconn: "PGconn", row_factory: RowFactory[Row]):
super().__init__(pgconn, row_factory)
Asynchronous wrapper for a connection to the database.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
def __init__(self, pgconn: "PGconn", row_factory: RowFactory[Row]):
super().__init__(pgconn, row_factory)
class ConnectionInfo:
"""Allow access to information about the connection."""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
def __init__(self, pgconn: pq.proto.PGconn):
self.pgconn = pgconn
"""
-psycopg3 copy support
+psycopg copy support
"""
# Copyright (C) 2020-2021 The Psycopg Team
class Copy(BaseCopy["Connection[Any]"]):
"""Manage a :sql:`COPY` operation."""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
def __init__(self, cursor: "Cursor[Any]"):
super().__init__(cursor)
class AsyncCopy(BaseCopy["AsyncConnection[Any]"]):
"""Manage an asynchronous :sql:`COPY` operation."""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
def __init__(self, cursor: "AsyncCursor[Any]"):
super().__init__(cursor)
# Override functions with fast versions if available
if pq.__impl__ == "c":
- from psycopg3_c import _psycopg3
+ from psycopg_c import _psycopg
- format_row_text = _psycopg3.format_row_text
- format_row_binary = _psycopg3.format_row_binary
- parse_row_text = _psycopg3.parse_row_text
- parse_row_binary = _psycopg3.parse_row_binary
+ format_row_text = _psycopg.format_row_text
+ format_row_binary = _psycopg.format_row_binary
+ parse_row_text = _psycopg.parse_row_text
+ parse_row_binary = _psycopg.parse_row_binary
else:
format_row_text = _format_row_text
"""
-psycopg3 cursor objects
+psycopg cursor objects
"""
# Copyright (C) 2020-2021 The Psycopg Team
execute: Callable[["PGconn"], PQGen[List["PGresult"]]]
if pq.__impl__ == "c":
- from psycopg3_c import _psycopg3
+ from psycopg_c import _psycopg
- execute = _psycopg3.execute
+ execute = _psycopg.execute
else:
execute = generators.execute
class Cursor(BaseCursor["Connection[Any]", Row]):
- __module__ = "psycopg3"
+ __module__ = "psycopg"
__slots__ = ()
def __enter__(self) -> "Cursor[Row]":
class AsyncCursor(BaseCursor["AsyncConnection[Any]", Row]):
- __module__ = "psycopg3"
+ __module__ = "psycopg"
__slots__ = ()
async def __aenter__(self) -> "AsyncCursor[Row]":
self.values = tuple(builtins[n].oid for n in type_names)
def __repr__(self) -> str:
- return f"psycopg3.{self.name}"
+ return f"psycopg.{self.name}"
def __eq__(self, other: Any) -> bool:
if isinstance(other, int):
"""
-psycopg3 exceptions
+psycopg exceptions
DBAPI-defined Exceptions are defined in the following hierarchy::
from typing import Any, Callable, Dict, Optional, Sequence, Tuple, Type, Union
from typing import cast
-from psycopg3.pq.proto import PGresult
-from psycopg3.pq._enums import DiagnosticField
+from psycopg.pq.proto import PGresult
+from psycopg.pq._enums import DiagnosticField
class Warning(Exception):
"""
Exception raised for important warnings.
- Defined for DBAPI compatibility, but never raised by ``psycopg3``.
+ Defined for DBAPI compatibility, but never raised by ``psycopg``.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
ErrorInfo = Union[None, PGresult, Dict[int, Optional[bytes]]]
class Error(Exception):
"""
- Base exception for all the errors psycopg3 will raise.
+ Base exception for all the errors psycopg will raise.
Exception that is the base class of all other error exceptions. You can
use this to catch all errors with one single `!except` statement.
This exception is guaranteed to be picklable.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
def __init__(
self,
An error related to the database interface rather than the database itself.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
class DatabaseError(Error):
Exception raised for errors that are related to the database.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
class DataError(DatabaseError):
Examples may be division by zero, numeric value out of range, etc.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
class OperationalError(DatabaseError):
during processing, etc.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
class IntegrityError(DatabaseError):
An example may be a foreign key check failed.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
class InternalError(DatabaseError):
of sync, etc.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
class ProgrammingError(DatabaseError):
statement, wrong number of parameters specified, etc.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
class NotSupportedError(DatabaseError):
A method or database API was used which is not supported by the database,
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
class Diagnostic:
def error_from_result(result: PGresult, encoding: str = "utf-8") -> Error:
- from psycopg3 import pq
+ from psycopg import pq
state = result.error_field(DiagnosticField.SQLSTATE) or b""
cls = _class_for_state(state.decode("ascii"))
"""
-psycopg3 connection pool package
+psycopg connection pool package
"""
# Copyright (C) 2021 The Psycopg Team
"""
-psycopg3 synchronous connection pool
+psycopg synchronous connection pool
"""
# Copyright (C) 2021 The Psycopg Team
from .sched import AsyncScheduler
from .errors import PoolClosed, PoolTimeout, TooManyRequests
-logger = logging.getLogger("psycopg3.pool")
+logger = logging.getLogger("psycopg.pool")
class AsyncConnectionPool(BasePool[AsyncConnection[Any]]):
"""
-psycopg3 connection pool base class and functionalities.
+psycopg connection pool base class and functionalities.
"""
# Copyright (C) 2021 The Psycopg Team
class PoolClosed(e.OperationalError):
"""Attempt to get a connection from a closed pool."""
- __module__ = "psycopg3.pool"
+ __module__ = "psycopg.pool"
class PoolTimeout(e.OperationalError):
"""The pool couldn't provide a connection in acceptable time."""
- __module__ = "psycopg3.pool"
+ __module__ = "psycopg.pool"
class TooManyRequests(e.OperationalError):
"""Too many requests in the queue waiting for a connection from the pool."""
- __module__ = "psycopg3.pool"
+ __module__ = "psycopg.pool"
"""
-psycopg3 synchronous connection pool
+psycopg synchronous connection pool
"""
# Copyright (C) 2021 The Psycopg Team
from .sched import Scheduler
from .errors import PoolClosed, PoolTimeout, TooManyRequests
-logger = logging.getLogger("psycopg3.pool")
+logger = logging.getLogger("psycopg.pool")
class ConnectionPool(BasePool[Connection[Any]]):
"""
-psycopg3 libpq wrapper
+psycopg libpq wrapper
This package exposes the libpq functionalities as Python objects and functions.
logger = logging.getLogger(__name__)
__impl__: str
-"""The currently loaded implementation of the `!psycopg3.pq` package.
+"""The currently loaded implementation of the `!psycopg.pq` package.
Possible values include ``python``, ``c``, ``binary``.
"""
# import these names into the module on success as side effect
global __impl__, version, PGconn, PGresult, Conninfo, Escaping, PGcancel
- impl = os.environ.get("PSYCOPG3_IMPL", "").lower()
+ impl = os.environ.get("PSYCOPG_IMPL", "").lower()
module = None
attempts: List[str] = []
if not impl or impl == "c":
try:
# TODO: extension module not recognised by mypy?
- from psycopg3_c import pq as module # type: ignore
+ from psycopg_c import pq as module # type: ignore
except Exception as e:
handle_error("c", e)
# Second best implementation: fast and stand-alone
if not module and (not impl or impl == "binary"):
try:
- from psycopg3_binary import pq as module # type: ignore
+ from psycopg_binary import pq as module # type: ignore
except Exception as e:
handle_error("binary", e)
"""
-libpq enum definitions for psycopg3
+libpq enum definitions for psycopg
"""
# Copyright (C) 2020-2021 The Psycopg Team
Current status of the connection.
"""
- __module__ = "psycopg3.pq"
+ __module__ = "psycopg.pq"
OK = 0
"""The connection is in a working state."""
If ``READING`` or ``WRITING`` you may select before polling again.
"""
- __module__ = "psycopg3.pq"
+ __module__ = "psycopg.pq"
FAILED = 0
"""Connection attempt failed."""
The status of a command.
"""
- __module__ = "psycopg3.pq"
+ __module__ = "psycopg.pq"
EMPTY_QUERY = 0
"""The string sent to the server was empty."""
The transaction status of a connection.
"""
- __module__ = "psycopg3.pq"
+ __module__ = "psycopg.pq"
IDLE = 0
"""Connection ready, no transaction active."""
class Ping(IntEnum):
"""Response from a ping attempt."""
- __module__ = "psycopg3.pq"
+ __module__ = "psycopg.pq"
OK = 0
"""
Fields in an error report.
"""
- __module__ = "psycopg3.pq"
+ __module__ = "psycopg.pq"
# from postgres_ext.h
SEVERITY = ord("S")
"""
Enum representing the format of a query argument or return value.
- These values are only the ones managed by the libpq. `~psycopg3` may also
- support automatically-chosen values: see `psycopg3.adapt.Format`.
+ These values are only the ones managed by the libpq. `~psycopg` may also
+ support automatically-chosen values: see `psycopg.adapt.Format`.
"""
- __module__ = "psycopg3.pq"
+ __module__ = "psycopg.pq"
TEXT = 0
"""Text parameter."""
from ctypes import c_char, c_char_p, c_int, c_size_t, c_ubyte, c_uint, c_void_p
from typing import List, Tuple
-from psycopg3.errors import NotSupportedError
+from psycopg.errors import NotSupportedError
if sys.platform == "win32":
libname = ctypes.util.find_library("libpq.dll")
) -> Callable[[Any], PGresult_struct]: ...
# TODO: Ignoring type as getting an error on mypy/ctypes:
-# Type argument "psycopg3.pq._pq_ctypes.PGnotify_struct" of "pointer" must be
+# Type argument "psycopg.pq._pq_ctypes.PGnotify_struct" of "pointer" must be
# a subtype of "ctypes._CData"
def PQnotifies(
arg1: Optional[PGconn_struct],
bmsg = bmsg.split(b":", 1)[-1].strip()
elif hasattr(obj, "error_message"):
- from psycopg3.encodings import py_codecs
+ from psycopg.encodings import py_codecs
# obj is a PGconn
obj = cast(PGconn, obj)
__impl__ = "python"
-logger = logging.getLogger("psycopg3")
+logger = logging.getLogger("psycopg")
def version() -> int:
Python representation of a libpq connection.
"""
- __module__ = "psycopg3.pq"
+ __module__ = "psycopg.pq"
__slots__ = (
"_pgconn_ptr",
"notice_handler",
`!None` if the connection is closed.
The value can be used to pass the structure to libpq functions which
- psycopg3 doesn't (currently) wrap, either in C or in Python using FFI
+ psycopg doesn't (currently) wrap, either in C or in Python using FFI
libraries such as `ctypes`.
"""
if self._pgconn_ptr is None:
Python representation of a libpq result.
"""
- __module__ = "psycopg3.pq"
+ __module__ = "psycopg.pq"
__slots__ = ("_pgresult_ptr",)
def __init__(self, pgresult_ptr: impl.PGresult_struct):
`!None` if the result waas cleared.
The value can be used to pass the structure to libpq functions which
- psycopg3 doesn't (currently) wrap, either in C or in Python using FFI
+ psycopg doesn't (currently) wrap, either in C or in Python using FFI
libraries such as `ctypes`.
"""
if self._pgresult_ptr is None:
Created by `PGconn.get_cancel()`.
"""
- __module__ = "psycopg3.pq"
+ __module__ = "psycopg.pq"
__slots__ = ("pgcancel_ptr",)
def __init__(self, pgcancel_ptr: impl.PGcancel_struct):
Utility object to manipulate connection strings.
"""
- __module__ = "psycopg3.pq"
+ __module__ = "psycopg.pq"
@classmethod
def get_defaults(cls) -> List[ConninfoOption]:
Utility object to escape strings for SQL interpolation.
"""
- __module__ = "psycopg3.pq"
+ __module__ = "psycopg.pq"
def __init__(self, conn: Optional[PGconn] = None):
self.conn = conn
"""
-psycopg3 row factories
+psycopg row factories
"""
# Copyright (C) 2021 The Psycopg Team
class RowFactory(Protocol[Row]):
"""
- Callable protocol taking a `~psycopg3.Cursor` and returning a `RowMaker`.
+ Callable protocol taking a `~psycopg.Cursor` and returning a `RowMaker`.
A `!RowFactory` is typically called when a `!Cursor` receives a result.
This way it can inspect the cursor state (for instance the
- `~psycopg3.Cursor.description` attribute) and help a `!RowMaker` to create
+ `~psycopg.Cursor.description` attribute) and help a `!RowMaker` to create
a complete object.
For instance the `dict_row()` `!RowFactory` uses the names of the column to
"""
-psycopg3 server-side cursor objects.
+psycopg server-side cursor objects.
"""
# Copyright (C) 2020-2021 The Psycopg Team
class ServerCursor(BaseCursor["Connection[Any]", Row]):
- __module__ = "psycopg3"
+ __module__ = "psycopg"
__slots__ = ("_helper", "itersize")
def __init__(
class AsyncServerCursor(BaseCursor["AsyncConnection[Any]", Row]):
- __module__ = "psycopg3"
+ __module__ = "psycopg"
__slots__ = ("_helper", "itersize")
def __init__(
Abstract base class for objects that can be used to compose an SQL string.
`!Composable` objects can be passed directly to
- `~psycopg3.Cursor.execute()`, `~psycopg3.Cursor.executemany()`,
- `~psycopg3.Cursor.copy()` in place of the query string.
+ `~psycopg.Cursor.execute()`, `~psycopg.Cursor.executemany()`,
+ `~psycopg.Cursor.copy()` in place of the query string.
`!Composable` objects can be joined using the ``+`` operator: the result
will be a `Composed` instance containing the objects joined. The operator
:param context: the context to evaluate the object into.
:type context: `connection` or `cursor`
- The method is automatically invoked by `~psycopg3.Cursor.execute()`,
- `~psycopg3.Cursor.executemany()`, `~psycopg3.Cursor.copy()` if a
+ The method is automatically invoked by `~psycopg.Cursor.execute()`,
+ `~psycopg.Cursor.executemany()`, `~psycopg.Cursor.copy()` if a
`!Composable` is passed instead of the query string.
"""
enclosing transactions contexts up to and including the one specified.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
def __init__(
self,
Returned by `Connection.transaction()` to handle a transaction block.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
@property
def connection(self) -> "Connection[Any]":
Returned by `AsyncConnection.transaction()` to handle a transaction block.
"""
- __module__ = "psycopg3"
+ __module__ = "psycopg"
@property
def connection(self) -> "AsyncConnection[Any]":
"""
-psycopg3 types package
+psycopg types package
"""
# Copyright (C) 2020-2021 The Psycopg Team
"""
-psycopg3 distribution version file.
+psycopg distribution version file.
"""
# Copyright (C) 2020-2021 The Psycopg Team
[metadata]
-name = psycopg3
+name = psycopg
description = PostgreSQL database adapter for Python
url = https://psycopg.org/psycopg3/
author = Daniele Varrazzo
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/
+ Code = https://github.com/psycopg/psycopg
+ Issue Tracker = https://github.com/psycopg/psycopg/issues
+ Download = https://pypi.org/project/psycopg/
classifiers =
Intended Audience :: Developers
typing_extensions; python_version < "3.8"
[options.package_data]
-psycopg3 = py.typed
+psycopg = py.typed
if os.path.abspath(os.getcwd()) != here:
os.chdir(here)
-with open("psycopg3/version.py") as f:
+with open("psycopg/version.py") as f:
data = f.read()
m = re.search(r"""(?m)^__version__\s*=\s*['"]([^'"]+)['"]""", data)
if not m:
extras_require = {
# Install the C extension module (requires dev tools)
"c": [
- f"psycopg3-c == {version}",
+ f"psycopg-c == {version}",
],
# Install the stand-alone C extension module
"binary": [
- f"psycopg3-binary == {version}",
+ f"psycopg-binary == {version}",
],
"test": [
"mypy >= 0.812",
changedir = ..
commands =
pytest {posargs}
-passenv = PG* PSYCOPG3_TEST_DSN PYTEST_ADDOPTS PSYCOPG3_IMPL TRAVIS*
+passenv = PG* PSYCOPG_TEST_DSN PYTEST_ADDOPTS PSYCOPG_IMPL
extras = test
[flake8]
+++ /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-2021 The Psycopg Team
+++ /dev/null
-"""
-psycopg3 -- PostgreSQL database adapter for Python -- C optimization package
-"""
-
-# Copyright (C) 2020-2021 The Psycopg Team
-
-import sys
-
-# This package shouldn't be imported before psycopg3 itself, or weird things
-# will happen
-if "psycopg3" not in sys.modules:
- raise ImportError(
- "the psycopg3 package should be imported before psycopg3_c"
- )
-
-from .version import __version__ # noqa
-PostgreSQL database adapter for Python - optimisation package
-=============================================================
+Psycopg 3: PostgreSQL database adapter for Python - optimisation package
+========================================================================
-This distribution contains the optional optimization package ``psycopg3_c``.
+This distribution contains the optional optimization package ``psycopg_c``.
You shouldn't install this package directly: use instead ::
- pip install psycopg3[c]
+ pip install psycopg[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.
+``psycopg`` package only.
Please read `the project readme`__ for more details.
-.. __: https://github.com/psycopg/psycopg3#readme
+.. __: https://github.com/psycopg/psycopg#readme
Requirements
--------------
This library is available pre-compiled and bundled with all the required
-client library as ``psycopg3_binary``. In order to use it please install::
+client library as ``psycopg_binary``. In order to use it please install::
- pip install psycopg3[binary]
+ pip install psycopg[binary]
Copyright (C) 2020-2021 The Psycopg Team
/*.so
-_psycopg3.c
+_psycopg.c
pq.c
*.html
--- /dev/null
+"""
+psycopg -- PostgreSQL database adapter for Python -- C optimization package
+"""
+
+# Copyright (C) 2020-2021 The Psycopg Team
+
+import sys
+
+# This package shouldn't be imported before psycopg itself, or weird things
+# will happen
+if "psycopg" not in sys.modules:
+ raise ImportError(
+ "the psycopg package should be imported before psycopg_c"
+ )
+
+from .version import __version__ # noqa
"""
-Stub representaton of the public objects exposed by the _psycopg3 module.
+Stub representaton of the public objects exposed by the _psycopg module.
TODO: this should be generated by mypy's stubgen but it crashes with no
information. Will submit a bug.
from typing import Any, Iterable, List, Optional, Sequence, Tuple
-from psycopg3 import pq
-from psycopg3 import proto
-from psycopg3.rows import Row, RowMaker
-from psycopg3.adapt import Dumper, Loader, AdaptersMap, Format
-from psycopg3.pq.proto import PGconn, PGresult
-from psycopg3.connection import BaseConnection
+from psycopg import pq
+from psycopg import proto
+from psycopg.rows import Row, RowMaker
+from psycopg.adapt import Dumper, Loader, AdaptersMap, Format
+from psycopg.pq.proto import PGconn, PGresult
+from psycopg.connection import BaseConnection
class Transformer(proto.AdaptContext):
def __init__(self, context: Optional[proto.AdaptContext] = None): ...
"""
-psycopg3_c._psycopg3 optimization module.
+psycopg_c._psycopg optimization module.
The module contains optimized C code used in preference to Python code
if a compiler is available.
# Copyright (C) 2020-2021 The Psycopg Team
-from psycopg3_c cimport pq
-from psycopg3_c.pq cimport libpq
-from psycopg3_c._psycopg3 cimport oids
+from psycopg_c cimport pq
+from psycopg_c.pq cimport libpq
+from psycopg_c._psycopg cimport oids
-from psycopg3.pq import Format as _pq_Format
-from psycopg3._enums import Format as _pg_Format
+from psycopg.pq import Format as _pq_Format
+from psycopg._enums import Format as _pg_Format
PQ_TEXT = _pq_Format.TEXT
PQ_BINARY = _pq_Format.BINARY
PG_BINARY = _pg_Format.BINARY
-include "_psycopg3/adapt.pyx"
-include "_psycopg3/copy.pyx"
-include "_psycopg3/generators.pyx"
-include "_psycopg3/transform.pyx"
+include "_psycopg/adapt.pyx"
+include "_psycopg/copy.pyx"
+include "_psycopg/generators.pyx"
+include "_psycopg/transform.pyx"
include "types/datetime.pyx"
include "types/numeric.pyx"
"""
-psycopg3_c.pq cython module.
+psycopg_c._psycopg cython module.
This file is necessary to allow c-importing pxd files from this directory.
"""
# Copyright (C) 2020-2021 The Psycopg Team
-from psycopg3_c._psycopg3 cimport oids
+from psycopg_c._psycopg cimport oids
from cpython.bytearray cimport PyByteArray_FromStringAndSize, PyByteArray_Resize
from cpython.bytearray cimport PyByteArray_GET_SIZE, PyByteArray_AS_STRING
-from psycopg3_c.pq cimport _buffer_as_string_and_size
+from psycopg_c.pq cimport _buffer_as_string_and_size
-from psycopg3 import errors as e
-from psycopg3.pq.misc import error_message
+from psycopg import errors as e
+from psycopg.pq.misc import error_message
import logging
-logger = logging.getLogger("psycopg3.adapt")
+logger = logging.getLogger("psycopg.adapt")
@cython.freelist(8)
if context is not None:
adapters = context.adapters
else:
- from psycopg3.adapt import global_adapters as adapters
+ from psycopg.adapt import global_adapters as adapters
adapters.register_dumper(cls, this_cls)
if context is not None:
adapters = context.adapters
else:
- from psycopg3.adapt import global_adapters as adapters
+ from psycopg.adapt import global_adapters as adapters
adapters.register_loader(oid, cls)
from cpython.bytearray cimport PyByteArray_AS_STRING, PyByteArray_GET_SIZE
from cpython.memoryview cimport PyMemoryView_FromObject
-from psycopg3_c._psycopg3 cimport endian
-from psycopg3_c.pq cimport ViewBuffer
+from psycopg_c._psycopg cimport endian
+from psycopg_c.pq cimport ViewBuffer
-from psycopg3 import errors as e
+from psycopg import errors as e
cdef int32_t _binary_null = -1
import logging
from typing import List
-from psycopg3 import errors as e
-from psycopg3.pq import proto, error_message
-from psycopg3.proto import PQGen
-from psycopg3.waiting import Wait, Ready
+from psycopg import errors as e
+from psycopg.pq import proto, error_message
+from psycopg.proto import PQGen
+from psycopg.waiting import Wait, Ready
cdef object WAIT_W = Wait.W
cdef object WAIT_R = Wait.R
from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple
-from psycopg3 import errors as e
-from psycopg3._enums import Format as Pg3Format
-from psycopg3.pq import Format as PqFormat
-from psycopg3.rows import Row, RowMaker
+from psycopg import errors as e
+from psycopg._enums import Format as Pg3Format
+from psycopg.pq import Format as PqFormat
+from psycopg.rows import Row, RowMaker
# internal structure: you are not supposed to know this. But it's worth some
# 10% of the innermost loop, so I'm willing to ask for forgiveness later...
self.adapters = context.adapters
self.connection = context.connection
else:
- from psycopg3.adapt import global_adapters
+ from psycopg.adapt import global_adapters
self.adapters = global_adapters
self.connection = None
cache = <PyObject *>self._text_dumpers
else:
raise ValueError(
- f"format should be a psycopg3.adapt.Format, not {<object>fmt}")
+ f"format should be a psycopg.adapt.Format, not {<object>fmt}")
# Reuse an existing Dumper class for objects of the same type
ptr = PyDict_GetItem(<object>cache, key)
cache = <PyObject *>self._binary_loaders
else:
raise ValueError(
- f"format should be a psycopg3.pq.Format, not {format}")
+ f"format should be a psycopg.pq.Format, not {format}")
ptr = PyDict_GetItem(<object>cache, <object>oid)
if ptr != NULL:
from posix.fcntl cimport pid_t
-from psycopg3_c.pq cimport libpq
+from psycopg_c.pq cimport libpq
ctypedef char *(*conn_bytes_f) (const libpq.PGconn *)
ctypedef int(*conn_int_f) (const libpq.PGconn *)
# Copyright (C) 2020-2021 The Psycopg Team
-from psycopg3_c.pq cimport libpq
+from psycopg_c.pq cimport libpq
-from psycopg3 import errors as e
-from psycopg3.pq import Format
-from psycopg3.pq.misc import error_message
+from psycopg import errors as e
+from psycopg.pq import Format
+from psycopg.pq.misc import error_message
__impl__ = 'c'
"""
-psycopg3_c.pq cython module.
+psycopg_c.pq cython module.
This file is necessary to allow c-importing pxd files from this directory.
"""
# Copyright (C) 2020-2021 The Psycopg Team
-from psycopg3_c.pq cimport libpq
+from psycopg_c.pq cimport libpq
"""
-psycopg3_c.pq.Conninfo object implementation.
+psycopg_c.pq.Conninfo object implementation.
"""
# Copyright (C) 2020-2021 The Psycopg Team
-from psycopg3.pq.misc import ConninfoOption
+from psycopg.pq.misc import ConninfoOption
class Conninfo:
"""
-psycopg3_c.pq.Escaping object implementation.
+psycopg_c.pq.Escaping object implementation.
"""
# Copyright (C) 2020-2021 The Psycopg Team
"""
-Libpq header definition for the cython psycopg3.pq implementation.
+Libpq header definition for the cython psycopg.pq implementation.
"""
# Copyright (C) 2020-2021 The Psycopg Team
"""
-psycopg3_c.pq.PGcancel object implementation.
+psycopg_c.pq.PGcancel object implementation.
"""
# Copyright (C) 2020-2021 The Psycopg Team
"""
-psycopg3_c.pq.PGconn object implementation.
+psycopg_c.pq.PGconn object implementation.
"""
# Copyright (C) 2020-2021 The Psycopg Team
import ctypes
import logging
-from psycopg3.pq import Format as PqFormat
-from psycopg3.pq.misc import PGnotify, connection_summary
-from psycopg3_c.pq cimport PQBuffer
+from psycopg.pq import Format as PqFormat
+from psycopg.pq.misc import PGnotify, connection_summary
+from psycopg_c.pq cimport PQBuffer
-logger = logging.getLogger('psycopg3')
+logger = logging.getLogger('psycopg')
cdef class PGconn:
@property
def hostaddr(self) -> bytes:
# Available only from PG 12. Use the dynamic ctypes implementation
- from psycopg3.pq import _pq_ctypes
+ from psycopg.pq import _pq_ctypes
_ensure_pgconn(self)
return _pq_ctypes.PQhostaddr(
"""
-psycopg3_c.pq.PGresult object implementation.
+psycopg_c.pq.PGresult object implementation.
"""
# Copyright (C) 2020-2021 The Psycopg Team
cimport cython
from cpython.mem cimport PyMem_Malloc, PyMem_Free
-from psycopg3.pq.misc import PGresAttDesc
-from psycopg3.pq._enums import ExecStatus
+from psycopg.pq.misc import PGresAttDesc
+from psycopg.pq._enums import ExecStatus
@cython.freelist(8)
from datetime import date, time, timedelta, datetime, timezone
-from psycopg3_c._psycopg3 cimport endian
+from psycopg_c._psycopg cimport endian
-from psycopg3 import errors as e
-from psycopg3.compat import ZoneInfo
+from psycopg import errors as e
+from psycopg.compat import ZoneInfo
# Initialise the datetime C API
try:
zi = ZoneInfo(sname)
except KeyError:
- logger = logging.getLogger("psycopg3")
+ logger = logging.getLogger("psycopg")
logger.warning(
"unknown PostgreSQL timezone: %r; will use UTC", sname
)
from decimal import Decimal, Context, DefaultContext
-from psycopg3_c._psycopg3 cimport endian
-from psycopg3 import errors as e
+from psycopg_c._psycopg cimport endian
+from psycopg import errors as e
-from psycopg3.types.numeric import Int2, Int4, Int8, IntNumeric
+from psycopg.types.numeric import Int2, Int4, Int8, IntNumeric
cdef extern from "Python.h":
# work around https://github.com/cython/cython/issues/3909
PyUnicode_DecodeUTF8,
)
-from psycopg3_c.pq cimport libpq, Escaping, _buffer_as_string_and_size
+from psycopg_c.pq cimport libpq, Escaping, _buffer_as_string_and_size
-from psycopg3 import errors as e
-from psycopg3.encodings import pg2py
+from psycopg import errors as e
+from psycopg.encodings import pg2py
cdef extern from "Python.h":
const char *PyUnicode_AsUTF8AndSize(unicode obj, Py_ssize_t *size) except NULL
"""
-psycopg3-c distribution version file.
+psycopg-c distribution version file.
"""
# Copyright (C) 2020-2021 The Psycopg Team
[metadata]
-name = psycopg3-c
+name = psycopg-c
description = PostgreSQL database adapter for Python -- C optimisation distribution
url = https://psycopg.org/psycopg3/
author = Daniele Varrazzo
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/
+ Code = https://github.com/psycopg/psycopg
+ Issue Tracker = https://github.com/psycopg/psycopg/issues
+ Download = https://pypi.org/project/psycopg-c/
# TODO: classifiers
classifiers =
# NOTE: do not include .pyx files: they shouldn't be in the sdist
# package, so that build is only performed from the .c files (which are
# distributed instead).
-psycopg3_c =
+psycopg_c =
py.typed
*.pyi
*.pxd
- _psycopg3/*.pxd
+ _psycopg/*.pxd
pq/*.pxd
if os.path.abspath(os.getcwd()) != here:
os.chdir(here)
-with open("psycopg3_c/version.py") as f:
+with open("psycopg_c/version.py") as f:
data = f.read()
m = re.search(r"""(?m)^__version__\s*=\s*['"]([^'"]+)['"]""", data)
if m is None:
version = m.group(1)
-class psycopg3_build_ext(build_ext):
+class psycopg_build_ext(build_ext):
def finalize_options(self) -> None:
self._setup_ext_build()
super().finalize_options()
# 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"):
+ if os.path.exists("psycopg_c/_psycopg.pyx"):
from Cython.Build import cythonize
# Add the include dir for the libpq.
self.distribution.ext_modules = [pgext, pqext]
-# Some details missing, to be finished by psycopg3_build_ext.finalize_options
+# Some details missing, to be finished by psycopg_build_ext.finalize_options
pgext = Extension(
- "psycopg3_c._psycopg3",
+ "psycopg_c._psycopg",
[
- "psycopg3_c/_psycopg3.c",
- "psycopg3_c/types/numutils.c",
+ "psycopg_c/_psycopg.c",
+ "psycopg_c/types/numutils.c",
],
libraries=["pq"],
include_dirs=[],
)
pqext = Extension(
- "psycopg3_c.pq",
- ["psycopg3_c/pq.c"],
+ "psycopg_c.pq",
+ ["psycopg_c/pq.c"],
libraries=["pq"],
include_dirs=[],
)
setup(
version=version,
ext_modules=[pgext, pqext],
- cmdclass={"build_ext": psycopg3_build_ext},
+ cmdclass={"build_ext": psycopg_build_ext},
)
changedir = ..
commands =
pytest {posargs}
-passenv = PG* PSYCOPG3_TEST_DSN PYTEST_ADDOPTS PSYCOPG3_IMPL TRAVIS*
+passenv = PG* PSYCOPG_TEST_DSN PYTEST_ADDOPTS PSYCOPG_IMPL
deps =
- -e {toxinidir}/../psycopg3[test]
+ -e {toxinidir}/../psycopg[test]
-psycopg3 test suite
+psycopg test suite
===================
Quick version
-------------
To run tests on the current code you can install the `test` extra of the
-package, specify a connection string in the `PSYCOPG3_TEST_DSN` env var to
+package, specify a connection string in the `PSYCOPG_TEST_DSN` env var to
connect to a test database, and run ``pytest``::
- $ pip install -e psycopg3[test]
- $ export PSYCOPG3_TEST_DSN="host=localhost dbname=psycopg3_test"
+ $ pip install -e psycopg[test]
+ $ export PSYCOPG_TEST_DSN="host=localhost dbname=psycopg_test"
$ pytest
Test options
------------
-- The tests output header shows additional psycopg3 related information,
+- The tests output header shows additional psycopg related information,
on top of the one normally displayed by ``pytest`` and the extensions used::
$ pytest
libpq wrapper implementation: c
-- By default the tests run using the ``pq`` implementation that psycopg3 would
+- By default the tests run using the ``pq`` implementation that psycopg would
choose (the C module if installed, else the Python one). In order to test a
different implementation, use the normal `pq module selection mechanism`__
- of the ``PSYCOPG3_IMPL`` env var::
+ of the ``PSYCOPG_IMPL`` env var::
- $ PSYCOPG3_IMPL=python pytest
+ $ PSYCOPG_IMPL=python pytest
========================= test session starts =========================
[...]
libpq available: 130002
libpq wrapper implementation: python
- .. __: https://www.psycopg.org/psycopg3/docs/api/pq.html#pq-module-implementations
+ .. __: https://www.psycopg.org/psycopg/docs/api/pq.html#pq-module-implementations
- Slow tests have a ``slow`` marker which can be selected to reduce test
a set of env vars working for your setup::
$ docker run -ti --rm --volume `pwd`:/src --workdir /src \
- -e PSYCOPG3_TEST_DSN -e PGHOST=172.17.0.1 -e PGUSER=`whoami` \
+ -e PSYCOPG_TEST_DSN -e PGHOST=172.17.0.1 -e PGUSER=`whoami` \
python:3.7 bash
- # pip install -e ./psycopg3[test] ./psycopg3_c
+ # pip install -e ./psycopg[test] ./psycopg_c
# pytest
# There are troubles on travis with these kind of tests and I cannot
# catch the exception for my life.
config.addinivalue_line(
- "markers", "subprocess: the test import psycopg3 after subprocess"
+ "markers", "subprocess: the test import psycopg after subprocess"
)
parser.addoption(
"--test-dsn",
metavar="DSN",
- default=os.environ.get("PSYCOPG3_TEST_DSN") or None,
+ default=os.environ.get("PSYCOPG_TEST_DSN") or None,
help="Connection string to run database tests requiring a connection"
- " [you can also use the PSYCOPG3_TEST_DSN env var].",
+ " [you can also use the PSYCOPG_TEST_DSN env var].",
)
@pytest.fixture
def pgconn(dsn, request):
"""Return a PGconn connection open to `--test-dsn`."""
- from psycopg3 import pq
+ from psycopg import pq
conn = pq.PGconn.connect(dsn.encode("utf8"))
if conn.status != pq.ConnStatus.OK:
@pytest.fixture
def conn(dsn, request):
"""Return a `Connection` connected to the ``--test-dsn`` database."""
- from psycopg3 import Connection
+ from psycopg import Connection
conn = Connection.connect(dsn)
msg = check_connection_version(conn.info.server_version, request.function)
@pytest.fixture
async def aconn(dsn, request):
"""Return an `AsyncConnection` connected to the ``--test-dsn`` database."""
- from psycopg3 import AsyncConnection
+ from psycopg import AsyncConnection
conn = await AsyncConnection.connect(dsn)
msg = check_connection_version(conn.info.server_version, request.function)
"""
Return a session `Connection` connected to the ``--test-dsn`` database.
"""
- from psycopg3 import Connection
+ from psycopg import Connection
conn = Connection.connect(dsn, autocommit=True)
yield conn
def patch_exec(conn, monkeypatch):
"""Helper to implement the commands fixture both sync and async."""
- from psycopg3 import sql
+ from psycopg import sql
_orig_exec_command = conn._exec_command
L = ListPopAll()
import pytest
-import psycopg3
-from psycopg3 import sql
-from psycopg3.adapt import Format
-from psycopg3.types.range import Range
-from psycopg3.types.numeric import Int4, Int8
+import psycopg
+from psycopg import sql
+from psycopg.adapt import Format
+from psycopg.types.range import Range
+from psycopg.types.numeric import Int4, Int8
@pytest.fixture
return self._types_names
record = self.make_record(nulls=0)
- tx = psycopg3.adapt.Transformer(self.conn)
+ tx = psycopg.adapt.Transformer(self.conn)
types = [
self._get_type_name(tx, schema, value)
for schema, value in zip(self.schema, record)
def pytest_report_header(config):
try:
- from psycopg3 import pq
+ from psycopg import pq
except ImportError:
return []
def pytest_runtest_setup(item):
- from psycopg3 import pq
+ from psycopg import pq
for m in item.iter_markers(name="libpq"):
assert len(m.args) == 1
assert libname, "libpq libname not found"
return ctypes.pydll.LoadLibrary(libname)
except Exception as e:
- from psycopg3 import pq
+ from psycopg import pq
if pq.__impl__ == "binary":
pytest.skip(f"can't load libpq for testing: {e}")
import pytest
-import psycopg3
-from psycopg3 import conninfo
+import psycopg
+from psycopg import conninfo
logger = logging.getLogger()
# verify that the proxy works
# TODO: investigate why it doesn't on Travis
try:
- with psycopg3.connect(self.client_dsn):
+ with psycopg.connect(self.client_dsn):
pass
except Exception as e:
pytest.xfail(f"failed to create a working proxy: {e}")
import pytest
-import psycopg3
-from psycopg3 import pool
-from psycopg3.pq import TransactionStatus
+import psycopg
+from psycopg import pool
+from psycopg.pq import TransactionStatus
def test_defaults(dsn):
def test_connection_class(dsn):
- class MyConn(psycopg3.Connection):
+ class MyConn(psycopg.Connection):
pass
with pool.ConnectionPool(dsn, connection_class=MyConn, min_size=1) as p:
@pytest.mark.slow
def test_configure_badstate(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
def configure(conn):
conn.execute("select 1")
@pytest.mark.slow
def test_configure_broken(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
def configure(conn):
with conn.transaction():
def test_reset_badstate(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
def reset(conn):
conn.execute("reset all")
def test_reset_broken(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
def reset(conn):
with conn.transaction():
def test_intrans_rollback(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
with pool.ConnectionPool(dsn, min_size=1) as p:
conn = p.getconn()
def test_inerror_rollback(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
with pool.ConnectionPool(dsn, min_size=1) as p:
conn = p.getconn()
pid = conn.pgconn.backend_pid
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
conn.execute("wat")
assert conn.pgconn.transaction_status == TransactionStatus.INERROR
p.putconn(conn)
def test_active_close(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
with pool.ConnectionPool(dsn, min_size=1) as p:
conn = p.getconn()
def test_fail_rollback_close(dsn, caplog, monkeypatch):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
with pool.ConnectionPool(dsn, min_size=1) as p:
conn = p.getconn()
monkeypatch.setattr(conn, "rollback", bad_rollback)
pid = conn.pgconn.backend_pid
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
conn.execute("wat")
assert conn.pgconn.transaction_status == TransactionStatus.INERROR
p.putconn(conn)
def test_putconn_no_pool(dsn):
with pool.ConnectionPool(dsn, min_size=1) as p:
- conn = psycopg3.connect(dsn)
+ conn = psycopg.connect(dsn)
with pytest.raises(ValueError):
p.putconn(conn)
@pytest.mark.slow
def test_shrink(dsn, monkeypatch):
- from psycopg3.pool.pool import ShrinkPool
+ from psycopg.pool.pool import ShrinkPool
results = []
@pytest.mark.slow
def test_reconnect(proxy, caplog, monkeypatch):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
assert pool.base.ConnectionAttempt.INITIAL_DELAY == 1.0
assert pool.base.ConnectionAttempt.DELAY_JITTER == 0.1
p.wait(2.0)
proxy.stop()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
with p.connection() as conn:
conn.execute("select 1")
p.wait(2.0)
proxy.stop()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
with p.connection() as conn:
conn.execute("select 1")
def test_check(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
with pool.ConnectionPool(dsn, min_size=4) as p:
p.wait(1.0)
with p.connection() as conn:
def test_async_pool_not_supported(dsn):
# note: this test is here because the all the ones in test_pool_async are
# skipped on Py 3.6
- with pytest.raises(psycopg3.NotSupportedError):
+ with pytest.raises(psycopg.NotSupportedError):
pool.AsyncConnectionPool(dsn)
sleep(sec - (t1 - t0))
return rv
- connect_orig = psycopg3.Connection.connect
- monkeypatch.setattr(psycopg3.Connection, "connect", connect_delay)
+ connect_orig = psycopg.Connection.connect
+ monkeypatch.setattr(psycopg.Connection, "connect", connect_delay)
import pytest
-import psycopg3
-from psycopg3 import pool
-from psycopg3.pq import TransactionStatus
-from psycopg3.compat import create_task
+import psycopg
+from psycopg import pool
+from psycopg.pq import TransactionStatus
+from psycopg.compat import create_task
pytestmark = [
pytest.mark.asyncio,
async def test_connection_class(dsn):
- class MyConn(psycopg3.AsyncConnection):
+ class MyConn(psycopg.AsyncConnection):
pass
async with pool.AsyncConnectionPool(
@pytest.mark.slow
async def test_configure_badstate(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
async def configure(conn):
await conn.execute("select 1")
@pytest.mark.slow
async def test_configure_broken(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
async def configure(conn):
async with conn.transaction():
async def test_reset_badstate(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
async def reset(conn):
await conn.execute("reset all")
async def test_reset_broken(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
async def reset(conn):
async with conn.transaction():
recs = [
r
for r in caplog.records
- if r.name.startswith("psycopg3") and r.levelno >= logging.WARNING
+ if r.name.startswith("psycopg") and r.levelno >= logging.WARNING
]
assert len(recs) == 1
assert "INTRANS" in recs[0].message
async with pool.AsyncConnectionPool(dsn, min_size=1) as p:
conn = await p.getconn()
pid = conn.pgconn.backend_pid
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
await conn.execute("wat")
assert conn.pgconn.transaction_status == TransactionStatus.INERROR
await p.putconn(conn)
recs = [
r
for r in caplog.records
- if r.name.startswith("psycopg3") and r.levelno >= logging.WARNING
+ if r.name.startswith("psycopg") and r.levelno >= logging.WARNING
]
assert len(recs) == 1
assert "INERROR" in recs[0].message
recs = [
r
for r in caplog.records
- if r.name.startswith("psycopg3") and r.levelno >= logging.WARNING
+ if r.name.startswith("psycopg") and r.levelno >= logging.WARNING
]
assert len(recs) == 2
assert "ACTIVE" in recs[0].message
monkeypatch.setattr(conn, "rollback", bad_rollback)
pid = conn.pgconn.backend_pid
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
await conn.execute("wat")
assert conn.pgconn.transaction_status == TransactionStatus.INERROR
await p.putconn(conn)
recs = [
r
for r in caplog.records
- if r.name.startswith("psycopg3") and r.levelno >= logging.WARNING
+ if r.name.startswith("psycopg") and r.levelno >= logging.WARNING
]
assert len(recs) == 3
assert "INERROR" in recs[0].message
async def test_putconn_no_pool(dsn):
async with pool.AsyncConnectionPool(dsn, min_size=1) as p:
- conn = psycopg3.connect(dsn)
+ conn = psycopg.connect(dsn)
with pytest.raises(ValueError):
await p.putconn(conn)
@pytest.mark.slow
async def test_shrink(dsn, monkeypatch):
- from psycopg3.pool.async_pool import ShrinkPool
+ from psycopg.pool.async_pool import ShrinkPool
results = []
await p.wait(2.0)
proxy.stop()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
async with p.connection() as conn:
await conn.execute("select 1")
recs = [
r
for r in caplog.records
- if r.name.startswith("psycopg3") and r.levelno >= logging.WARNING
+ if r.name.startswith("psycopg") and r.levelno >= logging.WARNING
]
assert "BAD" in recs[0].message
times = [rec.created for rec in recs]
await p.wait(2.0)
proxy.stop()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
async with p.connection() as conn:
await conn.execute("select 1")
async def test_check(dsn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3.pool")
+ caplog.set_level(logging.WARNING, logger="psycopg.pool")
async with pool.AsyncConnectionPool(dsn, min_size=4) as p:
await p.wait(1.0)
async with p.connection() as conn:
await asyncio.sleep(sec - (t1 - t0))
return rv
- connect_orig = psycopg3.AsyncConnection.connect
- monkeypatch.setattr(psycopg3.AsyncConnection, "connect", connect_delay)
+ connect_orig = psycopg.AsyncConnection.connect
+ monkeypatch.setattr(psycopg.AsyncConnection, "connect", connect_delay)
import pytest
-from psycopg3.pool.sched import Scheduler
+from psycopg.pool.sched import Scheduler
@pytest.mark.slow
@pytest.mark.slow
def test_sched_error(caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3")
+ caplog.set_level(logging.WARNING, logger="psycopg")
s = Scheduler()
t = Thread(target=s.run, daemon=True)
t.start()
import pytest
-from psycopg3.compat import create_task
-from psycopg3.pool.sched import AsyncScheduler
+from psycopg.compat import create_task
+from psycopg.pool.sched import AsyncScheduler
pytestmark = pytest.mark.asyncio
@pytest.mark.slow
async def test_sched_error(caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3")
+ caplog.set_level(logging.WARNING, logger="psycopg")
s = AsyncScheduler()
t = create_task(s.run())
import pytest
from select import select
-import psycopg3
-from psycopg3 import pq
-from psycopg3.generators import execute
+import psycopg
+from psycopg import pq
+from psycopg.generators import execute
def execute_wait(pgconn):
- return psycopg3.waiting.wait(execute(pgconn), pgconn.socket)
+ return psycopg.waiting.wait(execute(pgconn), pgconn.socket)
def test_send_query(pgconn):
def test_send_query_compact_test(pgconn):
- # Like the above test but use psycopg3 facilities for compactness
+ # Like the above test but use psycopg facilities for compactness
pgconn.send_query(
b"/* %s */ select pg_sleep(0.01); select 1 as foo;"
% (b"x" * 1_000_000)
assert results[1].get_value(0, 0) == b"1"
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.send_query(b"select 1")
assert res.get_value(0, 0) == b"8"
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.send_query_params(b"select $1", [b"1"])
assert res.get_value(0, 0) == b"8"
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.send_prepare(b"prep", b"select $1::int + $2::int")
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.send_query_prepared(b"prep", [b"3", b"5"])
assert res.ftype(0) == 23
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.send_describe_prepared(b"prep")
assert res.fname(0) == b"foo"
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.send_describe_portal(b"cur")
import pytest
-import psycopg3
-from psycopg3 import pq
+import psycopg
+from psycopg import pq
def test_defaults(monkeypatch):
def test_conninfo_parse_bad():
- with pytest.raises(psycopg3.OperationalError) as e:
+ with pytest.raises(psycopg.OperationalError) as e:
pq.Conninfo.parse(b"bad_conninfo=")
assert "bad_conninfo" in str(e.value)
import pytest
-import psycopg3
-from psycopg3 import pq
+import psycopg
+from psycopg import pq
sample_values = "values (10::int, 20::int, 'hello'::text), (40, NULL, 'world')"
def test_put_data_no_copy(pgconn):
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.put_copy_data(b"wat")
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.put_copy_data(b"wat")
def test_put_end_no_copy(pgconn):
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.put_copy_end()
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.put_copy_end()
def test_get_data_no_copy(pgconn):
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.get_copy_data(0)
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.get_copy_data(0)
import pytest
-import psycopg3
-from psycopg3 import pq
+import psycopg
+from psycopg import pq
@pytest.mark.parametrize(
def test_escape_literal_noconn(pgconn):
esc = pq.Escaping()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
esc.escape_literal(b"hi")
esc = pq.Escaping(pgconn)
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
esc.escape_literal(b"hi")
def test_escape_identifier_noconn(pgconn):
esc = pq.Escaping()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
esc.escape_identifier(b"hi")
esc = pq.Escaping(pgconn)
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
esc.escape_identifier(b"hi")
def test_escape_string_badconn(pgconn):
esc = pq.Escaping(pgconn)
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
esc.escape_string(b"hi")
assert res.status == pq.ExecStatus.COMMAND_OK
data = "\u20ac".encode("utf8")[:-1]
esc = pq.Escaping(pgconn)
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
esc.escape_string(data)
assert rv == exp
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
esc.escape_bytea(data)
assert rv == data
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
esc.unescape_bytea(data)
import pytest
-import psycopg3
-from psycopg3 import pq
+import psycopg
+from psycopg import pq
def test_exec_none(pgconn):
res = pgconn.exec_(b"select 'hel' || 'lo'")
assert res.get_value(0, 0) == b"hello"
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.exec_(b"select 'hello'")
assert res.status == pq.ExecStatus.TUPLES_OK
assert res.get_value(0, 0) == b"8"
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.exec_params(b"select $1::int + $2", [b"5", b"3"])
assert res.get_value(0, 0) == b"8"
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.prepare(b"prep", b"select $1::int + $2::int")
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.exec_prepared(b"prep", [b"3", b"5"])
assert res.fname(0) == b"foo"
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.describe_portal(b"cur")
import pytest
-import psycopg3
-from psycopg3 import pq
+import psycopg
+from psycopg import pq
def test_error_message(pgconn):
assert res.ftype(1) == 1700
assert res.ftype(2) == 25
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
res.set_attributes(attrs)
import pytest
-import psycopg3
-from psycopg3 import pq
-import psycopg3.generators
+import psycopg
+from psycopg import pq
+import psycopg.generators
from ..utils import gc_collect
def test_connectdb_error():
- conn = pq.PGconn.connect(b"dbname=psycopg3_test_not_for_real")
+ conn = pq.PGconn.connect(b"dbname=psycopg_test_not_for_real")
assert conn.status == pq.ConnStatus.BAD
assert conn.status == pq.ConnStatus.OK
conn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
conn.connect_poll()
for e in pq.Conninfo.parse(dsn.encode("utf8"))
if e.val
}
- parsed_dsn[b"dbname"] = b"psycopg3_test_not_for_real"
+ parsed_dsn[b"dbname"] = b"psycopg_test_not_for_real"
dsn = b" ".join(b"%s='%s'" % item for item in parsed_dsn.items())
conn = pq.PGconn.connect_start(dsn)
while 1:
assert dbname.val == (name or user)
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.info
assert pgconn.status == pq.ConnStatus.OK
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.reset()
assert pgconn.status == pq.ConnStatus.BAD
assert pgconn.status == pq.ConnStatus.OK
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.reset_start()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.reset_poll()
name = [o.val for o in pgconn.info if o.keyword == b"dbname"][0]
assert pgconn.db == name
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.db
user = [o.val for o in pgconn.info if o.keyword == b"user"][0]
assert pgconn.user == user
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.user
# not in info
assert isinstance(pgconn.password, bytes)
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.password
# might be not in info
assert isinstance(pgconn.host, bytes)
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.host
# not in info
assert isinstance(pgconn.hostaddr, bytes), pgconn.hostaddr
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.hostaddr
@pytest.mark.xfail
@pytest.mark.libpq("< 12")
def test_hostaddr_missing(pgconn):
- with pytest.raises(psycopg3.NotSupportedError):
+ with pytest.raises(psycopg.NotSupportedError):
pgconn.hostaddr
port = [o.val for o in pgconn.info if o.keyword == b"port"][0]
assert pgconn.port == port
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.port
tty = [o.val for o in pgconn.info if o.keyword == b"tty"][0]
assert pgconn.tty == tty
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.tty
assert pgconn.transaction_status == pq.TransactionStatus.INTRANS
pgconn.send_query(b"select 1")
assert pgconn.transaction_status == pq.TransactionStatus.ACTIVE
- psycopg3.waiting.wait(psycopg3.generators.execute(pgconn), pgconn.socket)
+ psycopg.waiting.wait(psycopg.generators.execute(pgconn), pgconn.socket)
assert pgconn.transaction_status == pq.TransactionStatus.INTRANS
pgconn.finish()
assert pgconn.transaction_status == pq.TransactionStatus.UNKNOWN
def test_parameter_status(dsn, monkeypatch):
- monkeypatch.setenv("PGAPPNAME", "psycopg3 tests")
+ monkeypatch.setenv("PGAPPNAME", "psycopg tests")
pgconn = pq.PGconn.connect(dsn.encode("utf8"))
- assert pgconn.parameter_status(b"application_name") == b"psycopg3 tests"
+ assert pgconn.parameter_status(b"application_name") == b"psycopg tests"
assert pgconn.parameter_status(b"wat") is None
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.parameter_status(b"application_name")
assert pgconn.parameter_status(b"client_encoding") == b"UTF8"
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.parameter_status(b"client_encoding")
def test_protocol_version(pgconn):
assert pgconn.protocol_version == 3
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.protocol_version
def test_server_version(pgconn):
assert pgconn.server_version >= 90400
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.server_version
# so let's see if at least an ok value comes out of it.
try:
assert pgconn.socket == socket
- except psycopg3.OperationalError:
+ except psycopg.OperationalError:
pass
def test_backend_pid(pgconn):
assert isinstance(pgconn.backend_pid, int)
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.backend_pid
assert pgconn.ssl_in_use
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.ssl_in_use
def test_set_single_row_mode(pgconn):
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.set_single_row_mode()
pgconn.send_query(b"select 1")
cancel.cancel()
pgconn.finish()
cancel.cancel()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
pgconn.get_cancel()
def test_cancel_free(pgconn):
cancel = pgconn.get_cancel()
cancel.free()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
cancel.cancel()
cancel.free()
def test_notice_error(pgconn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3")
+ caplog.set_level(logging.WARNING, logger="psycopg")
def callback(res):
raise Exception("hello error")
import ctypes
import pytest
-from psycopg3 import pq
+from psycopg import pq
@pytest.mark.parametrize(
-from psycopg3 import pq
+from psycopg import pq
def test_version():
"""
from random import randrange
from decimal import Decimal
-import psycopg3
-from psycopg3 import sql
+import psycopg
+from psycopg import sql
ncols = 10
nrows = 500000
-format = psycopg3.pq.Format.BINARY
+format = psycopg.pq.Format.BINARY
test = "copy"
def main():
- cnn = psycopg3.connect()
+ cnn = psycopg.connect()
cnn.execute(
sql.SQL("create table testdec ({})").format(
import time
import threading
-import psycopg3.pool
+import psycopg.pool
import logging
logging.getLogger("psycopg2.pool").setLevel(loglevel)
- with psycopg3.pool.ConnectionPool(
+ with psycopg.pool.ConnectionPool(
opt.dsn,
min_size=opt.min_size,
max_size=opt.max_size,
time.sleep(interval)
-class DelayedConnection(psycopg3.Connection):
+class DelayedConnection(psycopg.Connection):
"""A connection adding a delay to the connection time."""
@classmethod
import pytest
-import psycopg3
-from psycopg3 import pq
-from psycopg3.adapt import Transformer, Format, Dumper, Loader
-from psycopg3.oids import postgres_types as builtins, TEXT_OID
+import psycopg
+from psycopg import pq
+from psycopg.adapt import Transformer, Format, Dumper, Loader
+from psycopg.oids import postgres_types as builtins, TEXT_OID
@pytest.mark.parametrize(
def test_subclass_dumper(conn):
# This might be a C fast object: make sure that the Python code is called
- from psycopg3.types.string import StrDumper
+ from psycopg.types.string import StrDumper
class MyStrDumper(StrDumper):
def dump(self, obj):
def test_subclass_loader(conn):
# This might be a C fast object: make sure that the Python code is called
- from psycopg3.types.string import TextLoader
+ from psycopg.types.string import TextLoader
class MyTextLoader(TextLoader):
def load(self, data):
L = []
L.append(L)
- with pytest.raises(psycopg3.DataError):
+ with pytest.raises(psycopg.DataError):
assert t.get_dumper(L, fmt_in)
assert cur.fetchone()[0] == 20
-@pytest.mark.skipif(psycopg3.pq.__impl__ == "python", reason="C module test")
+@pytest.mark.skipif(psycopg.pq.__impl__ == "python", reason="C module test")
def test_optimised_adapters():
- from psycopg3_c import _psycopg3
+ from psycopg_c import _psycopg
# All the optimised adapters available
c_adapters = {}
- for n in dir(_psycopg3):
+ for n in dir(_psycopg):
if n.startswith("_") or n in ("CDumper", "CLoader"):
continue
- obj = getattr(_psycopg3, n)
+ obj = getattr(_psycopg, n)
if not isinstance(obj, type):
continue
- if not issubclass(obj, (_psycopg3.CDumper, _psycopg3.CLoader)):
+ if not issubclass(obj, (_psycopg.CDumper, _psycopg.CLoader)):
continue
c_adapters[n] = obj
# All the registered adapters
reg_adapters = set()
adapters = (
- list(psycopg3.global_adapters._dumpers.values())
- + psycopg3.global_adapters._loaders
+ list(psycopg.global_adapters._dumpers.values())
+ + psycopg.global_adapters._loaders
)
assert len(adapters) == 5
for m in adapters:
assert n >= 10
# Check that every optimised adapter is the optimised version of a Py one
- for n in dir(psycopg3.types):
- mod = getattr(psycopg3.types, n)
+ for n in dir(psycopg.types):
+ mod = getattr(psycopg.types, n)
if not isinstance(mod, ModuleType):
continue
for n1 in dir(mod):
cur.execute(faker.create_stmt)
try:
cur.executemany(faker.insert_stmt, faker.records)
- except psycopg3.DatabaseError:
+ except psycopg.DatabaseError:
# Insert one by one to find problematic values
conn.rollback()
cur.execute(faker.drop_stmt)
import threading
import subprocess as sp
-import psycopg3
+import psycopg
@pytest.mark.slow
def test_concurrent_execution(dsn):
def worker():
- cnn = psycopg3.connect(dsn)
+ cnn = psycopg.connect(dsn)
cur = cnn.cursor()
cur.execute("select pg_sleep(0.5)")
cur.close()
# Subprocess gcs the copy of the fd after fork so it closes connection.
module = f"""\
import time
-import psycopg3
+import psycopg
def thread():
- conn = psycopg3.connect({dsn!r})
+ conn = psycopg.connect({dsn!r})
curs = conn.cursor()
for i in range(10):
curs.execute("select 1")
@pytest.mark.slow
def test_notifies(conn, dsn):
- nconn = psycopg3.connect(dsn, autocommit=True)
+ nconn = psycopg.connect(dsn, autocommit=True)
npid = nconn.pgconn.backend_pid
def notifier():
assert len(ns) == 2
n, t1 = ns[0]
- assert isinstance(n, psycopg3.Notify)
+ assert isinstance(n, psycopg.Notify)
assert n.pid == npid
assert n.channel == "foo"
assert n.payload == "1"
t0 = time.time()
t.start()
- with pytest.raises(psycopg3.DatabaseError):
+ with pytest.raises(psycopg.DatabaseError):
cur.execute("select pg_sleep(2)")
t1 = time.time()
@pytest.mark.slow
def test_identify_closure(conn, dsn):
- conn2 = psycopg3.connect(dsn)
+ conn2 = psycopg.connect(dsn)
def closer():
time.sleep(0.3)
t.start()
assert sel.select(timeout=1.0)
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
conn.execute("select 1")
t1 = time.time()
assert 0.3 < t1 - t0 < 0.5
import asyncio
from asyncio.queues import Queue
-import psycopg3
-from psycopg3.compat import create_task
+import psycopg
+from psycopg.compat import create_task
pytestmark = pytest.mark.asyncio
@pytest.mark.slow
async def test_concurrent_execution(dsn):
async def worker():
- cnn = await psycopg3.AsyncConnection.connect(dsn)
+ cnn = await psycopg.AsyncConnection.connect(dsn)
cur = cnn.cursor()
await cur.execute("select pg_sleep(0.5)")
await cur.close()
@pytest.mark.slow
async def test_notifies(aconn, dsn):
- nconn = await psycopg3.AsyncConnection.connect(dsn, autocommit=True)
+ nconn = await psycopg.AsyncConnection.connect(dsn, autocommit=True)
npid = nconn.pgconn.backend_pid
async def notifier():
async def worker():
cur = aconn.cursor()
- with pytest.raises(psycopg3.DatabaseError):
+ with pytest.raises(psycopg.DatabaseError):
await cur.execute("select pg_sleep(2)")
workers = [worker(), canceller()]
@pytest.mark.slow
async def test_identify_closure(aconn, dsn):
- conn2 = await psycopg3.AsyncConnection.connect(dsn)
+ conn2 = await psycopg.AsyncConnection.connect(dsn)
async def closer():
await asyncio.sleep(0.3)
create_task(closer())
await asyncio.wait_for(ev.wait(), 1.0)
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
await aconn.execute("select 1")
t1 = time.time()
assert 0.3 < t1 - t0 < 0.5
import weakref
from threading import Thread
-import psycopg3
-from psycopg3 import encodings
-from psycopg3 import Connection, Notify
-from psycopg3.rows import tuple_row
-from psycopg3.errors import UndefinedTable
-from psycopg3.conninfo import conninfo_to_dict
+import psycopg
+from psycopg import encodings
+from psycopg import Connection, Notify
+from psycopg.rows import tuple_row
+from psycopg.errors import UndefinedTable
+from psycopg.conninfo import conninfo_to_dict
from .utils import gc_collect
from .test_cursor import my_row_factory
def test_connect_bad():
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
Connection.connect("dbname=nosuchdb")
Thread(target=closer).start()
t0 = time.time()
- with pytest.raises(psycopg3.OperationalError, match="timeout expired"):
+ with pytest.raises(psycopg.OperationalError, match="timeout expired"):
Connection.connect(host="localhost", port=port, connect_timeout=1)
elapsed = time.time() - t0
assert elapsed == pytest.approx(1.0, abs=0.05)
assert conn.closed
assert conn.pgconn.status == conn.ConnStatus.BAD
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
cur.execute("select 1")
def test_broken(conn):
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
conn.execute(
"select pg_terminate_backend(%s)", [conn.pgconn.backend_pid]
)
assert conn.closed
assert not conn.broken
- with psycopg3.connect(dsn) as conn:
+ with psycopg.connect(dsn) as conn:
with conn.cursor() as cur:
cur.execute("select * from textctx")
assert cur.fetchall() == []
assert conn.closed
assert not conn.broken
- with psycopg3.connect(dsn) as conn:
+ with psycopg.connect(dsn) as conn:
with conn.cursor() as cur:
with pytest.raises(UndefinedTable):
cur.execute("select * from textctx")
def test_context_rollback_no_clobber(conn, dsn, recwarn):
with pytest.raises(ZeroDivisionError):
- with psycopg3.connect(dsn) as conn2:
+ with psycopg.connect(dsn) as conn2:
conn2.execute("select 1")
conn.execute(
"select pg_terminate_backend(%s::int)",
def test_weakref(dsn):
- conn = psycopg3.connect(dsn)
+ conn = psycopg.connect(dsn)
w = weakref.ref(conn)
conn.close()
del conn
assert res.get_value(0, 0) == b"1"
conn.close()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
conn.commit()
assert res.ntuples == 0
conn.close()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
conn.rollback()
cur.execute("insert into foo values (1)")
assert conn.pgconn.transaction_status == conn.TransactionStatus.INTRANS
- with pytest.raises(psycopg3.DatabaseError):
+ with pytest.raises(psycopg.DatabaseError):
cur.execute("meh")
assert conn.pgconn.transaction_status == conn.TransactionStatus.INERROR
- with pytest.raises(psycopg3.errors.InFailedSqlTransaction):
+ with pytest.raises(psycopg.errors.InFailedSqlTransaction):
cur.execute("select 1")
conn.commit()
cur = conn.cursor()
assert cur.execute("select 1").fetchone() == (1,)
assert conn.pgconn.transaction_status == conn.TransactionStatus.INTRANS
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
conn.autocommit = True
assert not conn.autocommit
def test_autocommit_inerror(conn):
cur = conn.cursor()
- with pytest.raises(psycopg3.DatabaseError):
+ with pytest.raises(psycopg.DatabaseError):
cur.execute("meh")
assert conn.pgconn.transaction_status == conn.TransactionStatus.INERROR
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
conn.autocommit = True
assert not conn.autocommit
def test_autocommit_unknown(conn):
conn.close()
assert conn.pgconn.transaction_status == conn.TransactionStatus.UNKNOWN
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
conn.autocommit = True
assert not conn.autocommit
)
def test_encoding_env_var(dsn, monkeypatch, enc, out, codec):
monkeypatch.setenv("PGCLIENTENCODING", enc)
- conn = psycopg3.connect(dsn)
+ conn = psycopg.connect(dsn)
assert (
conn.pgconn.parameter_status(b"client_encoding").decode("utf-8") == out
)
def test_set_encoding_unsupported(conn):
cur = conn.cursor()
cur.execute("set client_encoding to EUC_TW")
- with pytest.raises(psycopg3.NotSupportedError):
+ with pytest.raises(psycopg.NotSupportedError):
cur.execute("select 'x'")
return pgconn
yield
- monkeypatch.setattr(psycopg3.connection, "connect", fake_connect)
- psycopg3.Connection.connect(*args, **kwargs)
+ monkeypatch.setattr(psycopg.connection, "connect", fake_connect)
+ psycopg.Connection.connect(*args, **kwargs)
assert conninfo_to_dict(the_conninfo) == conninfo_to_dict(want)
return pgconn
yield
- monkeypatch.setattr(psycopg3.connection, "connect", fake_connect)
- with pytest.raises((TypeError, psycopg3.ProgrammingError)):
- psycopg3.Connection.connect(*args, **kwargs)
+ monkeypatch.setattr(psycopg.connection, "connect", fake_connect)
+ with pytest.raises((TypeError, psycopg.ProgrammingError)):
+ psycopg.Connection.connect(*args, **kwargs)
def test_broken_connection(conn):
cur = conn.cursor()
- with pytest.raises(psycopg3.DatabaseError):
+ with pytest.raises(psycopg.DatabaseError):
cur.execute("select pg_terminate_backend(pg_backend_pid())")
assert conn.closed
def test_notice_handlers(conn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3")
+ caplog.set_level(logging.WARNING, logger="psycopg")
messages = []
severities = []
def test_fileno(conn):
assert conn.fileno() == conn.pgconn.socket
conn.close()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
conn.fileno()
import logging
import weakref
-import psycopg3
-from psycopg3 import encodings
-from psycopg3 import AsyncConnection, Notify
-from psycopg3.rows import tuple_row
-from psycopg3.errors import UndefinedTable
-from psycopg3.conninfo import conninfo_to_dict
+import psycopg
+from psycopg import encodings
+from psycopg import AsyncConnection, Notify
+from psycopg.rows import tuple_row
+from psycopg.errors import UndefinedTable
+from psycopg.conninfo import conninfo_to_dict
from .utils import gc_collect
from .test_cursor import my_row_factory
async def test_connect_bad():
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
await AsyncConnection.connect("dbname=nosuchdb")
async def connect():
t0 = time.time()
- with pytest.raises(psycopg3.OperationalError, match="timeout expired"):
+ with pytest.raises(psycopg.OperationalError, match="timeout expired"):
await AsyncConnection.connect(
host="localhost", port=port, connect_timeout=1
)
assert aconn.closed
assert aconn.pgconn.status == aconn.ConnStatus.BAD
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
await cur.execute("select 1")
async def test_broken(aconn):
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
await aconn.execute(
"select pg_terminate_backend(%s)", [aconn.pgconn.backend_pid]
)
assert aconn.closed
assert not aconn.broken
- async with await psycopg3.AsyncConnection.connect(dsn) as aconn:
+ async with await psycopg.AsyncConnection.connect(dsn) as aconn:
async with aconn.cursor() as cur:
await cur.execute("select * from textctx")
assert await cur.fetchall() == []
assert aconn.closed
assert not aconn.broken
- async with await psycopg3.AsyncConnection.connect(dsn) as aconn:
+ async with await psycopg.AsyncConnection.connect(dsn) as aconn:
async with aconn.cursor() as cur:
with pytest.raises(UndefinedTable):
await cur.execute("select * from textctx")
async def test_context_rollback_no_clobber(conn, dsn, recwarn):
with pytest.raises(ZeroDivisionError):
- async with await psycopg3.AsyncConnection.connect(dsn) as conn2:
+ async with await psycopg.AsyncConnection.connect(dsn) as conn2:
await conn2.execute("select 1")
conn.execute(
"select pg_terminate_backend(%s::int)",
async def test_weakref(dsn):
- conn = await psycopg3.AsyncConnection.connect(dsn)
+ conn = await psycopg.AsyncConnection.connect(dsn)
w = weakref.ref(conn)
await conn.close()
del conn
assert res.get_value(0, 0) == b"1"
await aconn.close()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
await aconn.commit()
assert res.ntuples == 0
await aconn.close()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
await aconn.rollback()
await cur.execute("insert into foo values (1)")
assert aconn.pgconn.transaction_status == aconn.TransactionStatus.INTRANS
- with pytest.raises(psycopg3.DatabaseError):
+ with pytest.raises(psycopg.DatabaseError):
await cur.execute("meh")
assert aconn.pgconn.transaction_status == aconn.TransactionStatus.INERROR
async def test_autocommit_connect(dsn):
- aconn = await psycopg3.AsyncConnection.connect(dsn, autocommit=True)
+ aconn = await psycopg.AsyncConnection.connect(dsn, autocommit=True)
assert aconn.autocommit
await cur.execute("select 1")
assert await cur.fetchone() == (1,)
assert aconn.pgconn.transaction_status == aconn.TransactionStatus.INTRANS
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
await aconn.set_autocommit(True)
assert not aconn.autocommit
async def test_autocommit_inerror(aconn):
cur = aconn.cursor()
- with pytest.raises(psycopg3.DatabaseError):
+ with pytest.raises(psycopg.DatabaseError):
await cur.execute("meh")
assert aconn.pgconn.transaction_status == aconn.TransactionStatus.INERROR
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
await aconn.set_autocommit(True)
assert not aconn.autocommit
async def test_autocommit_unknown(aconn):
await aconn.close()
assert aconn.pgconn.transaction_status == aconn.TransactionStatus.UNKNOWN
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
await aconn.set_autocommit(True)
assert not aconn.autocommit
)
async def test_encoding_env_var(dsn, monkeypatch, enc, out, codec):
monkeypatch.setenv("PGCLIENTENCODING", enc)
- aconn = await psycopg3.AsyncConnection.connect(dsn)
+ aconn = await psycopg.AsyncConnection.connect(dsn)
assert (
aconn.pgconn.parameter_status(b"client_encoding").decode("utf-8")
== out
async def test_set_encoding_unsupported(aconn):
cur = aconn.cursor()
await cur.execute("set client_encoding to EUC_TW")
- with pytest.raises(psycopg3.NotSupportedError):
+ with pytest.raises(psycopg.NotSupportedError):
await cur.execute("select 'x'")
return pgconn
yield
- monkeypatch.setattr(psycopg3.connection, "connect", fake_connect)
- await psycopg3.AsyncConnection.connect(*args, **kwargs)
+ monkeypatch.setattr(psycopg.connection, "connect", fake_connect)
+ await psycopg.AsyncConnection.connect(*args, **kwargs)
assert conninfo_to_dict(the_conninfo) == conninfo_to_dict(want)
return pgconn
yield
- monkeypatch.setattr(psycopg3.connection, "connect", fake_connect)
- with pytest.raises((TypeError, psycopg3.ProgrammingError)):
- await psycopg3.AsyncConnection.connect(*args, **kwargs)
+ monkeypatch.setattr(psycopg.connection, "connect", fake_connect)
+ with pytest.raises((TypeError, psycopg.ProgrammingError)):
+ await psycopg.AsyncConnection.connect(*args, **kwargs)
async def test_broken_connection(aconn):
cur = aconn.cursor()
- with pytest.raises(psycopg3.DatabaseError):
+ with pytest.raises(psycopg.DatabaseError):
await cur.execute("select pg_terminate_backend(pg_backend_pid())")
assert aconn.closed
async def test_notice_handlers(aconn, caplog):
- caplog.set_level(logging.WARNING, logger="psycopg3")
+ caplog.set_level(logging.WARNING, logger="psycopg")
messages = []
severities = []
async def test_fileno(aconn):
assert aconn.fileno() == aconn.pgconn.socket
await aconn.close()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
aconn.fileno()
import pytest
-import psycopg3
-from psycopg3 import ProgrammingError
-from psycopg3.conninfo import (
+import psycopg
+from psycopg import ProgrammingError
+from psycopg.conninfo import (
_conninfo_connect_timeout,
make_conninfo,
conninfo_to_dict,
else:
info_attr = pgconn_attr = attr
- if info_attr == "hostaddr" and psycopg3.pq.version() < 120000:
+ if info_attr == "hostaddr" and psycopg.pq.version() < 120000:
pytest.skip("hostaddr not supported on libpq < 12")
info_val = getattr(conn.info, info_attr)
assert info_val == pgconn_val
conn.close()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
getattr(conn.info, info_attr)
@pytest.mark.libpq("< 12")
def test_hostaddr_not_supported(self, conn):
- with pytest.raises(psycopg3.NotSupportedError):
+ with pytest.raises(psycopg.NotSupportedError):
conn.info.hostaddr
def test_port(self, conn):
assert conn.info.port == int(conn.pgconn.port.decode("utf-8"))
conn.close()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
conn.info.port
def test_get_params(self, conn, dsn):
dsn.pop("application_name", None)
monkeypatch.delenv("PGAPPNAME", raising=False)
- with psycopg3.connect(**dsn) as conn:
+ with psycopg.connect(**dsn) as conn:
assert "application_name" not in conn.info.get_parameters()
monkeypatch.setenv("PGAPPNAME", "hello test")
- with psycopg3.connect(**dsn) as conn:
+ with psycopg.connect(**dsn) as conn:
assert (
conn.info.get_parameters()["application_name"] == "hello test"
)
def test_no_password(self, dsn):
dsn2 = make_conninfo(dsn, password="the-pass-word")
- pgconn = psycopg3.pq.PGconn.connect_start(dsn2.encode("utf8"))
+ pgconn = psycopg.pq.PGconn.connect_start(dsn2.encode("utf8"))
info = ConnectionInfo(pgconn)
assert info.password == "the-pass-word"
assert "password" not in info.get_parameters()
def test_error_message(self, conn):
assert conn.info.error_message == ""
- with pytest.raises(psycopg3.ProgrammingError) as ex:
+ with pytest.raises(psycopg.ProgrammingError) as ex:
conn.execute("wat")
assert conn.info.error_message
assert ex.value.diag.severity in conn.info.error_message
conn.close()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
conn.info.error_message
def test_backend_pid(self, conn):
assert conn.info.backend_pid
assert conn.info.backend_pid == conn.pgconn.backend_pid
conn.close()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
conn.info.backend_pid
def test_timezone(self, conn):
import pytest
-import psycopg3
-from psycopg3 import pq
-from psycopg3 import sql
-from psycopg3 import errors as e
-from psycopg3.pq import Format
-from psycopg3.adapt import Format as PgFormat
-from psycopg3.types.numeric import Int4
+import psycopg
+from psycopg import pq
+from psycopg import sql
+from psycopg import errors as e
+from psycopg.pq import Format
+from psycopg.adapt import Format as PgFormat
+from psycopg.types.numeric import Int4
from .utils import gc_collect
@pytest.mark.parametrize("format", [Format.TEXT, Format.BINARY])
def test_subclass_adapter(conn, format):
if format == Format.TEXT:
- from psycopg3.types.string import StrDumper as BaseDumper
+ from psycopg.types.string import StrDumper as BaseDumper
else:
- from psycopg3.types.string import StrBinaryDumper as BaseDumper
+ from psycopg.types.string import StrBinaryDumper as BaseDumper
class MyStrDumper(BaseDumper):
def dump(self, obj):
faker.make_records(20)
def work():
- with psycopg3.connect(dsn) as conn:
+ with psycopg.connect(dsn) as conn:
with conn.cursor(binary=fmt) as cur:
cur.execute(faker.drop_stmt)
cur.execute(faker.create_stmt)
faker.make_records(20)
def work():
- with psycopg3.connect(dsn) as conn:
+ with psycopg.connect(dsn) as conn:
with conn.cursor(binary=fmt) as cur:
cur.execute(faker.drop_stmt)
cur.execute(faker.create_stmt)
import pytest
-import psycopg3
-from psycopg3 import pq
-from psycopg3 import sql
-from psycopg3 import errors as e
-from psycopg3.pq import Format
-from psycopg3.adapt import Format as PgFormat
+import psycopg
+from psycopg import pq
+from psycopg import sql
+from psycopg import errors as e
+from psycopg.pq import Format
+from psycopg.adapt import Format as PgFormat
from .utils import gc_collect
from .test_copy import sample_text, sample_binary, sample_binary_rows # noqa
faker.make_records(20)
async def work():
- async with await psycopg3.AsyncConnection.connect(dsn) as conn:
+ async with await psycopg.AsyncConnection.connect(dsn) as conn:
async with conn.cursor(binary=fmt) as cur:
await cur.execute(faker.drop_stmt)
await cur.execute(faker.create_stmt)
faker.make_records(20)
async def work():
- async with await psycopg3.AsyncConnection.connect(dsn) as conn:
+ async with await psycopg.AsyncConnection.connect(dsn) as conn:
async with conn.cursor(binary=fmt) as cur:
await cur.execute(faker.drop_stmt)
await cur.execute(faker.create_stmt)
import pytest
-import psycopg3
-from psycopg3 import pq, sql, rows
-from psycopg3.oids import postgres_types as builtins
-from psycopg3.adapt import Format
+import psycopg
+from psycopg import pq, sql, rows
+from psycopg.oids import postgres_types as builtins
+from psycopg.adapt import Format
from .utils import gc_collect
cur.close()
assert cur.closed
- with pytest.raises(psycopg3.InterfaceError):
+ with pytest.raises(psycopg.InterfaceError):
cur.execute("select 'foo'")
cur.close()
cur = conn.cursor()
cur.execute(query)
assert cur.status == cur.ExecStatus.EMPTY_QUERY
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
cur.fetchone()
def test_execute_copy(conn, query):
cur = conn.cursor()
cur.execute("create table testcopy (id int)")
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
cur.execute(query)
)
def test_executemany_badquery(conn, query):
cur = conn.cursor()
- with pytest.raises(psycopg3.DatabaseError):
+ with pytest.raises(psycopg.DatabaseError):
cur.executemany(query, [(10, "hello"), (20, "world")])
f"insert into testmany values (%{fmt_in}, %{fmt_in})",
[[1, None], [3, 4]],
)
- with pytest.raises((psycopg3.DataError, psycopg3.ProgrammingError)):
+ with pytest.raises((psycopg.DataError, psycopg.ProgrammingError)):
cur.executemany(
f"insert into testmany values (%{fmt_in}, %{fmt_in})",
[[1, ""], [3, 4]],
def test_scroll(conn):
cur = conn.cursor()
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
cur.scroll(0)
cur.execute("select generate_series(0,9)")
assert cur.query == b"select 1"
assert cur.params is None
- with pytest.raises(psycopg3.DataError):
+ with pytest.raises(psycopg.DataError):
cur.execute("select %t::int", ["wat"])
assert cur.query == b"select $1::int"
assert cur.query == b"select $1, $2"
assert cur.params == [b"3", b"4"]
- with pytest.raises((psycopg3.DataError, TypeError)):
+ with pytest.raises((psycopg.DataError, TypeError)):
cur.executemany("select %t::int", [[1], ["x"], [2]])
assert cur.query == b"select $1::int"
# TODO: cannot really check this: after introduced row_dumpers, this
)
def test_stream_badquery(conn, query):
cur = conn.cursor()
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
for rec in cur.stream(query):
pass
n = []
for i in range(3):
- with psycopg3.connect(dsn) as conn:
+ with psycopg.connect(dsn) as conn:
with conn.cursor(binary=fmt_out, row_factory=row_factory) as cur:
cur.execute(faker.drop_stmt)
cur.execute(faker.create_stmt)
import weakref
import datetime as dt
-import psycopg3
-from psycopg3 import pq, sql, rows
-from psycopg3.adapt import Format
+import psycopg
+from psycopg import pq, sql, rows
+from psycopg.adapt import Format
from .utils import gc_collect
from .test_cursor import my_row_factory
await cur.close()
assert cur.closed
- with pytest.raises(psycopg3.InterfaceError):
+ with pytest.raises(psycopg.InterfaceError):
await cur.execute("select 'foo'")
await cur.close()
cur = aconn.cursor()
await cur.execute(query)
assert cur.status == cur.ExecStatus.EMPTY_QUERY
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
await cur.fetchone()
async def test_execute_copy(aconn, query):
cur = aconn.cursor()
await cur.execute("create table testcopy (id int)")
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
await cur.execute(query)
)
async def test_executemany_badquery(aconn, query):
cur = aconn.cursor()
- with pytest.raises(psycopg3.DatabaseError):
+ with pytest.raises(psycopg.DatabaseError):
await cur.executemany(query, [(10, "hello"), (20, "world")])
f"insert into testmany values (%{fmt_in}, %{fmt_in})",
[[1, None], [3, 4]],
)
- with pytest.raises((psycopg3.DataError, psycopg3.ProgrammingError)):
+ with pytest.raises((psycopg.DataError, psycopg.ProgrammingError)):
await cur.executemany(
f"insert into testmany values (%{fmt_in}, %{fmt_in})",
[[1, ""], [3, 4]],
async def test_scroll(aconn):
cur = aconn.cursor()
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
await cur.scroll(0)
await cur.execute("select generate_series(0,9)")
assert cur.query == b"select 1"
assert cur.params is None
- with pytest.raises(psycopg3.DataError):
+ with pytest.raises(psycopg.DataError):
await cur.execute("select %t::int", ["wat"])
assert cur.query == b"select $1::int"
assert cur.query == b"select $1, $2"
assert cur.params == [b"3", b"4"]
- with pytest.raises((psycopg3.DataError, TypeError)):
+ with pytest.raises((psycopg.DataError, TypeError)):
await cur.executemany("select %t::int", [[1], ["x"], [2]])
assert cur.query == b"select $1::int"
# TODO: cannot really check this: after introduced row_dumpers, this
)
async def test_stream_badquery(aconn, query):
cur = aconn.cursor()
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
async for rec in cur.stream(query):
pass
n = []
for i in range(3):
- async with await psycopg3.AsyncConnection.connect(dsn) as conn:
+ async with await psycopg.AsyncConnection.connect(dsn) as conn:
async with conn.cursor(
binary=fmt_out, row_factory=row_factory
) as cur:
import codecs
import pytest
-import psycopg3
-from psycopg3 import encodings
+import psycopg
+from psycopg import encodings
def test_names_normalised():
@pytest.mark.parametrize("pgenc", ["MULE_INTERNAL", "EUC_TW"])
def test_pg2py_missing(pgenc):
- with pytest.raises(psycopg3.NotSupportedError):
+ with pytest.raises(psycopg.NotSupportedError):
encodings.pg2py(pgenc.encode("utf-8"))
import pytest
-from psycopg3 import pq
-from psycopg3 import errors as e
+from psycopg import pq
+from psycopg import errors as e
from .utils import gc_collect
],
)
def test_connect(monkeypatch, dsn, args, kwargs, want_conninfo):
- # Check the main args passing from psycopg3.connect to the conn generator
+ # Check the main args passing from psycopg.connect to the conn generator
# Details of the params manipulation are in test_conninfo.
- import psycopg3.connection
+ import psycopg.connection
- orig_connect = psycopg3.connection.connect
+ orig_connect = psycopg.connection.connect
got_conninfo = None
got_conninfo = conninfo
return orig_connect(dsn)
- monkeypatch.setattr(psycopg3.connection, "connect", mock_connect)
+ monkeypatch.setattr(psycopg.connection, "connect", mock_connect)
- psycopg3.connect(*args, **kwargs)
+ psycopg.connect(*args, **kwargs)
assert got_conninfo == want_conninfo
import pytest
import datetime as dt
-import psycopg3
-from psycopg3.conninfo import conninfo_to_dict
+import psycopg
+from psycopg.conninfo import conninfo_to_dict
from . import dbapi20
@pytest.mark.usefixtures("with_dsn")
-class Psycopg3Tests(dbapi20.DatabaseAPI20Test):
- driver = psycopg3
+class PsycopgTests(dbapi20.DatabaseAPI20Test):
+ driver = psycopg
# connect_args = () # set by the fixture
connect_kw_args = {}
# Shut up warnings
-Psycopg3Tests.failUnless = Psycopg3Tests.assertTrue
+PsycopgTests.failUnless = PsycopgTests.assertTrue
@pytest.mark.parametrize(
],
)
def test_singletons(conn, typename, singleton):
- singleton = getattr(psycopg3, singleton)
+ singleton = getattr(psycopg, singleton)
cur = conn.cursor()
cur.execute(f"select null::{typename}")
oid = cur.description[0].type_code
],
)
def test_timestamp_from_ticks(ticks, want):
- s = psycopg3.TimestampFromTicks(ticks)
+ s = psycopg.TimestampFromTicks(ticks)
want = dt.datetime.strptime(want, "%Y-%m-%dT%H:%M:%S.%f%z")
assert s == want
],
)
def test_date_from_ticks(ticks, want):
- s = psycopg3.DateFromTicks(ticks)
+ s = psycopg.DateFromTicks(ticks)
if isinstance(want, str):
want = [want]
want = [dt.datetime.strptime(w, "%Y-%m-%d").date() for w in want]
[(0, "00:00:00.000000"), (1273173119.99992, "00:11:59.999920")],
)
def test_time_from_ticks(ticks, want):
- s = psycopg3.TimeFromTicks(ticks)
+ s = psycopg.TimeFromTicks(ticks)
want = dt.datetime.strptime(want, "%H:%M:%S.%f").time()
assert s.replace(hour=0) == want
return pgconn
yield
- monkeypatch.setattr(psycopg3.connection, "connect", fake_connect)
- psycopg3.connect(*args, **kwargs)
+ monkeypatch.setattr(psycopg.connection, "connect", fake_connect)
+ psycopg.connect(*args, **kwargs)
assert conninfo_to_dict(the_conninfo) == conninfo_to_dict(want)
return pgconn
yield
- monkeypatch.setattr(psycopg3.connection, "connect", fake_connect)
- with pytest.raises((TypeError, psycopg3.ProgrammingError)):
- psycopg3.connect(*args, **kwargs)
+ monkeypatch.setattr(psycopg.connection, "connect", fake_connect)
+ with pytest.raises((TypeError, psycopg.ProgrammingError)):
+ psycopg.connect(*args, **kwargs)
import pytest
-import psycopg3
-from psycopg3 import pq
-from psycopg3.adapt import Transformer, Format
-from psycopg3._queries import PostgresQuery, _split_query
+import psycopg
+from psycopg import pq
+from psycopg.adapt import Transformer, Format
+from psycopg._queries import PostgresQuery, _split_query
@pytest.mark.parametrize(
],
)
def test_split_query_bad(input):
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
_split_query(input)
)
def test_pq_query_badprog(query, params):
pq = PostgresQuery(Transformer())
- with pytest.raises(psycopg3.ProgrammingError):
+ with pytest.raises(psycopg.ProgrammingError):
pq.convert(query, params)
-from psycopg3 import rows
+from psycopg import rows
def test_tuple_row(conn):
import pytest
-from psycopg3 import errors as e
-from psycopg3.pq import Format
-from psycopg3.rows import dict_row
+from psycopg import errors as e
+from psycopg.pq import Format
+from psycopg.rows import dict_row
def test_funny_name(conn):
import pytest
-from psycopg3 import errors as e
-from psycopg3.rows import dict_row
-from psycopg3.pq import Format
+from psycopg import errors as e
+from psycopg.rows import dict_row
+from psycopg.pq import Format
pytestmark = pytest.mark.asyncio
import pytest
-from psycopg3 import sql, ProgrammingError
-from psycopg3.adapt import Format
+from psycopg import sql, ProgrammingError
+from psycopg.adapt import Format
@pytest.mark.parametrize(
import pytest
-from psycopg3 import Connection, ProgrammingError, Rollback
+from psycopg import Connection, ProgrammingError, Rollback
@pytest.fixture(autouse=True)
import pytest
-from psycopg3 import ProgrammingError, Rollback
+from psycopg import ProgrammingError, Rollback
from .test_transaction import in_transaction, insert_row, inserted
from .test_transaction import ExpectedException
"conn, type",
[
(
- "psycopg3.connect()",
- "psycopg3.Connection[Tuple[Any, ...]]",
+ "psycopg.connect()",
+ "psycopg.Connection[Tuple[Any, ...]]",
),
(
- "psycopg3.connect(row_factory=rows.tuple_row)",
- "psycopg3.Connection[Tuple[Any, ...]]",
+ "psycopg.connect(row_factory=rows.tuple_row)",
+ "psycopg.Connection[Tuple[Any, ...]]",
),
(
- "psycopg3.connect(row_factory=rows.dict_row)",
- "psycopg3.Connection[Dict[str, Any]]",
+ "psycopg.connect(row_factory=rows.dict_row)",
+ "psycopg.Connection[Dict[str, Any]]",
),
(
- "psycopg3.connect(row_factory=rows.namedtuple_row)",
- "psycopg3.Connection[NamedTuple]",
+ "psycopg.connect(row_factory=rows.namedtuple_row)",
+ "psycopg.Connection[NamedTuple]",
),
(
- "psycopg3.connect(row_factory=thing_row)",
- "psycopg3.Connection[Thing]",
+ "psycopg.connect(row_factory=thing_row)",
+ "psycopg.Connection[Thing]",
),
(
- "psycopg3.Connection.connect()",
- "psycopg3.Connection[Tuple[Any, ...]]",
+ "psycopg.Connection.connect()",
+ "psycopg.Connection[Tuple[Any, ...]]",
),
(
- "psycopg3.Connection.connect(row_factory=rows.dict_row)",
- "psycopg3.Connection[Dict[str, Any]]",
+ "psycopg.Connection.connect(row_factory=rows.dict_row)",
+ "psycopg.Connection[Dict[str, Any]]",
),
(
- "await psycopg3.AsyncConnection.connect()",
- "psycopg3.AsyncConnection[Tuple[Any, ...]]",
+ "await psycopg.AsyncConnection.connect()",
+ "psycopg.AsyncConnection[Tuple[Any, ...]]",
),
(
- "await psycopg3.AsyncConnection.connect(row_factory=rows.dict_row)",
- "psycopg3.AsyncConnection[Dict[str, Any]]",
+ "await psycopg.AsyncConnection.connect(row_factory=rows.dict_row)",
+ "psycopg.AsyncConnection[Dict[str, Any]]",
),
],
)
"conn, curs, type",
[
(
- "psycopg3.connect()",
+ "psycopg.connect()",
"conn.cursor()",
- "psycopg3.Cursor[Tuple[Any, ...]]",
+ "psycopg.Cursor[Tuple[Any, ...]]",
),
(
- "psycopg3.connect(row_factory=rows.dict_row)",
+ "psycopg.connect(row_factory=rows.dict_row)",
"conn.cursor()",
- "psycopg3.Cursor[Dict[str, Any]]",
+ "psycopg.Cursor[Dict[str, Any]]",
),
(
- "psycopg3.connect(row_factory=rows.dict_row)",
+ "psycopg.connect(row_factory=rows.dict_row)",
"conn.cursor(row_factory=rows.namedtuple_row)",
- "psycopg3.Cursor[NamedTuple]",
+ "psycopg.Cursor[NamedTuple]",
),
(
- "psycopg3.connect(row_factory=thing_row)",
+ "psycopg.connect(row_factory=thing_row)",
"conn.cursor()",
- "psycopg3.Cursor[Thing]",
+ "psycopg.Cursor[Thing]",
),
(
- "psycopg3.connect()",
+ "psycopg.connect()",
"conn.cursor(row_factory=thing_row)",
- "psycopg3.Cursor[Thing]",
+ "psycopg.Cursor[Thing]",
),
# Async cursors
(
- "await psycopg3.AsyncConnection.connect()",
+ "await psycopg.AsyncConnection.connect()",
"conn.cursor()",
- "psycopg3.AsyncCursor[Tuple[Any, ...]]",
+ "psycopg.AsyncCursor[Tuple[Any, ...]]",
),
(
- "await psycopg3.AsyncConnection.connect()",
+ "await psycopg.AsyncConnection.connect()",
"conn.cursor(row_factory=thing_row)",
- "psycopg3.AsyncCursor[Thing]",
+ "psycopg.AsyncCursor[Thing]",
),
# Server-side cursors
(
- "psycopg3.connect()",
+ "psycopg.connect()",
"conn.cursor(name='foo')",
- "psycopg3.ServerCursor[Tuple[Any, ...]]",
+ "psycopg.ServerCursor[Tuple[Any, ...]]",
),
(
- "psycopg3.connect(row_factory=rows.dict_row)",
+ "psycopg.connect(row_factory=rows.dict_row)",
"conn.cursor(name='foo')",
- "psycopg3.ServerCursor[Dict[str, Any]]",
+ "psycopg.ServerCursor[Dict[str, Any]]",
),
(
- "psycopg3.connect()",
+ "psycopg.connect()",
"conn.cursor(name='foo', row_factory=rows.dict_row)",
- "psycopg3.ServerCursor[Dict[str, Any]]",
+ "psycopg.ServerCursor[Dict[str, Any]]",
),
# Async server-side cursors
(
- "await psycopg3.AsyncConnection.connect()",
+ "await psycopg.AsyncConnection.connect()",
"conn.cursor(name='foo')",
- "psycopg3.AsyncServerCursor[Tuple[Any, ...]]",
+ "psycopg.AsyncServerCursor[Tuple[Any, ...]]",
),
(
- "await psycopg3.AsyncConnection.connect(row_factory=rows.dict_row)",
+ "await psycopg.AsyncConnection.connect(row_factory=rows.dict_row)",
"conn.cursor(name='foo')",
- "psycopg3.AsyncServerCursor[Dict[str, Any]]",
+ "psycopg.AsyncServerCursor[Dict[str, Any]]",
),
(
- "psycopg3.connect()",
+ "psycopg.connect()",
"conn.cursor(name='foo', row_factory=rows.dict_row)",
- "psycopg3.ServerCursor[Dict[str, Any]]",
+ "psycopg.ServerCursor[Dict[str, Any]]",
),
],
)
if server_side:
curs = curs.replace("(", "(name='foo',", 1)
stmts = f"""\
-conn = {await_} psycopg3.{conn_class}.connect()
+conn = {await_} psycopg.{conn_class}.connect()
curs = {curs}
obj = {await_} curs.fetchone()
"""
if server_side:
curs = curs.replace("(", "(name='foo',", 1)
stmts = f"""\
-conn = {await_}psycopg3.{conn_class}.connect()
+conn = {await_}psycopg.{conn_class}.connect()
curs = {curs}
{async_}for obj in curs:
pass
if server_side:
curs = curs.replace("(", "(name='foo',", 1)
stmts = f"""\
-conn = {await_} psycopg3.{conn_class}.connect()
+conn = {await_} psycopg.{conn_class}.connect()
curs = {curs}
obj = {await_} curs.{method}()
"""
src = f"""\
from typing import Any, Callable, Dict, List, NamedTuple, Optional, Sequence, Tuple
-import psycopg3
-from psycopg3 import rows
+import psycopg
+from psycopg import rows
class Thing:
def __init__(self, **kwargs: Any) -> None:
self.kwargs = kwargs
def thing_row(
- cur: psycopg3.AnyCursor[Thing],
+ cur: psycopg.AnyCursor[Thing],
) -> Callable[[Sequence[Any]], Thing]:
assert cur.description
names = [d.name for d in cur.description]
import pytest
-import psycopg3
-from psycopg3 import waiting
-from psycopg3 import generators
-from psycopg3.pq import ConnStatus, ExecStatus
+import psycopg
+from psycopg import waiting
+from psycopg import generators
+from psycopg.pq import ConnStatus, ExecStatus
skip_no_epoll = pytest.mark.skipif(
def test_wait_conn_bad(dsn):
gen = generators.connect("dbname=nosuchdb")
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
waiting.wait_conn(gen)
pgconn.send_query(b"select 1")
gen = generators.execute(pgconn)
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
waiting.wait_selector(gen, pgconn.socket)
@pytest.mark.asyncio
async def test_wait_conn_async_bad(dsn):
gen = generators.connect("dbname=nosuchdb")
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
await waiting.wait_conn_async(gen)
gen = generators.execute(pgconn)
socket = pgconn.socket
pgconn.finish()
- with pytest.raises(psycopg3.OperationalError):
+ with pytest.raises(psycopg.OperationalError):
await waiting.wait_async(gen, socket)
import pytest
-import psycopg3
-from psycopg3 import pq
-from psycopg3 import sql
-from psycopg3.oids import postgres_types as builtins
-from psycopg3.adapt import Format, Transformer
-from psycopg3.types import TypeInfo
+import psycopg
+from psycopg import pq
+from psycopg import sql
+from psycopg.oids import postgres_types as builtins
+from psycopg.adapt import Format, Transformer
+from psycopg.types import TypeInfo
tests_str = [
)
def test_bad_binary_array(input):
tx = Transformer()
- with pytest.raises(psycopg3.DataError):
+ with pytest.raises(psycopg.DataError):
tx.get_dumper(input, Format.BINARY).dump(input)
import pytest
-from psycopg3 import pq
-from psycopg3 import sql
-from psycopg3.oids import postgres_types as builtins
-from psycopg3.adapt import Transformer, Format
+from psycopg import pq
+from psycopg import sql
+from psycopg.oids import postgres_types as builtins
+from psycopg.adapt import Transformer, Format
@pytest.mark.parametrize("fmt_in", [Format.AUTO, Format.TEXT, Format.BINARY])
import pytest
-from psycopg3 import pq
-from psycopg3.sql import Identifier
-from psycopg3.oids import postgres_types as builtins
-from psycopg3.adapt import Format, global_adapters
-from psycopg3.types.composite import CompositeInfo
+from psycopg import pq
+from psycopg.sql import Identifier
+from psycopg.oids import postgres_types as builtins
+from psycopg.adapt import Format, global_adapters
+from psycopg.types.composite import CompositeInfo
tests_str = [
import pytest
-from psycopg3 import DataError, pq, sql
-from psycopg3.adapt import Format
+from psycopg import DataError, pq, sql
+from psycopg.adapt import Format
class TestDate:
def test_infinity_date_example(self, conn):
# NOTE: this is an example in the docs. Make sure it doesn't regress when
# adding binary datetime adapters
- from psycopg3.oids import postgres_types as builtins
- from psycopg3.types.datetime import DateLoader, DateDumper
+ from psycopg.oids import postgres_types as builtins
+ from psycopg.types.datetime import DateLoader, DateDumper
class InfDateDumper(DateDumper):
def dump(self, obj):
import pytest
-import psycopg3.types
-from psycopg3 import pq
-from psycopg3 import sql
-from psycopg3.adapt import Format
-from psycopg3.types.json import Json, Jsonb, set_json_dumps, set_json_loads
+import psycopg.types
+from psycopg import pq
+from psycopg import sql
+from psycopg.adapt import Format
+from psycopg.types.json import Json, Jsonb, set_json_dumps, set_json_loads
samples = [
"null",
@pytest.mark.parametrize("fmt_in", [Format.AUTO, Format.TEXT, Format.BINARY])
@pytest.mark.parametrize("wrapper", ["Json", "Jsonb"])
def test_json_dump_customise(conn, wrapper, fmt_in):
- wrapper = getattr(psycopg3.types.json, wrapper)
+ wrapper = getattr(psycopg.types.json, wrapper)
obj = {"foo": "bar"}
cur = conn.cursor()
@pytest.mark.parametrize("wrapper", ["Json", "Jsonb"])
def test_json_dump_subclass(conn, wrapper, fmt_in):
JDumper = getattr(
- psycopg3.types.json,
+ psycopg.types.json,
f"{wrapper}{'Binary' if fmt_in != Format.TEXT else ''}Dumper",
)
- wrapper = getattr(psycopg3.types.json, wrapper)
+ wrapper = getattr(psycopg.types.json, wrapper)
class MyJsonDumper(JDumper):
def get_dumps(self):
@pytest.mark.parametrize("pgtype", ["json", "jsonb"])
def test_json_load_subclass(conn, binary, pgtype):
JLoader = getattr(
- psycopg3.types.json,
+ psycopg.types.json,
f"{pgtype.title()}{'Binary' if binary else ''}Loader",
)
import pytest
-from psycopg3 import pq
-from psycopg3 import sql
-from psycopg3.adapt import Format
+from psycopg import pq
+from psycopg import sql
+from psycopg.adapt import Format
@pytest.mark.parametrize("fmt_in", [Format.AUTO, Format.TEXT, Format.BINARY])
def test_lazy_load(dsn):
script = f"""\
import sys
-import psycopg3
+import psycopg
# In 3.6 it seems already loaded (at least on Travis).
if sys.version_info >= (3, 7):
assert 'ipaddress' not in sys.modules
-conn = psycopg3.connect({dsn!r})
+conn = psycopg.connect({dsn!r})
with conn.cursor() as cur:
cur.execute("select '127.0.0.1'::inet")
cur.fetchone()
-from psycopg3 import sql
-from psycopg3.adapt import Transformer, Format
+from psycopg import sql
+from psycopg.adapt import Transformer, Format
def test_quote_none(conn):
import pytest
-from psycopg3 import pq
-from psycopg3 import sql
-from psycopg3.adapt import Transformer, Format
-from psycopg3.types.numeric import FloatLoader
+from psycopg import pq
+from psycopg import sql
+from psycopg.adapt import Transformer, Format
+from psycopg.types.numeric import FloatLoader
#
import pytest
-import psycopg3.errors
-from psycopg3 import pq
-from psycopg3.sql import Identifier
-from psycopg3.adapt import Format
-from psycopg3.types.range import Range, RangeInfo
+import psycopg.errors
+from psycopg import pq
+from psycopg.sql import Identifier
+from psycopg.adapt import Format
+from psycopg.types.range import Range, RangeInfo
type2sub = {
f"copy copyrange (r) from stdin (format {format.name})"
) as copy:
copy.write_row([r])
- except psycopg3.errors.ProtocolViolation:
+ except psycopg.errors.ProtocolViolation:
if not min and not max and format == pq.Format.BINARY:
pytest.xfail(
"TODO: add annotation to dump array with no type info"
)
@pytest.mark.parametrize("format", [pq.Format.TEXT, pq.Format.BINARY])
def test_copy_in_empty_wrappers(conn, bounds, wrapper, format):
- from psycopg3.types import range as range_module
+ from psycopg.types import range as range_module
cur = conn.cursor()
cur.execute("create table copyrange (id serial primary key, r daterange)")
import pytest
-import psycopg3
-from psycopg3 import pq
-from psycopg3 import sql
-from psycopg3.adapt import Format
-from psycopg3 import Binary
+import psycopg
+from psycopg import pq
+from psycopg import sql
+from psycopg.adapt import Format
+from psycopg import Binary
eur = "\u20ac"
def test_dump_zero(conn, fmt_in):
cur = conn.cursor()
s = "foo\x00bar"
- with pytest.raises(psycopg3.DataError):
+ with pytest.raises(psycopg.DataError):
cur.execute(f"select %{fmt_in}::text", (s,))
def test_quote_zero(conn):
cur = conn.cursor()
s = "foo\x00bar"
- with pytest.raises(psycopg3.DataError):
+ with pytest.raises(psycopg.DataError):
cur.execute(sql.SQL("select {}").format(sql.Literal(s)))
cur = conn.cursor(binary=fmt_out)
conn.client_encoding = "latin1"
- with pytest.raises(psycopg3.DataError):
+ with pytest.raises(psycopg.DataError):
cur.execute(f"select chr(%s::int)::{typename}", (ord(eur),))
stmt = sql.SQL("copy (select chr({}::int)) to stdout (format {})").format(
)
with cur.copy(stmt) as copy:
copy.set_types([typename])
- with pytest.raises(psycopg3.DataError):
+ with pytest.raises(psycopg.DataError):
copy.read_row()
import pytest
-from psycopg3 import pq
-from psycopg3 import sql
-from psycopg3.adapt import Format
+from psycopg import pq
+from psycopg import sql
+from psycopg.adapt import Format
@pytest.mark.parametrize("fmt_in", [Format.AUTO, Format.TEXT, Format.BINARY])
def test_lazy_load(dsn):
script = f"""\
import sys
-import psycopg3
+import psycopg
assert 'uuid' not in sys.modules
-conn = psycopg3.connect({dsn!r})
+conn = psycopg.connect({dsn!r})
with conn.cursor() as cur:
cur.execute("select repeat('1', 32)::uuid")
cur.fetchone()
from dataclasses import dataclass
from typing import Any, Callable, Optional, Sequence, Tuple
-from psycopg3 import AnyCursor, Connection, Cursor, ServerCursor, connect
+from psycopg import AnyCursor, Connection, Cursor, ServerCursor, connect
def int_row_factory(cursor: AnyCursor[int]) -> Callable[[Sequence[int]], int]:
#!/bin/bash
-# Script to build binary psycopg3-c package.
+# Script to build binary psycopg-c package.
# Built packages will be available in the `dist` directory.
# Copyright (C) 2020-2021 The Psycopg Team
#
# docker run --rm \
# -e PLAT=manylinux2014_x86_64 \
-# -e PSYCOPG3_TEST_DSN="host=172.17.0.1 user=piro dbname=psycopg3_test" \
-# -v `pwd`:/psycopg3 \
-# quay.io/pypa/manylinux2014_x86_64 /psycopg3/tools/build_wheels.sh
+# -e PSYCOPG_TEST_DSN="host=172.17.0.1 user=piro dbname=psycopg_test" \
+# -v `pwd`:/psycopg \
+# quay.io/pypa/manylinux2014_x86_64 /psycopg/tools/build_wheels.sh
# The version of psycopg we are building
version=$( \
- (cat psycopg3/psycopg3/psycopg3/version.py && echo "print(__version__)") \
+ (cat psycopg/psycopg/psycopg/version.py && echo "print(__version__)") \
| python)
function repair_wheel {
if ! auditwheel show "$wheel"; then
echo "Skipping non-platform wheel $wheel"
else
- auditwheel repair "$wheel" --plat "$PLAT" -w /psycopg3/dist/
+ auditwheel repair "$wheel" --plat "$PLAT" -w /psycopg/dist/
fi
}
cp -avr /usr/pgsql-13/lib/* /usr/lib/
# Patch a copy of the c package to name it -binary
-cp -r /psycopg3/psycopg3_c /psycopg3_binary
-mv /psycopg3_binary/{psycopg3_c,psycopg3_binary}/
-sed -i 's/psycopg3-c/psycopg3-binary/' /psycopg3_binary/setup.cfg
+cp -r /psycopg/psycopg_c /psycopg_binary
+mv /psycopg_binary/{psycopg_c,psycopg_binary}/
+sed -i 's/psycopg-c/psycopg-binary/' /psycopg_binary/setup.cfg
sed -i "s/__impl__[[:space:]]*=.*/__impl__ = 'binary'/" \
- /psycopg3_binary/psycopg3_binary/pq.pyx
-find /psycopg3_binary/ -name \*.pyx -or -name \*.pxd -or -name \*.py \
- | xargs sed -i 's/\bpsycopg3_c\b/psycopg3_binary/'
+ /psycopg_binary/psycopg_binary/pq.pyx
+find /psycopg_binary/ -name \*.pyx -or -name \*.pxd -or -name \*.py \
+ | xargs sed -i 's/\bpsycopg_c\b/psycopg_binary/'
# Compile wheels
for PYBIN in /opt/python/*/bin; do
if [[ $PYBIN =~ "cp35" ]]; then continue; fi
- "${PYBIN}/pip" wheel /psycopg3_binary/ --no-deps -w /tmpwheels/
+ "${PYBIN}/pip" wheel /psycopg_binary/ --no-deps -w /tmpwheels/
done
# Bundle external shared libraries into the wheels
repair_wheel "$whl"
done
-# Create a sdist package with the basic psycopg3 package in order to install
-# psycopg3[binary] with packages from a single dir.
-# While you are there, build the sdist for psycopg3-c too.
-"/opt/python/cp38-cp38/bin/python" /psycopg3/psycopg3/setup.py sdist --dist-dir /psycopg3/dist/
-"/opt/python/cp38-cp38/bin/python" /psycopg3/psycopg3_c/setup.py sdist --dist-dir /psycopg3/dist/
+# Create a sdist package with the basic psycopg package in order to install
+# psycopg[binary] with packages from a single dir.
+# While you are there, build the sdist for psycopg-c too.
+"/opt/python/cp38-cp38/bin/python" /psycopg/psycopg/setup.py sdist --dist-dir /psycopg/dist/
+"/opt/python/cp38-cp38/bin/python" /psycopg/psycopg_c/setup.py sdist --dist-dir /psycopg/dist/
# Delete the libpq to make sure the package is independent.
rm -v /usr/lib/libpq.*
# Install packages and test
for PYBIN in /opt/python/*/bin/; do
if [[ $PYBIN =~ "cp35" ]]; then continue; fi
- "${PYBIN}/pip" install psycopg3[binary,test]==$version -f /psycopg3/dist
- PSYCOPG3_IMPL=binary "${PYBIN}/pytest" /psycopg3/tests -m "not slow"
+ "${PYBIN}/pip" install psycopg[binary,test]==$version -f /psycopg/dist
+ PSYCOPG_IMPL=binary "${PYBIN}/pytest" /psycopg/tests -m "not slow"
done
from urllib.request import urlopen
from collections import defaultdict, namedtuple
-from psycopg3.errors import get_base_exception # type: ignore
+from psycopg.errors import get_base_exception # type: ignore
logger = logging.getLogger()
logging.basicConfig(
def main():
classes, errors = fetch_errors(["9.6", "10", "11", "12", "13"])
- fn = os.path.dirname(__file__) + "/../psycopg3/psycopg3/errors.py"
+ fn = os.path.dirname(__file__) + "/../psycopg/psycopg/errors.py"
update_file(fn, generate_module_data(classes, errors))
logger.info("running black on the resulting module")
def update_python_oids() -> None:
queries = [version_sql, py_types_sql, py_ranges_sql]
- fn = ROOT / "psycopg3/psycopg3/oids.py"
+ fn = ROOT / "psycopg/psycopg/oids.py"
update_file(fn, queries)
sp.check_call(["black", "-q", fn])
def update_cython_oids() -> None:
queries = [version_sql, cython_oids_sql]
- fn = ROOT / "psycopg3_c/psycopg3_c/_psycopg3/oids.pxd"
+ fn = ROOT / "psycopg/psycopg/_psycopg/oids.pxd"
update_file(fn, queries)
[testenv:docs]
commands = sphinx-build -W -T -b html docs docs/_build/html
deps =
- ./psycopg3
+ ./psycopg
-r docs/requirements.txt
skip_install = true
ignore = W503, E203
extend-exclude = .venv
per-file-ignores =
- ./psycopg3/psycopg3/__init__.py: F401
- ./psycopg3/psycopg3/types/__init__.py: F401
+ ./psycopg/psycopg/__init__.py: F401
+ ./psycopg/psycopg/types/__init__.py: F401