diff options
| author | AlexSm <[email protected]> | 2024-01-19 17:48:10 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-01-19 17:48:10 +0100 |
| commit | 5722bbf18aa2f471fc5491834c6c877b524e8795 (patch) | |
| tree | 0bfe53383cc4dc38261e3e0086af199f39777801 /contrib/python/pg8000 | |
| parent | 610b3da211be5d7cfd27077f22b876aedaa2dc29 (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/METADATA | 40 | ||||
| -rw-r--r-- | contrib/python/pg8000/README.rst | 38 | ||||
| -rw-r--r-- | contrib/python/pg8000/pg8000/converters.py | 154 | ||||
| -rw-r--r-- | contrib/python/pg8000/pg8000/core.py | 16 | ||||
| -rw-r--r-- | contrib/python/pg8000/ya.make | 2 |
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) |
