summaryrefslogtreecommitdiffstats
path: root/contrib/python/pg8000
diff options
context:
space:
mode:
authorAlexSm <[email protected]>2024-01-19 17:48:10 +0100
committerGitHub <[email protected]>2024-01-19 17:48:10 +0100
commit5722bbf18aa2f471fc5491834c6c877b524e8795 (patch)
tree0bfe53383cc4dc38261e3e0086af199f39777801 /contrib/python/pg8000
parent610b3da211be5d7cfd27077f22b876aedaa2dc29 (diff)
Library update 9 (#1163)
* Right libs import scripts * Library update 9 * Add contrib/libs/cxxsupp/libcxx/include/memory_resource
Diffstat (limited to 'contrib/python/pg8000')
-rw-r--r--contrib/python/pg8000/.dist-info/METADATA40
-rw-r--r--contrib/python/pg8000/README.rst38
-rw-r--r--contrib/python/pg8000/pg8000/converters.py154
-rw-r--r--contrib/python/pg8000/pg8000/core.py16
-rw-r--r--contrib/python/pg8000/ya.make2
5 files changed, 169 insertions, 81 deletions
diff --git a/contrib/python/pg8000/.dist-info/METADATA b/contrib/python/pg8000/.dist-info/METADATA
index 3511e11a2a8..93aec222db4 100644
--- a/contrib/python/pg8000/.dist-info/METADATA
+++ b/contrib/python/pg8000/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pg8000
-Version: 1.30.3
+Version: 1.30.4
Summary: PostgreSQL interface library
License: BSD 3-Clause License
Project-URL: Homepage, https://github.com/tlocke/pg8000
@@ -39,7 +39,7 @@ pg8000
pg8000 is a pure-`Python <https://www.python.org/>`_
`PostgreSQL <http://www.postgresql.org/>`_ driver that complies with
`DB-API 2.0 <http://www.python.org/dev/peps/pep-0249/>`_. It is tested on Python
-versions 3.8+, on CPython and PyPy, and PostgreSQL versions 11+. pg8000's name comes
+versions 3.8+, on CPython and PyPy, and PostgreSQL versions 12+. pg8000's name comes
from the belief that it is probably about the 8000th PostgreSQL interface for Python.
pg8000 is distributed under the BSD 3-clause license.
@@ -303,9 +303,7 @@ PostgreSQL `notices
<https://www.postgresql.org/docs/current/static/plpgsql-errors-and-messages.html>`_ are
stored in a deque called ``Connection.notices`` and added using the ``append()``
method. Similarly there are ``Connection.notifications`` for `notifications
-<https://www.postgresql.org/docs/current/static/sql-notify.html>`_ and
-``Connection.parameter_statuses`` for changes to the server configuration. Here's an
-example:
+<https://www.postgresql.org/docs/current/static/sql-notify.html>`_. Here's an example:
>>> import pg8000.native
>>>
@@ -321,6 +319,26 @@ example:
>>> con.close()
+Parameter Statuses
+``````````````````
+
+`Certain parameter values are reported by the server automatically at connection startup or whenever
+their values change
+<https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQPARAMETERSTATUS>`_ and pg8000
+stores the latest values in a dict called ``Connection.parameter_statuses``. Here's an example where
+we set the ``aplication_name`` parameter and then read it from the ``parameter_statuses``:
+
+>>> import pg8000.native
+>>>
+>>> con = pg8000.native.Connection(
+... "postgres", password="cpsnow", application_name='AGI')
+>>>
+>>> con.parameter_statuses['application_name']
+'AGI'
+>>>
+>>> con.close()
+
+
LIMIT ALL
`````````
@@ -667,7 +685,7 @@ the server:
>>>
>>> con.run("SELECT :v IS NULL", v=None)
Traceback (most recent call last):
-pg8000.exceptions.DatabaseError: {'S': 'ERROR', 'V': 'ERROR', 'C': '42P18', 'M': 'could not determine data type of parameter $1', 'F': 'postgres.c', 'L': '...', 'R': 'exec_parse_message'}
+pg8000.exceptions.DatabaseError: {'S': 'ERROR', 'V': 'ERROR', 'C': '42P18', 'M': 'could not determine data type of parameter $1', 'F': 'postgres.c', 'L': '...', 'R': '...'}
>>>
>>> con.close()
@@ -889,7 +907,7 @@ the ``replication`` keyword when creating a connection:
... 'postgres', password="cpsnow", replication="database")
>>>
>>> con.run("IDENTIFY_SYSTEM")
-[['...', 1, '0/...', 'postgres']]
+[['...', 1, '.../...', 'postgres']]
>>>
>>> con.close()
@@ -2240,6 +2258,14 @@ Run ``tox`` to make sure all tests pass, then update the release notes, then do:
Release Notes
-------------
+Version 1.30.4, 2024-01-03
+``````````````````````````
+
+- Add support for more range and multirange types.
+
+- Make the ``Connection.parameter_statuses`` property a ``dict`` rather than a ``dequeue``.
+
+
Version 1.30.3, 2023-10-31
``````````````````````````
diff --git a/contrib/python/pg8000/README.rst b/contrib/python/pg8000/README.rst
index 71e0fea7511..ad8ea650f27 100644
--- a/contrib/python/pg8000/README.rst
+++ b/contrib/python/pg8000/README.rst
@@ -11,7 +11,7 @@ pg8000
pg8000 is a pure-`Python <https://www.python.org/>`_
`PostgreSQL <http://www.postgresql.org/>`_ driver that complies with
`DB-API 2.0 <http://www.python.org/dev/peps/pep-0249/>`_. It is tested on Python
-versions 3.8+, on CPython and PyPy, and PostgreSQL versions 11+. pg8000's name comes
+versions 3.8+, on CPython and PyPy, and PostgreSQL versions 12+. pg8000's name comes
from the belief that it is probably about the 8000th PostgreSQL interface for Python.
pg8000 is distributed under the BSD 3-clause license.
@@ -275,9 +275,7 @@ PostgreSQL `notices
<https://www.postgresql.org/docs/current/static/plpgsql-errors-and-messages.html>`_ are
stored in a deque called ``Connection.notices`` and added using the ``append()``
method. Similarly there are ``Connection.notifications`` for `notifications
-<https://www.postgresql.org/docs/current/static/sql-notify.html>`_ and
-``Connection.parameter_statuses`` for changes to the server configuration. Here's an
-example:
+<https://www.postgresql.org/docs/current/static/sql-notify.html>`_. Here's an example:
>>> import pg8000.native
>>>
@@ -293,6 +291,26 @@ example:
>>> con.close()
+Parameter Statuses
+``````````````````
+
+`Certain parameter values are reported by the server automatically at connection startup or whenever
+their values change
+<https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQPARAMETERSTATUS>`_ and pg8000
+stores the latest values in a dict called ``Connection.parameter_statuses``. Here's an example where
+we set the ``aplication_name`` parameter and then read it from the ``parameter_statuses``:
+
+>>> import pg8000.native
+>>>
+>>> con = pg8000.native.Connection(
+... "postgres", password="cpsnow", application_name='AGI')
+>>>
+>>> con.parameter_statuses['application_name']
+'AGI'
+>>>
+>>> con.close()
+
+
LIMIT ALL
`````````
@@ -639,7 +657,7 @@ the server:
>>>
>>> con.run("SELECT :v IS NULL", v=None)
Traceback (most recent call last):
-pg8000.exceptions.DatabaseError: {'S': 'ERROR', 'V': 'ERROR', 'C': '42P18', 'M': 'could not determine data type of parameter $1', 'F': 'postgres.c', 'L': '...', 'R': 'exec_parse_message'}
+pg8000.exceptions.DatabaseError: {'S': 'ERROR', 'V': 'ERROR', 'C': '42P18', 'M': 'could not determine data type of parameter $1', 'F': 'postgres.c', 'L': '...', 'R': '...'}
>>>
>>> con.close()
@@ -861,7 +879,7 @@ the ``replication`` keyword when creating a connection:
... 'postgres', password="cpsnow", replication="database")
>>>
>>> con.run("IDENTIFY_SYSTEM")
-[['...', 1, '0/...', 'postgres']]
+[['...', 1, '.../...', 'postgres']]
>>>
>>> con.close()
@@ -2212,6 +2230,14 @@ Run ``tox`` to make sure all tests pass, then update the release notes, then do:
Release Notes
-------------
+Version 1.30.4, 2024-01-03
+``````````````````````````
+
+- Add support for more range and multirange types.
+
+- Make the ``Connection.parameter_statuses`` property a ``dict`` rather than a ``dequeue``.
+
+
Version 1.30.3, 2023-10-31
``````````````````````````
diff --git a/contrib/python/pg8000/pg8000/converters.py b/contrib/python/pg8000/pg8000/converters.py
index 1ce16480ee5..73392a94be6 100644
--- a/contrib/python/pg8000/pg8000/converters.py
+++ b/contrib/python/pg8000/pg8000/converters.py
@@ -40,16 +40,22 @@ CSTRING_ARRAY = 1263
DATE = 1082
DATE_ARRAY = 1182
DATEMULTIRANGE = 4535
+DATEMULTIRANGE_ARRAY = 6155
DATERANGE = 3912
+DATERANGE_ARRAY = 3913
FLOAT = 701
FLOAT_ARRAY = 1022
INET = 869
INET_ARRAY = 1041
INT2VECTOR = 22
INT4MULTIRANGE = 4451
+INT4MULTIRANGE_ARRAY = 6150
INT4RANGE = 3904
+INT4RANGE_ARRAY = 3905
INT8MULTIRANGE = 4536
+INT8MULTIRANGE_ARRAY = 6157
INT8RANGE = 3926
+INT8RANGE_ARRAY = 3927
INTEGER = 23
INTEGER_ARRAY = 1007
INTERVAL = 1186
@@ -67,7 +73,9 @@ NAME_ARRAY = 1003
NUMERIC = 1700
NUMERIC_ARRAY = 1231
NUMRANGE = 3906
+NUMRANGE_ARRAY = 3907
NUMMULTIRANGE = 4532
+NUMMULTIRANGE_ARRAY = 6151
NULLTYPE = -1
OID = 26
POINT = 600
@@ -87,9 +95,13 @@ TIMESTAMP_ARRAY = 1115
TIMESTAMPTZ = 1184
TIMESTAMPTZ_ARRAY = 1185
TSMULTIRANGE = 4533
+TSMULTIRANGE_ARRAY = 6152
TSRANGE = 3908
+TSRANGE_ARRAY = 3909
TSTZMULTIRANGE = 4534
+TSTZMULTIRANGE_ARRAY = 6153
TSTZRANGE = 3910
+TSTZRANGE_ARRAY = 3911
UNKNOWN = 705
UUID_TYPE = 2950
UUID_ARRAY = 2951
@@ -291,6 +303,65 @@ def uuid_in(data):
return UUID(data)
+def _range_in(elem_func):
+ def range_in(data):
+ if data == "empty":
+ return Range(is_empty=True)
+ else:
+ le, ue = [None if v == "" else elem_func(v) for v in data[1:-1].split(",")]
+ return Range(le, ue, bounds=f"{data[0]}{data[-1]}")
+
+ return range_in
+
+
+daterange_in = _range_in(date_in)
+int4range_in = _range_in(int)
+int8range_in = _range_in(int)
+numrange_in = _range_in(Decimal)
+
+
+def ts_in(data):
+ return timestamp_in(data[1:-1])
+
+
+def tstz_in(data):
+ return timestamptz_in(data[1:-1])
+
+
+tsrange_in = _range_in(ts_in)
+tstzrange_in = _range_in(tstz_in)
+
+
+def _multirange_in(adapter):
+ def f(data):
+ in_range = False
+ result = []
+ val = []
+ for c in data:
+ if in_range:
+ val.append(c)
+ if c in "])":
+ value = "".join(val)
+ val.clear()
+ result.append(adapter(value))
+ in_range = False
+ elif c in "[(":
+ val.append(c)
+ in_range = True
+
+ return result
+
+ return f
+
+
+datemultirange_in = _multirange_in(daterange_in)
+int4multirange_in = _multirange_in(int4range_in)
+int8multirange_in = _multirange_in(int8range_in)
+nummultirange_in = _multirange_in(numrange_in)
+tsmultirange_in = _multirange_in(tsrange_in)
+tstzmultirange_in = _multirange_in(tstzrange_in)
+
+
class ParserState(Enum):
InString = 1
InEscape = 2
@@ -353,16 +424,28 @@ bool_array_in = _array_in(bool_in)
bytes_array_in = _array_in(bytes_in)
cidr_array_in = _array_in(cidr_in)
date_array_in = _array_in(date_in)
+datemultirange_array_in = _array_in(datemultirange_in)
+daterange_array_in = _array_in(daterange_in)
inet_array_in = _array_in(inet_in)
int_array_in = _array_in(int)
+int4multirange_array_in = _array_in(int4multirange_in)
+int4range_array_in = _array_in(int4range_in)
+int8multirange_array_in = _array_in(int8multirange_in)
+int8range_array_in = _array_in(int8range_in)
interval_array_in = _array_in(interval_in)
json_array_in = _array_in(json_in)
float_array_in = _array_in(float)
numeric_array_in = _array_in(numeric_in)
+nummultirange_array_in = _array_in(nummultirange_in)
+numrange_array_in = _array_in(numrange_in)
string_array_in = _array_in(string_in)
time_array_in = _array_in(time_in)
timestamp_array_in = _array_in(timestamp_in)
timestamptz_array_in = _array_in(timestamptz_in)
+tsrange_array_in = _array_in(tsrange_in)
+tsmultirange_array_in = _array_in(tsmultirange_in)
+tstzmultirange_array_in = _array_in(tstzmultirange_in)
+tstzrange_array_in = _array_in(tstzrange_in)
uuid_array_in = _array_in(uuid_in)
@@ -443,65 +526,6 @@ def composite_out(ar):
return f'({",".join(result)})'
-def _range_in(elem_func):
- def range_in(data):
- if data == "empty":
- return Range(is_empty=True)
- else:
- le, ue = [None if v == "" else elem_func(v) for v in data[1:-1].split(",")]
- return Range(le, ue, bounds=f"{data[0]}{data[-1]}")
-
- return range_in
-
-
-daterange_in = _range_in(date_in)
-int4range_in = _range_in(int)
-int8range_in = _range_in(int)
-numrange_in = _range_in(Decimal)
-
-
-def ts_in(data):
- return timestamp_in(data[1:-1])
-
-
-def tstz_in(data):
- return timestamptz_in(data[1:-1])
-
-
-tsrange_in = _range_in(ts_in)
-tstzrange_in = _range_in(tstz_in)
-
-
-def _multirange_in(adapter):
- def f(data):
- in_range = False
- result = []
- val = []
- for c in data:
- if in_range:
- val.append(c)
- if c in "])":
- value = "".join(val)
- val.clear()
- result.append(adapter(value))
- in_range = False
- elif c in "[(":
- val.append(c)
- in_range = True
-
- return result
-
- return f
-
-
-datemultirange_in = _multirange_in(daterange_in)
-int4multirange_in = _multirange_in(int4range_in)
-int8multirange_in = _multirange_in(int8range_in)
-nummultirange_in = _multirange_in(numrange_in)
-tsmultirange_in = _multirange_in(tsrange_in)
-tstzmultirange_in = _multirange_in(tstzrange_in)
-
-
def record_in(data):
state = ParserState.Out
results = []
@@ -605,15 +629,21 @@ PG_TYPES = {
DATE: date_in, # date
DATE_ARRAY: date_array_in, # date[]
DATEMULTIRANGE: datemultirange_in, # datemultirange
+ DATEMULTIRANGE_ARRAY: datemultirange_array_in, # datemultirange[]
DATERANGE: daterange_in, # daterange
+ DATERANGE_ARRAY: daterange_array_in, # daterange[]
FLOAT: float, # float8
FLOAT_ARRAY: float_array_in, # float8[]
INET: inet_in, # inet
INET_ARRAY: inet_array_in, # inet[]
INT4MULTIRANGE: int4multirange_in, # int4multirange
+ INT4MULTIRANGE_ARRAY: int4multirange_array_in, # int4multirange[]
INT4RANGE: int4range_in, # int4range
+ INT4RANGE_ARRAY: int4range_array_in, # int4range[]
INT8MULTIRANGE: int8multirange_in, # int8multirange
+ INT8MULTIRANGE_ARRAY: int8multirange_array_in, # int8multirange[]
INT8RANGE: int8range_in, # int8range
+ INT8RANGE_ARRAY: int8range_array_in, # int8range[]
INTEGER: int, # int4
INTEGER_ARRAY: int_array_in, # int4[]
JSON: json_in, # json
@@ -628,7 +658,9 @@ PG_TYPES = {
NUMERIC: numeric_in, # numeric
NUMERIC_ARRAY: numeric_array_in, # numeric[]
NUMRANGE: numrange_in, # numrange
+ NUMRANGE_ARRAY: numrange_array_in, # numrange[]
NUMMULTIRANGE: nummultirange_in, # nummultirange
+ NUMMULTIRANGE_ARRAY: nummultirange_array_in, # nummultirange[]
OID: int, # oid
POINT: point_in, # point
INTERVAL: interval_in, # interval
@@ -649,9 +681,13 @@ PG_TYPES = {
TIMESTAMPTZ: timestamptz_in, # timestamptz
TIMESTAMPTZ_ARRAY: timestamptz_array_in, # timestamptz
TSMULTIRANGE: tsmultirange_in, # tsmultirange
+ TSMULTIRANGE_ARRAY: tsmultirange_array_in, # tsmultirange[]
TSRANGE: tsrange_in, # tsrange
+ TSRANGE_ARRAY: tsrange_array_in, # tsrange[]
TSTZMULTIRANGE: tstzmultirange_in, # tstzmultirange
+ TSTZMULTIRANGE_ARRAY: tstzmultirange_array_in, # tstzmultirange[]
TSTZRANGE: tstzrange_in, # tstzrange
+ TSTZRANGE_ARRAY: tstzrange_array_in, # tstzrange[]
UNKNOWN: string_in, # unknown
UUID_ARRAY: uuid_array_in, # uuid[]
UUID_TYPE: uuid_in, # uuid
diff --git a/contrib/python/pg8000/pg8000/core.py b/contrib/python/pg8000/pg8000/core.py
index 54ef496ddd9..3e55957755a 100644
--- a/contrib/python/pg8000/pg8000/core.py
+++ b/contrib/python/pg8000/pg8000/core.py
@@ -277,7 +277,7 @@ class CoreConnection:
)
self.notifications = deque(maxlen=100)
self.notices = deque(maxlen=100)
- self.parameter_statuses = deque(maxlen=100)
+ self.parameter_statuses = {}
if user is None:
raise InterfaceError("The 'user' connection parameter cannot be None")
@@ -842,20 +842,20 @@ class CoreConnection:
def handle_PARAMETER_STATUS(self, data, context):
pos = data.find(NULL_BYTE)
- key, value = data[:pos], data[pos + 1 : -1]
- self.parameter_statuses.append((key, value))
- if key == b"client_encoding":
- encoding = value.decode("ascii").lower()
+ key, value = data[:pos].decode("ascii"), data[pos + 1 : -1].decode("ascii")
+ self.parameter_statuses[key] = value
+ if key == "client_encoding":
+ encoding = value.lower()
self._client_encoding = PG_PY_ENCODINGS.get(encoding, encoding)
- elif key == b"integer_datetimes":
- if value == b"on":
+ elif key == "integer_datetimes":
+ if value == "on":
pass
else:
pass
- elif key == b"server_version":
+ elif key == "server_version":
pass
diff --git a/contrib/python/pg8000/ya.make b/contrib/python/pg8000/ya.make
index 6172a193123..50676227044 100644
--- a/contrib/python/pg8000/ya.make
+++ b/contrib/python/pg8000/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(1.30.3)
+VERSION(1.30.4)
LICENSE(BSD-3-Clause)