aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs')
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/__init__.pxd157
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/bits.pyx47
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/bytea.pyx34
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/context.pyx26
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/datetime.pyx423
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/float.pyx34
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/geometry.pyx164
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/hstore.pyx73
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/int.pyx144
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/json.pyx57
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/jsonpath.pyx29
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/misc.pyx16
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/network.pyx139
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/numeric.pyx356
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/pg_snapshot.pyx63
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/text.pyx48
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/tid.pyx51
-rw-r--r--.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/uuid.pyx27
18 files changed, 1888 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/__init__.pxd b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/__init__.pxd
new file mode 100644
index 00000000..2dbcbd3c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/__init__.pxd
@@ -0,0 +1,157 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef class CodecContext:
+
+ cpdef get_text_codec(self)
+ cdef is_encoding_utf8(self)
+ cpdef get_json_decoder(self)
+ cdef is_decoding_json(self)
+ cpdef get_json_encoder(self)
+ cdef is_encoding_json(self)
+
+
+ctypedef object (*encode_func)(CodecContext settings,
+ WriteBuffer buf,
+ object obj)
+
+ctypedef object (*decode_func)(CodecContext settings,
+ FRBuffer *buf)
+
+
+# Datetime
+cdef date_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef date_decode(CodecContext settings, FRBuffer * buf)
+cdef date_encode_tuple(CodecContext settings, WriteBuffer buf, obj)
+cdef date_decode_tuple(CodecContext settings, FRBuffer * buf)
+cdef timestamp_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef timestamp_decode(CodecContext settings, FRBuffer * buf)
+cdef timestamp_encode_tuple(CodecContext settings, WriteBuffer buf, obj)
+cdef timestamp_decode_tuple(CodecContext settings, FRBuffer * buf)
+cdef timestamptz_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef timestamptz_decode(CodecContext settings, FRBuffer * buf)
+cdef time_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef time_decode(CodecContext settings, FRBuffer * buf)
+cdef time_encode_tuple(CodecContext settings, WriteBuffer buf, obj)
+cdef time_decode_tuple(CodecContext settings, FRBuffer * buf)
+cdef timetz_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef timetz_decode(CodecContext settings, FRBuffer * buf)
+cdef timetz_encode_tuple(CodecContext settings, WriteBuffer buf, obj)
+cdef timetz_decode_tuple(CodecContext settings, FRBuffer * buf)
+cdef interval_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef interval_decode(CodecContext settings, FRBuffer * buf)
+cdef interval_encode_tuple(CodecContext settings, WriteBuffer buf, tuple obj)
+cdef interval_decode_tuple(CodecContext settings, FRBuffer * buf)
+
+
+# Bits
+cdef bits_encode(CodecContext settings, WriteBuffer wbuf, obj)
+cdef bits_decode(CodecContext settings, FRBuffer * buf)
+
+
+# Bools
+cdef bool_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef bool_decode(CodecContext settings, FRBuffer * buf)
+
+
+# Geometry
+cdef box_encode(CodecContext settings, WriteBuffer wbuf, obj)
+cdef box_decode(CodecContext settings, FRBuffer * buf)
+cdef line_encode(CodecContext settings, WriteBuffer wbuf, obj)
+cdef line_decode(CodecContext settings, FRBuffer * buf)
+cdef lseg_encode(CodecContext settings, WriteBuffer wbuf, obj)
+cdef lseg_decode(CodecContext settings, FRBuffer * buf)
+cdef point_encode(CodecContext settings, WriteBuffer wbuf, obj)
+cdef point_decode(CodecContext settings, FRBuffer * buf)
+cdef path_encode(CodecContext settings, WriteBuffer wbuf, obj)
+cdef path_decode(CodecContext settings, FRBuffer * buf)
+cdef poly_encode(CodecContext settings, WriteBuffer wbuf, obj)
+cdef poly_decode(CodecContext settings, FRBuffer * buf)
+cdef circle_encode(CodecContext settings, WriteBuffer wbuf, obj)
+cdef circle_decode(CodecContext settings, FRBuffer * buf)
+
+
+# Hstore
+cdef hstore_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef hstore_decode(CodecContext settings, FRBuffer * buf)
+
+
+# Ints
+cdef int2_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef int2_decode(CodecContext settings, FRBuffer * buf)
+cdef int4_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef int4_decode(CodecContext settings, FRBuffer * buf)
+cdef uint4_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef uint4_decode(CodecContext settings, FRBuffer * buf)
+cdef int8_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef int8_decode(CodecContext settings, FRBuffer * buf)
+cdef uint8_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef uint8_decode(CodecContext settings, FRBuffer * buf)
+
+
+# Floats
+cdef float4_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef float4_decode(CodecContext settings, FRBuffer * buf)
+cdef float8_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef float8_decode(CodecContext settings, FRBuffer * buf)
+
+
+# JSON
+cdef jsonb_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef jsonb_decode(CodecContext settings, FRBuffer * buf)
+
+
+# JSON path
+cdef jsonpath_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef jsonpath_decode(CodecContext settings, FRBuffer * buf)
+
+
+# Text
+cdef as_pg_string_and_size(
+ CodecContext settings, obj, char **cstr, ssize_t *size)
+cdef text_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef text_decode(CodecContext settings, FRBuffer * buf)
+
+# Bytea
+cdef bytea_encode(CodecContext settings, WriteBuffer wbuf, obj)
+cdef bytea_decode(CodecContext settings, FRBuffer * buf)
+
+
+# UUID
+cdef uuid_encode(CodecContext settings, WriteBuffer wbuf, obj)
+cdef uuid_decode(CodecContext settings, FRBuffer * buf)
+
+
+# Numeric
+cdef numeric_encode_text(CodecContext settings, WriteBuffer buf, obj)
+cdef numeric_decode_text(CodecContext settings, FRBuffer * buf)
+cdef numeric_encode_binary(CodecContext settings, WriteBuffer buf, obj)
+cdef numeric_decode_binary(CodecContext settings, FRBuffer * buf)
+cdef numeric_decode_binary_ex(CodecContext settings, FRBuffer * buf,
+ bint trail_fract_zero)
+
+
+# Void
+cdef void_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef void_decode(CodecContext settings, FRBuffer * buf)
+
+
+# tid
+cdef tid_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef tid_decode(CodecContext settings, FRBuffer * buf)
+
+
+# Network
+cdef cidr_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef cidr_decode(CodecContext settings, FRBuffer * buf)
+cdef inet_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef inet_decode(CodecContext settings, FRBuffer * buf)
+
+
+# pg_snapshot
+cdef pg_snapshot_encode(CodecContext settings, WriteBuffer buf, obj)
+cdef pg_snapshot_decode(CodecContext settings, FRBuffer * buf)
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/bits.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/bits.pyx
new file mode 100644
index 00000000..14f7bb0b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/bits.pyx
@@ -0,0 +1,47 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef bits_encode(CodecContext settings, WriteBuffer wbuf, obj):
+ cdef:
+ Py_buffer pybuf
+ bint pybuf_used = False
+ char *buf
+ ssize_t len
+ ssize_t bitlen
+
+ if cpython.PyBytes_CheckExact(obj):
+ buf = cpython.PyBytes_AS_STRING(obj)
+ len = cpython.Py_SIZE(obj)
+ bitlen = len * 8
+ elif isinstance(obj, pgproto_types.BitString):
+ cpython.PyBytes_AsStringAndSize(obj.bytes, &buf, &len)
+ bitlen = obj.__len__()
+ else:
+ cpython.PyObject_GetBuffer(obj, &pybuf, cpython.PyBUF_SIMPLE)
+ pybuf_used = True
+ buf = <char*>pybuf.buf
+ len = pybuf.len
+ bitlen = len * 8
+
+ try:
+ if bitlen > _MAXINT32:
+ raise ValueError('bit value too long')
+ wbuf.write_int32(4 + <int32_t>len)
+ wbuf.write_int32(<int32_t>bitlen)
+ wbuf.write_cstr(buf, len)
+ finally:
+ if pybuf_used:
+ cpython.PyBuffer_Release(&pybuf)
+
+
+cdef bits_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ int32_t bitlen = hton.unpack_int32(frb_read(buf, 4))
+ ssize_t buf_len = buf.len
+
+ bytes_ = cpython.PyBytes_FromStringAndSize(frb_read_all(buf), buf_len)
+ return pgproto_types.BitString.frombytes(bytes_, bitlen)
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/bytea.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/bytea.pyx
new file mode 100644
index 00000000..15818258
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/bytea.pyx
@@ -0,0 +1,34 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef bytea_encode(CodecContext settings, WriteBuffer wbuf, obj):
+ cdef:
+ Py_buffer pybuf
+ bint pybuf_used = False
+ char *buf
+ ssize_t len
+
+ if cpython.PyBytes_CheckExact(obj):
+ buf = cpython.PyBytes_AS_STRING(obj)
+ len = cpython.Py_SIZE(obj)
+ else:
+ cpython.PyObject_GetBuffer(obj, &pybuf, cpython.PyBUF_SIMPLE)
+ pybuf_used = True
+ buf = <char*>pybuf.buf
+ len = pybuf.len
+
+ try:
+ wbuf.write_int32(<int32_t>len)
+ wbuf.write_cstr(buf, len)
+ finally:
+ if pybuf_used:
+ cpython.PyBuffer_Release(&pybuf)
+
+
+cdef bytea_decode(CodecContext settings, FRBuffer *buf):
+ cdef ssize_t buf_len = buf.len
+ return cpython.PyBytes_FromStringAndSize(frb_read_all(buf), buf_len)
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/context.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/context.pyx
new file mode 100644
index 00000000..c4d4416e
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/context.pyx
@@ -0,0 +1,26 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef class CodecContext:
+
+ cpdef get_text_codec(self):
+ raise NotImplementedError
+
+ cdef is_encoding_utf8(self):
+ raise NotImplementedError
+
+ cpdef get_json_decoder(self):
+ raise NotImplementedError
+
+ cdef is_decoding_json(self):
+ return False
+
+ cpdef get_json_encoder(self):
+ raise NotImplementedError
+
+ cdef is_encoding_json(self):
+ return False
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/datetime.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/datetime.pyx
new file mode 100644
index 00000000..bed0b9e9
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/datetime.pyx
@@ -0,0 +1,423 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cimport cpython.datetime
+import datetime
+
+cpython.datetime.import_datetime()
+
+utc = datetime.timezone.utc
+date_from_ordinal = datetime.date.fromordinal
+timedelta = datetime.timedelta
+
+pg_epoch_datetime = datetime.datetime(2000, 1, 1)
+cdef int32_t pg_epoch_datetime_ts = \
+ <int32_t>cpython.PyLong_AsLong(int(pg_epoch_datetime.timestamp()))
+
+pg_epoch_datetime_utc = datetime.datetime(2000, 1, 1, tzinfo=utc)
+cdef int32_t pg_epoch_datetime_utc_ts = \
+ <int32_t>cpython.PyLong_AsLong(int(pg_epoch_datetime_utc.timestamp()))
+
+pg_epoch_date = datetime.date(2000, 1, 1)
+cdef int32_t pg_date_offset_ord = \
+ <int32_t>cpython.PyLong_AsLong(pg_epoch_date.toordinal())
+
+# Binary representations of infinity for datetimes.
+cdef int64_t pg_time64_infinity = 0x7fffffffffffffff
+cdef int64_t pg_time64_negative_infinity = <int64_t>0x8000000000000000
+cdef int32_t pg_date_infinity = 0x7fffffff
+cdef int32_t pg_date_negative_infinity = <int32_t>0x80000000
+
+infinity_datetime = datetime.datetime(
+ datetime.MAXYEAR, 12, 31, 23, 59, 59, 999999)
+
+cdef int32_t infinity_datetime_ord = <int32_t>cpython.PyLong_AsLong(
+ infinity_datetime.toordinal())
+
+cdef int64_t infinity_datetime_ts = 252455615999999999
+
+negative_infinity_datetime = datetime.datetime(
+ datetime.MINYEAR, 1, 1, 0, 0, 0, 0)
+
+cdef int32_t negative_infinity_datetime_ord = <int32_t>cpython.PyLong_AsLong(
+ negative_infinity_datetime.toordinal())
+
+cdef int64_t negative_infinity_datetime_ts = -63082281600000000
+
+infinity_date = datetime.date(datetime.MAXYEAR, 12, 31)
+
+cdef int32_t infinity_date_ord = <int32_t>cpython.PyLong_AsLong(
+ infinity_date.toordinal())
+
+negative_infinity_date = datetime.date(datetime.MINYEAR, 1, 1)
+
+cdef int32_t negative_infinity_date_ord = <int32_t>cpython.PyLong_AsLong(
+ negative_infinity_date.toordinal())
+
+
+cdef inline _local_timezone():
+ d = datetime.datetime.now(datetime.timezone.utc).astimezone()
+ return datetime.timezone(d.utcoffset())
+
+
+cdef inline _encode_time(WriteBuffer buf, int64_t seconds,
+ int32_t microseconds):
+ # XXX: add support for double timestamps
+ # int64 timestamps,
+ cdef int64_t ts = seconds * 1000000 + microseconds
+
+ if ts == infinity_datetime_ts:
+ buf.write_int64(pg_time64_infinity)
+ elif ts == negative_infinity_datetime_ts:
+ buf.write_int64(pg_time64_negative_infinity)
+ else:
+ buf.write_int64(ts)
+
+
+cdef inline int32_t _decode_time(FRBuffer *buf, int64_t *seconds,
+ int32_t *microseconds):
+ cdef int64_t ts = hton.unpack_int64(frb_read(buf, 8))
+
+ if ts == pg_time64_infinity:
+ return 1
+ elif ts == pg_time64_negative_infinity:
+ return -1
+ else:
+ seconds[0] = ts // 1000000
+ microseconds[0] = <int32_t>(ts % 1000000)
+ return 0
+
+
+cdef date_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ int32_t ordinal = <int32_t>cpython.PyLong_AsLong(obj.toordinal())
+ int32_t pg_ordinal
+
+ if ordinal == infinity_date_ord:
+ pg_ordinal = pg_date_infinity
+ elif ordinal == negative_infinity_date_ord:
+ pg_ordinal = pg_date_negative_infinity
+ else:
+ pg_ordinal = ordinal - pg_date_offset_ord
+
+ buf.write_int32(4)
+ buf.write_int32(pg_ordinal)
+
+
+cdef date_encode_tuple(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ int32_t pg_ordinal
+
+ if len(obj) != 1:
+ raise ValueError(
+ 'date tuple encoder: expecting 1 element '
+ 'in tuple, got {}'.format(len(obj)))
+
+ pg_ordinal = obj[0]
+ buf.write_int32(4)
+ buf.write_int32(pg_ordinal)
+
+
+cdef date_decode(CodecContext settings, FRBuffer *buf):
+ cdef int32_t pg_ordinal = hton.unpack_int32(frb_read(buf, 4))
+
+ if pg_ordinal == pg_date_infinity:
+ return infinity_date
+ elif pg_ordinal == pg_date_negative_infinity:
+ return negative_infinity_date
+ else:
+ return date_from_ordinal(pg_ordinal + pg_date_offset_ord)
+
+
+cdef date_decode_tuple(CodecContext settings, FRBuffer *buf):
+ cdef int32_t pg_ordinal = hton.unpack_int32(frb_read(buf, 4))
+
+ return (pg_ordinal,)
+
+
+cdef timestamp_encode(CodecContext settings, WriteBuffer buf, obj):
+ if not cpython.datetime.PyDateTime_Check(obj):
+ if cpython.datetime.PyDate_Check(obj):
+ obj = datetime.datetime(obj.year, obj.month, obj.day)
+ else:
+ raise TypeError(
+ 'expected a datetime.date or datetime.datetime instance, '
+ 'got {!r}'.format(type(obj).__name__)
+ )
+
+ delta = obj - pg_epoch_datetime
+ cdef:
+ int64_t seconds = cpython.PyLong_AsLongLong(delta.days) * 86400 + \
+ cpython.PyLong_AsLong(delta.seconds)
+ int32_t microseconds = <int32_t>cpython.PyLong_AsLong(
+ delta.microseconds)
+
+ buf.write_int32(8)
+ _encode_time(buf, seconds, microseconds)
+
+
+cdef timestamp_encode_tuple(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ int64_t microseconds
+
+ if len(obj) != 1:
+ raise ValueError(
+ 'timestamp tuple encoder: expecting 1 element '
+ 'in tuple, got {}'.format(len(obj)))
+
+ microseconds = obj[0]
+
+ buf.write_int32(8)
+ buf.write_int64(microseconds)
+
+
+cdef timestamp_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ int64_t seconds = 0
+ int32_t microseconds = 0
+ int32_t inf = _decode_time(buf, &seconds, &microseconds)
+
+ if inf > 0:
+ # positive infinity
+ return infinity_datetime
+ elif inf < 0:
+ # negative infinity
+ return negative_infinity_datetime
+ else:
+ return pg_epoch_datetime.__add__(
+ timedelta(0, seconds, microseconds))
+
+
+cdef timestamp_decode_tuple(CodecContext settings, FRBuffer *buf):
+ cdef:
+ int64_t ts = hton.unpack_int64(frb_read(buf, 8))
+
+ return (ts,)
+
+
+cdef timestamptz_encode(CodecContext settings, WriteBuffer buf, obj):
+ if not cpython.datetime.PyDateTime_Check(obj):
+ if cpython.datetime.PyDate_Check(obj):
+ obj = datetime.datetime(obj.year, obj.month, obj.day,
+ tzinfo=_local_timezone())
+ else:
+ raise TypeError(
+ 'expected a datetime.date or datetime.datetime instance, '
+ 'got {!r}'.format(type(obj).__name__)
+ )
+
+ buf.write_int32(8)
+
+ if obj == infinity_datetime:
+ buf.write_int64(pg_time64_infinity)
+ return
+ elif obj == negative_infinity_datetime:
+ buf.write_int64(pg_time64_negative_infinity)
+ return
+
+ utc_dt = obj.astimezone(utc)
+
+ delta = utc_dt - pg_epoch_datetime_utc
+ cdef:
+ int64_t seconds = cpython.PyLong_AsLongLong(delta.days) * 86400 + \
+ cpython.PyLong_AsLong(delta.seconds)
+ int32_t microseconds = <int32_t>cpython.PyLong_AsLong(
+ delta.microseconds)
+
+ _encode_time(buf, seconds, microseconds)
+
+
+cdef timestamptz_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ int64_t seconds = 0
+ int32_t microseconds = 0
+ int32_t inf = _decode_time(buf, &seconds, &microseconds)
+
+ if inf > 0:
+ # positive infinity
+ return infinity_datetime
+ elif inf < 0:
+ # negative infinity
+ return negative_infinity_datetime
+ else:
+ return pg_epoch_datetime_utc.__add__(
+ timedelta(0, seconds, microseconds))
+
+
+cdef time_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ int64_t seconds = cpython.PyLong_AsLong(obj.hour) * 3600 + \
+ cpython.PyLong_AsLong(obj.minute) * 60 + \
+ cpython.PyLong_AsLong(obj.second)
+ int32_t microseconds = <int32_t>cpython.PyLong_AsLong(obj.microsecond)
+
+ buf.write_int32(8)
+ _encode_time(buf, seconds, microseconds)
+
+
+cdef time_encode_tuple(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ int64_t microseconds
+
+ if len(obj) != 1:
+ raise ValueError(
+ 'time tuple encoder: expecting 1 element '
+ 'in tuple, got {}'.format(len(obj)))
+
+ microseconds = obj[0]
+
+ buf.write_int32(8)
+ buf.write_int64(microseconds)
+
+
+cdef time_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ int64_t seconds = 0
+ int32_t microseconds = 0
+
+ _decode_time(buf, &seconds, &microseconds)
+
+ cdef:
+ int64_t minutes = <int64_t>(seconds / 60)
+ int64_t sec = seconds % 60
+ int64_t hours = <int64_t>(minutes / 60)
+ int64_t min = minutes % 60
+
+ return datetime.time(hours, min, sec, microseconds)
+
+
+cdef time_decode_tuple(CodecContext settings, FRBuffer *buf):
+ cdef:
+ int64_t ts = hton.unpack_int64(frb_read(buf, 8))
+
+ return (ts,)
+
+
+cdef timetz_encode(CodecContext settings, WriteBuffer buf, obj):
+ offset = obj.tzinfo.utcoffset(None)
+
+ cdef:
+ int32_t offset_sec = \
+ <int32_t>cpython.PyLong_AsLong(offset.days) * 24 * 60 * 60 + \
+ <int32_t>cpython.PyLong_AsLong(offset.seconds)
+
+ int64_t seconds = cpython.PyLong_AsLong(obj.hour) * 3600 + \
+ cpython.PyLong_AsLong(obj.minute) * 60 + \
+ cpython.PyLong_AsLong(obj.second)
+
+ int32_t microseconds = <int32_t>cpython.PyLong_AsLong(obj.microsecond)
+
+ buf.write_int32(12)
+ _encode_time(buf, seconds, microseconds)
+ # In Python utcoffset() is the difference between the local time
+ # and the UTC, whereas in PostgreSQL it's the opposite,
+ # so we need to flip the sign.
+ buf.write_int32(-offset_sec)
+
+
+cdef timetz_encode_tuple(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ int64_t microseconds
+ int32_t offset_sec
+
+ if len(obj) != 2:
+ raise ValueError(
+ 'time tuple encoder: expecting 2 elements2 '
+ 'in tuple, got {}'.format(len(obj)))
+
+ microseconds = obj[0]
+ offset_sec = obj[1]
+
+ buf.write_int32(12)
+ buf.write_int64(microseconds)
+ buf.write_int32(offset_sec)
+
+
+cdef timetz_decode(CodecContext settings, FRBuffer *buf):
+ time = time_decode(settings, buf)
+ cdef int32_t offset = <int32_t>(hton.unpack_int32(frb_read(buf, 4)) / 60)
+ # See the comment in the `timetz_encode` method.
+ return time.replace(tzinfo=datetime.timezone(timedelta(minutes=-offset)))
+
+
+cdef timetz_decode_tuple(CodecContext settings, FRBuffer *buf):
+ cdef:
+ int64_t microseconds = hton.unpack_int64(frb_read(buf, 8))
+ int32_t offset_sec = hton.unpack_int32(frb_read(buf, 4))
+
+ return (microseconds, offset_sec)
+
+
+cdef interval_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ int32_t days = <int32_t>cpython.PyLong_AsLong(obj.days)
+ int64_t seconds = cpython.PyLong_AsLongLong(obj.seconds)
+ int32_t microseconds = <int32_t>cpython.PyLong_AsLong(obj.microseconds)
+
+ buf.write_int32(16)
+ _encode_time(buf, seconds, microseconds)
+ buf.write_int32(days)
+ buf.write_int32(0) # Months
+
+
+cdef interval_encode_tuple(CodecContext settings, WriteBuffer buf,
+ tuple obj):
+ cdef:
+ int32_t months
+ int32_t days
+ int64_t microseconds
+
+ if len(obj) != 3:
+ raise ValueError(
+ 'interval tuple encoder: expecting 3 elements '
+ 'in tuple, got {}'.format(len(obj)))
+
+ months = obj[0]
+ days = obj[1]
+ microseconds = obj[2]
+
+ buf.write_int32(16)
+ buf.write_int64(microseconds)
+ buf.write_int32(days)
+ buf.write_int32(months)
+
+
+cdef interval_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ int32_t days
+ int32_t months
+ int32_t years
+ int64_t seconds = 0
+ int32_t microseconds = 0
+
+ _decode_time(buf, &seconds, &microseconds)
+
+ days = hton.unpack_int32(frb_read(buf, 4))
+ months = hton.unpack_int32(frb_read(buf, 4))
+
+ if months < 0:
+ years = -<int32_t>(-months // 12)
+ months = -<int32_t>(-months % 12)
+ else:
+ years = <int32_t>(months // 12)
+ months = <int32_t>(months % 12)
+
+ return datetime.timedelta(days=days + months * 30 + years * 365,
+ seconds=seconds, microseconds=microseconds)
+
+
+cdef interval_decode_tuple(CodecContext settings, FRBuffer *buf):
+ cdef:
+ int32_t days
+ int32_t months
+ int64_t microseconds
+
+ microseconds = hton.unpack_int64(frb_read(buf, 8))
+ days = hton.unpack_int32(frb_read(buf, 4))
+ months = hton.unpack_int32(frb_read(buf, 4))
+
+ return (months, days, microseconds)
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/float.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/float.pyx
new file mode 100644
index 00000000..94eda03a
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/float.pyx
@@ -0,0 +1,34 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+from libc cimport math
+
+
+cdef float4_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef double dval = cpython.PyFloat_AsDouble(obj)
+ cdef float fval = <float>dval
+ if math.isinf(fval) and not math.isinf(dval):
+ raise ValueError('value out of float32 range')
+
+ buf.write_int32(4)
+ buf.write_float(fval)
+
+
+cdef float4_decode(CodecContext settings, FRBuffer *buf):
+ cdef float f = hton.unpack_float(frb_read(buf, 4))
+ return cpython.PyFloat_FromDouble(f)
+
+
+cdef float8_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef double dval = cpython.PyFloat_AsDouble(obj)
+ buf.write_int32(8)
+ buf.write_double(dval)
+
+
+cdef float8_decode(CodecContext settings, FRBuffer *buf):
+ cdef double f = hton.unpack_double(frb_read(buf, 8))
+ return cpython.PyFloat_FromDouble(f)
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/geometry.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/geometry.pyx
new file mode 100644
index 00000000..44aac64b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/geometry.pyx
@@ -0,0 +1,164 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef inline _encode_points(WriteBuffer wbuf, object points):
+ cdef object point
+
+ for point in points:
+ wbuf.write_double(point[0])
+ wbuf.write_double(point[1])
+
+
+cdef inline _decode_points(FRBuffer *buf):
+ cdef:
+ int32_t npts = hton.unpack_int32(frb_read(buf, 4))
+ pts = cpython.PyTuple_New(npts)
+ int32_t i
+ object point
+ double x
+ double y
+
+ for i in range(npts):
+ x = hton.unpack_double(frb_read(buf, 8))
+ y = hton.unpack_double(frb_read(buf, 8))
+ point = pgproto_types.Point(x, y)
+ cpython.Py_INCREF(point)
+ cpython.PyTuple_SET_ITEM(pts, i, point)
+
+ return pts
+
+
+cdef box_encode(CodecContext settings, WriteBuffer wbuf, obj):
+ wbuf.write_int32(32)
+ _encode_points(wbuf, (obj[0], obj[1]))
+
+
+cdef box_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ double high_x = hton.unpack_double(frb_read(buf, 8))
+ double high_y = hton.unpack_double(frb_read(buf, 8))
+ double low_x = hton.unpack_double(frb_read(buf, 8))
+ double low_y = hton.unpack_double(frb_read(buf, 8))
+
+ return pgproto_types.Box(
+ pgproto_types.Point(high_x, high_y),
+ pgproto_types.Point(low_x, low_y))
+
+
+cdef line_encode(CodecContext settings, WriteBuffer wbuf, obj):
+ wbuf.write_int32(24)
+ wbuf.write_double(obj[0])
+ wbuf.write_double(obj[1])
+ wbuf.write_double(obj[2])
+
+
+cdef line_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ double A = hton.unpack_double(frb_read(buf, 8))
+ double B = hton.unpack_double(frb_read(buf, 8))
+ double C = hton.unpack_double(frb_read(buf, 8))
+
+ return pgproto_types.Line(A, B, C)
+
+
+cdef lseg_encode(CodecContext settings, WriteBuffer wbuf, obj):
+ wbuf.write_int32(32)
+ _encode_points(wbuf, (obj[0], obj[1]))
+
+
+cdef lseg_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ double p1_x = hton.unpack_double(frb_read(buf, 8))
+ double p1_y = hton.unpack_double(frb_read(buf, 8))
+ double p2_x = hton.unpack_double(frb_read(buf, 8))
+ double p2_y = hton.unpack_double(frb_read(buf, 8))
+
+ return pgproto_types.LineSegment((p1_x, p1_y), (p2_x, p2_y))
+
+
+cdef point_encode(CodecContext settings, WriteBuffer wbuf, obj):
+ wbuf.write_int32(16)
+ wbuf.write_double(obj[0])
+ wbuf.write_double(obj[1])
+
+
+cdef point_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ double x = hton.unpack_double(frb_read(buf, 8))
+ double y = hton.unpack_double(frb_read(buf, 8))
+
+ return pgproto_types.Point(x, y)
+
+
+cdef path_encode(CodecContext settings, WriteBuffer wbuf, obj):
+ cdef:
+ int8_t is_closed = 0
+ ssize_t npts
+ ssize_t encoded_len
+ int32_t i
+
+ if cpython.PyTuple_Check(obj):
+ is_closed = 1
+ elif cpython.PyList_Check(obj):
+ is_closed = 0
+ elif isinstance(obj, pgproto_types.Path):
+ is_closed = obj.is_closed
+
+ npts = len(obj)
+ encoded_len = 1 + 4 + 16 * npts
+ if encoded_len > _MAXINT32:
+ raise ValueError('path value too long')
+
+ wbuf.write_int32(<int32_t>encoded_len)
+ wbuf.write_byte(is_closed)
+ wbuf.write_int32(<int32_t>npts)
+
+ _encode_points(wbuf, obj)
+
+
+cdef path_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ int8_t is_closed = <int8_t>(frb_read(buf, 1)[0])
+
+ return pgproto_types.Path(*_decode_points(buf), is_closed=is_closed == 1)
+
+
+cdef poly_encode(CodecContext settings, WriteBuffer wbuf, obj):
+ cdef:
+ bint is_closed
+ ssize_t npts
+ ssize_t encoded_len
+ int32_t i
+
+ npts = len(obj)
+ encoded_len = 4 + 16 * npts
+ if encoded_len > _MAXINT32:
+ raise ValueError('polygon value too long')
+
+ wbuf.write_int32(<int32_t>encoded_len)
+ wbuf.write_int32(<int32_t>npts)
+ _encode_points(wbuf, obj)
+
+
+cdef poly_decode(CodecContext settings, FRBuffer *buf):
+ return pgproto_types.Polygon(*_decode_points(buf))
+
+
+cdef circle_encode(CodecContext settings, WriteBuffer wbuf, obj):
+ wbuf.write_int32(24)
+ wbuf.write_double(obj[0][0])
+ wbuf.write_double(obj[0][1])
+ wbuf.write_double(obj[1])
+
+
+cdef circle_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ double center_x = hton.unpack_double(frb_read(buf, 8))
+ double center_y = hton.unpack_double(frb_read(buf, 8))
+ double radius = hton.unpack_double(frb_read(buf, 8))
+
+ return pgproto_types.Circle((center_x, center_y), radius)
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/hstore.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/hstore.pyx
new file mode 100644
index 00000000..09051c76
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/hstore.pyx
@@ -0,0 +1,73 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef hstore_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ char *str
+ ssize_t size
+ ssize_t count
+ object items
+ WriteBuffer item_buf = WriteBuffer.new()
+
+ count = len(obj)
+ if count > _MAXINT32:
+ raise ValueError('hstore value is too large')
+ item_buf.write_int32(<int32_t>count)
+
+ if hasattr(obj, 'items'):
+ items = obj.items()
+ else:
+ items = obj
+
+ for k, v in items:
+ if k is None:
+ raise ValueError('null value not allowed in hstore key')
+ as_pg_string_and_size(settings, k, &str, &size)
+ item_buf.write_int32(<int32_t>size)
+ item_buf.write_cstr(str, size)
+ if v is None:
+ item_buf.write_int32(<int32_t>-1)
+ else:
+ as_pg_string_and_size(settings, v, &str, &size)
+ item_buf.write_int32(<int32_t>size)
+ item_buf.write_cstr(str, size)
+
+ buf.write_int32(item_buf.len())
+ buf.write_buffer(item_buf)
+
+
+cdef hstore_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ dict result
+ uint32_t elem_count
+ int32_t elem_len
+ uint32_t i
+ str k
+ str v
+
+ result = {}
+
+ elem_count = <uint32_t>hton.unpack_int32(frb_read(buf, 4))
+ if elem_count == 0:
+ return result
+
+ for i in range(elem_count):
+ elem_len = hton.unpack_int32(frb_read(buf, 4))
+ if elem_len < 0:
+ raise ValueError('null value not allowed in hstore key')
+
+ k = decode_pg_string(settings, frb_read(buf, elem_len), elem_len)
+
+ elem_len = hton.unpack_int32(frb_read(buf, 4))
+ if elem_len < 0:
+ v = None
+ else:
+ v = decode_pg_string(settings, frb_read(buf, elem_len), elem_len)
+
+ result[k] = v
+
+ return result
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/int.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/int.pyx
new file mode 100644
index 00000000..99972444
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/int.pyx
@@ -0,0 +1,144 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef bool_encode(CodecContext settings, WriteBuffer buf, obj):
+ if not cpython.PyBool_Check(obj):
+ raise TypeError('a boolean is required (got type {})'.format(
+ type(obj).__name__))
+
+ buf.write_int32(1)
+ buf.write_byte(b'\x01' if obj is True else b'\x00')
+
+
+cdef bool_decode(CodecContext settings, FRBuffer *buf):
+ return frb_read(buf, 1)[0] is b'\x01'
+
+
+cdef int2_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef int overflow = 0
+ cdef long val
+
+ try:
+ if type(obj) is not int and hasattr(type(obj), '__int__'):
+ # Silence a Python warning about implicit __int__
+ # conversion.
+ obj = int(obj)
+ val = cpython.PyLong_AsLong(obj)
+ except OverflowError:
+ overflow = 1
+
+ if overflow or val < INT16_MIN or val > INT16_MAX:
+ raise OverflowError('value out of int16 range')
+
+ buf.write_int32(2)
+ buf.write_int16(<int16_t>val)
+
+
+cdef int2_decode(CodecContext settings, FRBuffer *buf):
+ return cpython.PyLong_FromLong(hton.unpack_int16(frb_read(buf, 2)))
+
+
+cdef int4_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef int overflow = 0
+ cdef long val = 0
+
+ try:
+ if type(obj) is not int and hasattr(type(obj), '__int__'):
+ # Silence a Python warning about implicit __int__
+ # conversion.
+ obj = int(obj)
+ val = cpython.PyLong_AsLong(obj)
+ except OverflowError:
+ overflow = 1
+
+ # "long" and "long long" have the same size for x86_64, need an extra check
+ if overflow or (sizeof(val) > 4 and (val < INT32_MIN or val > INT32_MAX)):
+ raise OverflowError('value out of int32 range')
+
+ buf.write_int32(4)
+ buf.write_int32(<int32_t>val)
+
+
+cdef int4_decode(CodecContext settings, FRBuffer *buf):
+ return cpython.PyLong_FromLong(hton.unpack_int32(frb_read(buf, 4)))
+
+
+cdef uint4_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef int overflow = 0
+ cdef unsigned long val = 0
+
+ try:
+ if type(obj) is not int and hasattr(type(obj), '__int__'):
+ # Silence a Python warning about implicit __int__
+ # conversion.
+ obj = int(obj)
+ val = cpython.PyLong_AsUnsignedLong(obj)
+ except OverflowError:
+ overflow = 1
+
+ # "long" and "long long" have the same size for x86_64, need an extra check
+ if overflow or (sizeof(val) > 4 and val > UINT32_MAX):
+ raise OverflowError('value out of uint32 range')
+
+ buf.write_int32(4)
+ buf.write_int32(<int32_t>val)
+
+
+cdef uint4_decode(CodecContext settings, FRBuffer *buf):
+ return cpython.PyLong_FromUnsignedLong(
+ <uint32_t>hton.unpack_int32(frb_read(buf, 4)))
+
+
+cdef int8_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef int overflow = 0
+ cdef long long val
+
+ try:
+ if type(obj) is not int and hasattr(type(obj), '__int__'):
+ # Silence a Python warning about implicit __int__
+ # conversion.
+ obj = int(obj)
+ val = cpython.PyLong_AsLongLong(obj)
+ except OverflowError:
+ overflow = 1
+
+ # Just in case for systems with "long long" bigger than 8 bytes
+ if overflow or (sizeof(val) > 8 and (val < INT64_MIN or val > INT64_MAX)):
+ raise OverflowError('value out of int64 range')
+
+ buf.write_int32(8)
+ buf.write_int64(<int64_t>val)
+
+
+cdef int8_decode(CodecContext settings, FRBuffer *buf):
+ return cpython.PyLong_FromLongLong(hton.unpack_int64(frb_read(buf, 8)))
+
+
+cdef uint8_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef int overflow = 0
+ cdef unsigned long long val = 0
+
+ try:
+ if type(obj) is not int and hasattr(type(obj), '__int__'):
+ # Silence a Python warning about implicit __int__
+ # conversion.
+ obj = int(obj)
+ val = cpython.PyLong_AsUnsignedLongLong(obj)
+ except OverflowError:
+ overflow = 1
+
+ # Just in case for systems with "long long" bigger than 8 bytes
+ if overflow or (sizeof(val) > 8 and val > UINT64_MAX):
+ raise OverflowError('value out of uint64 range')
+
+ buf.write_int32(8)
+ buf.write_int64(<int64_t>val)
+
+
+cdef uint8_decode(CodecContext settings, FRBuffer *buf):
+ return cpython.PyLong_FromUnsignedLongLong(
+ <uint64_t>hton.unpack_int64(frb_read(buf, 8))) \ No newline at end of file
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/json.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/json.pyx
new file mode 100644
index 00000000..97e6916b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/json.pyx
@@ -0,0 +1,57 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef jsonb_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ char *str
+ ssize_t size
+
+ if settings.is_encoding_json():
+ obj = settings.get_json_encoder().encode(obj)
+
+ as_pg_string_and_size(settings, obj, &str, &size)
+
+ if size > 0x7fffffff - 1:
+ raise ValueError('string too long')
+
+ buf.write_int32(<int32_t>size + 1)
+ buf.write_byte(1) # JSONB format version
+ buf.write_cstr(str, size)
+
+
+cdef jsonb_decode(CodecContext settings, FRBuffer *buf):
+ cdef uint8_t format = <uint8_t>(frb_read(buf, 1)[0])
+
+ if format != 1:
+ raise ValueError('unexpected JSONB format: {}'.format(format))
+
+ rv = text_decode(settings, buf)
+
+ if settings.is_decoding_json():
+ rv = settings.get_json_decoder().decode(rv)
+
+ return rv
+
+
+cdef json_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ char *str
+ ssize_t size
+
+ if settings.is_encoding_json():
+ obj = settings.get_json_encoder().encode(obj)
+
+ text_encode(settings, buf, obj)
+
+
+cdef json_decode(CodecContext settings, FRBuffer *buf):
+ rv = text_decode(settings, buf)
+
+ if settings.is_decoding_json():
+ rv = settings.get_json_decoder().decode(rv)
+
+ return rv
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/jsonpath.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/jsonpath.pyx
new file mode 100644
index 00000000..610b30d7
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/jsonpath.pyx
@@ -0,0 +1,29 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef jsonpath_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ char *str
+ ssize_t size
+
+ as_pg_string_and_size(settings, obj, &str, &size)
+
+ if size > 0x7fffffff - 1:
+ raise ValueError('string too long')
+
+ buf.write_int32(<int32_t>size + 1)
+ buf.write_byte(1) # jsonpath format version
+ buf.write_cstr(str, size)
+
+
+cdef jsonpath_decode(CodecContext settings, FRBuffer *buf):
+ cdef uint8_t format = <uint8_t>(frb_read(buf, 1)[0])
+
+ if format != 1:
+ raise ValueError('unexpected jsonpath format: {}'.format(format))
+
+ return text_decode(settings, buf)
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/misc.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/misc.pyx
new file mode 100644
index 00000000..99b19c99
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/misc.pyx
@@ -0,0 +1,16 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef void_encode(CodecContext settings, WriteBuffer buf, obj):
+ # Void is zero bytes
+ buf.write_int32(0)
+
+
+cdef void_decode(CodecContext settings, FRBuffer *buf):
+ # Do nothing; void will be passed as NULL so this function
+ # will never be called.
+ pass
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/network.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/network.pyx
new file mode 100644
index 00000000..730c947f
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/network.pyx
@@ -0,0 +1,139 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+import ipaddress
+
+
+# defined in postgresql/src/include/inet.h
+#
+DEF PGSQL_AF_INET = 2 # AF_INET
+DEF PGSQL_AF_INET6 = 3 # AF_INET + 1
+
+
+_ipaddr = ipaddress.ip_address
+_ipiface = ipaddress.ip_interface
+_ipnet = ipaddress.ip_network
+
+
+cdef inline uint8_t _ip_max_prefix_len(int32_t family):
+ # Maximum number of bits in the network prefix of the specified
+ # IP protocol version.
+ if family == PGSQL_AF_INET:
+ return 32
+ else:
+ return 128
+
+
+cdef inline int32_t _ip_addr_len(int32_t family):
+ # Length of address in bytes for the specified IP protocol version.
+ if family == PGSQL_AF_INET:
+ return 4
+ else:
+ return 16
+
+
+cdef inline int8_t _ver_to_family(int32_t version):
+ if version == 4:
+ return PGSQL_AF_INET
+ else:
+ return PGSQL_AF_INET6
+
+
+cdef inline _net_encode(WriteBuffer buf, int8_t family, uint32_t bits,
+ int8_t is_cidr, bytes addr):
+
+ cdef:
+ char *addrbytes
+ ssize_t addrlen
+
+ cpython.PyBytes_AsStringAndSize(addr, &addrbytes, &addrlen)
+
+ buf.write_int32(4 + <int32_t>addrlen)
+ buf.write_byte(family)
+ buf.write_byte(<int8_t>bits)
+ buf.write_byte(is_cidr)
+ buf.write_byte(<int8_t>addrlen)
+ buf.write_cstr(addrbytes, addrlen)
+
+
+cdef net_decode(CodecContext settings, FRBuffer *buf, bint as_cidr):
+ cdef:
+ int32_t family = <int32_t>frb_read(buf, 1)[0]
+ uint8_t bits = <uint8_t>frb_read(buf, 1)[0]
+ int prefix_len
+ int32_t is_cidr = <int32_t>frb_read(buf, 1)[0]
+ int32_t addrlen = <int32_t>frb_read(buf, 1)[0]
+ bytes addr
+ uint8_t max_prefix_len = _ip_max_prefix_len(family)
+
+ if is_cidr != as_cidr:
+ raise ValueError('unexpected CIDR flag set in non-cidr value')
+
+ if family != PGSQL_AF_INET and family != PGSQL_AF_INET6:
+ raise ValueError('invalid address family in "{}" value'.format(
+ 'cidr' if is_cidr else 'inet'
+ ))
+
+ max_prefix_len = _ip_max_prefix_len(family)
+
+ if bits > max_prefix_len:
+ raise ValueError('invalid network prefix length in "{}" value'.format(
+ 'cidr' if is_cidr else 'inet'
+ ))
+
+ if addrlen != _ip_addr_len(family):
+ raise ValueError('invalid address length in "{}" value'.format(
+ 'cidr' if is_cidr else 'inet'
+ ))
+
+ addr = cpython.PyBytes_FromStringAndSize(frb_read(buf, addrlen), addrlen)
+
+ if as_cidr or bits != max_prefix_len:
+ prefix_len = cpython.PyLong_FromLong(bits)
+
+ if as_cidr:
+ return _ipnet((addr, prefix_len))
+ else:
+ return _ipiface((addr, prefix_len))
+ else:
+ return _ipaddr(addr)
+
+
+cdef cidr_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ object ipnet
+ int8_t family
+
+ ipnet = _ipnet(obj)
+ family = _ver_to_family(ipnet.version)
+ _net_encode(buf, family, ipnet.prefixlen, 1, ipnet.network_address.packed)
+
+
+cdef cidr_decode(CodecContext settings, FRBuffer *buf):
+ return net_decode(settings, buf, True)
+
+
+cdef inet_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ object ipaddr
+ int8_t family
+
+ try:
+ ipaddr = _ipaddr(obj)
+ except ValueError:
+ # PostgreSQL accepts *both* CIDR and host values
+ # for the host datatype.
+ ipaddr = _ipiface(obj)
+ family = _ver_to_family(ipaddr.version)
+ _net_encode(buf, family, ipaddr.network.prefixlen, 1, ipaddr.packed)
+ else:
+ family = _ver_to_family(ipaddr.version)
+ _net_encode(buf, family, _ip_max_prefix_len(family), 0, ipaddr.packed)
+
+
+cdef inet_decode(CodecContext settings, FRBuffer *buf):
+ return net_decode(settings, buf, False)
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/numeric.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/numeric.pyx
new file mode 100644
index 00000000..b75d0961
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/numeric.pyx
@@ -0,0 +1,356 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+from libc.math cimport abs, log10
+from libc.stdio cimport snprintf
+
+import decimal
+
+# defined in postgresql/src/backend/utils/adt/numeric.c
+DEF DEC_DIGITS = 4
+DEF MAX_DSCALE = 0x3FFF
+DEF NUMERIC_POS = 0x0000
+DEF NUMERIC_NEG = 0x4000
+DEF NUMERIC_NAN = 0xC000
+DEF NUMERIC_PINF = 0xD000
+DEF NUMERIC_NINF = 0xF000
+
+_Dec = decimal.Decimal
+
+
+cdef numeric_encode_text(CodecContext settings, WriteBuffer buf, obj):
+ text_encode(settings, buf, str(obj))
+
+
+cdef numeric_decode_text(CodecContext settings, FRBuffer *buf):
+ return _Dec(text_decode(settings, buf))
+
+
+cdef numeric_encode_binary(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ object dec
+ object dt
+ int64_t exponent
+ int64_t i
+ int64_t j
+ tuple pydigits
+ int64_t num_pydigits
+ int16_t pgdigit
+ int64_t num_pgdigits
+ int16_t dscale
+ int64_t dweight
+ int64_t weight
+ uint16_t sign
+ int64_t padding_size = 0
+
+ if isinstance(obj, _Dec):
+ dec = obj
+ else:
+ dec = _Dec(obj)
+
+ dt = dec.as_tuple()
+
+ if dt.exponent == 'n' or dt.exponent == 'N':
+ # NaN
+ sign = NUMERIC_NAN
+ num_pgdigits = 0
+ weight = 0
+ dscale = 0
+ elif dt.exponent == 'F':
+ # Infinity
+ if dt.sign:
+ sign = NUMERIC_NINF
+ else:
+ sign = NUMERIC_PINF
+ num_pgdigits = 0
+ weight = 0
+ dscale = 0
+ else:
+ exponent = dt.exponent
+ if exponent < 0 and -exponent > MAX_DSCALE:
+ raise ValueError(
+ 'cannot encode Decimal value into numeric: '
+ 'exponent is too small')
+
+ if dt.sign:
+ sign = NUMERIC_NEG
+ else:
+ sign = NUMERIC_POS
+
+ pydigits = dt.digits
+ num_pydigits = len(pydigits)
+
+ dweight = num_pydigits + exponent - 1
+ if dweight >= 0:
+ weight = (dweight + DEC_DIGITS) // DEC_DIGITS - 1
+ else:
+ weight = -((-dweight - 1) // DEC_DIGITS + 1)
+
+ if weight > 2 ** 16 - 1:
+ raise ValueError(
+ 'cannot encode Decimal value into numeric: '
+ 'exponent is too large')
+
+ padding_size = \
+ (weight + 1) * DEC_DIGITS - (dweight + 1)
+ num_pgdigits = \
+ (num_pydigits + padding_size + DEC_DIGITS - 1) // DEC_DIGITS
+
+ if num_pgdigits > 2 ** 16 - 1:
+ raise ValueError(
+ 'cannot encode Decimal value into numeric: '
+ 'number of digits is too large')
+
+ # Pad decimal digits to provide room for correct Postgres
+ # digit alignment in the digit computation loop.
+ pydigits = (0,) * DEC_DIGITS + pydigits + (0,) * DEC_DIGITS
+
+ if exponent < 0:
+ if -exponent > MAX_DSCALE:
+ raise ValueError(
+ 'cannot encode Decimal value into numeric: '
+ 'exponent is too small')
+ dscale = <int16_t>-exponent
+ else:
+ dscale = 0
+
+ buf.write_int32(2 + 2 + 2 + 2 + 2 * <uint16_t>num_pgdigits)
+ buf.write_int16(<int16_t>num_pgdigits)
+ buf.write_int16(<int16_t>weight)
+ buf.write_int16(<int16_t>sign)
+ buf.write_int16(dscale)
+
+ j = DEC_DIGITS - padding_size
+
+ for i in range(num_pgdigits):
+ pgdigit = (pydigits[j] * 1000 + pydigits[j + 1] * 100 +
+ pydigits[j + 2] * 10 + pydigits[j + 3])
+ j += DEC_DIGITS
+ buf.write_int16(pgdigit)
+
+
+# The decoding strategy here is to form a string representation of
+# the numeric var, as it is faster than passing an iterable of digits.
+# For this reason the below code is pure overhead and is ~25% slower
+# than the simple text decoder above. That said, we need the binary
+# decoder to support binary COPY with numeric values.
+cdef numeric_decode_binary_ex(
+ CodecContext settings,
+ FRBuffer *buf,
+ bint trail_fract_zero,
+):
+ cdef:
+ uint16_t num_pgdigits = <uint16_t>hton.unpack_int16(frb_read(buf, 2))
+ int16_t weight = hton.unpack_int16(frb_read(buf, 2))
+ uint16_t sign = <uint16_t>hton.unpack_int16(frb_read(buf, 2))
+ uint16_t dscale = <uint16_t>hton.unpack_int16(frb_read(buf, 2))
+ int16_t pgdigit0
+ ssize_t i
+ int16_t pgdigit
+ object pydigits
+ ssize_t num_pydigits
+ ssize_t actual_num_pydigits
+ ssize_t buf_size
+ int64_t exponent
+ int64_t abs_exponent
+ ssize_t exponent_chars
+ ssize_t front_padding = 0
+ ssize_t num_fract_digits
+ ssize_t trailing_fract_zeros_adj
+ char smallbuf[_NUMERIC_DECODER_SMALLBUF_SIZE]
+ char *charbuf
+ char *bufptr
+ bint buf_allocated = False
+
+ if sign == NUMERIC_NAN:
+ # Not-a-number
+ return _Dec('NaN')
+ elif sign == NUMERIC_PINF:
+ # +Infinity
+ return _Dec('Infinity')
+ elif sign == NUMERIC_NINF:
+ # -Infinity
+ return _Dec('-Infinity')
+
+ if num_pgdigits == 0:
+ # Zero
+ return _Dec('0e-' + str(dscale))
+
+ pgdigit0 = hton.unpack_int16(frb_read(buf, 2))
+ if weight >= 0:
+ if pgdigit0 < 10:
+ front_padding = 3
+ elif pgdigit0 < 100:
+ front_padding = 2
+ elif pgdigit0 < 1000:
+ front_padding = 1
+
+ # The number of fractional decimal digits actually encoded in
+ # base-DEC_DEIGITS digits sent by Postgres.
+ num_fract_digits = (num_pgdigits - weight - 1) * DEC_DIGITS
+
+ # The trailing zero adjustment necessary to obtain exactly
+ # dscale number of fractional digits in output. May be negative,
+ # which indicates that trailing zeros in the last input digit
+ # should be discarded.
+ trailing_fract_zeros_adj = dscale - num_fract_digits
+
+ # Maximum possible number of decimal digits in base 10.
+ # The actual number might be up to 3 digits smaller due to
+ # leading zeros in first input digit.
+ num_pydigits = num_pgdigits * DEC_DIGITS
+ if trailing_fract_zeros_adj > 0:
+ num_pydigits += trailing_fract_zeros_adj
+
+ # Exponent.
+ exponent = (weight + 1) * DEC_DIGITS - front_padding
+ abs_exponent = abs(exponent)
+ if abs_exponent != 0:
+ # Number of characters required to render absolute exponent value
+ # in decimal.
+ exponent_chars = <ssize_t>log10(<double>abs_exponent) + 1
+ else:
+ exponent_chars = 0
+
+ # Output buffer size.
+ buf_size = (
+ 1 + # sign
+ 1 + # leading zero
+ 1 + # decimal dot
+ num_pydigits + # digits
+ 1 + # possible trailing zero padding
+ 2 + # exponent indicator (E-,E+)
+ exponent_chars + # exponent
+ 1 # null terminator char
+ )
+
+ if buf_size > _NUMERIC_DECODER_SMALLBUF_SIZE:
+ charbuf = <char *>cpython.PyMem_Malloc(<size_t>buf_size)
+ buf_allocated = True
+ else:
+ charbuf = smallbuf
+
+ try:
+ bufptr = charbuf
+
+ if sign == NUMERIC_NEG:
+ bufptr[0] = b'-'
+ bufptr += 1
+
+ bufptr[0] = b'0'
+ bufptr[1] = b'.'
+ bufptr += 2
+
+ if weight >= 0:
+ bufptr = _unpack_digit_stripping_lzeros(bufptr, pgdigit0)
+ else:
+ bufptr = _unpack_digit(bufptr, pgdigit0)
+
+ for i in range(1, num_pgdigits):
+ pgdigit = hton.unpack_int16(frb_read(buf, 2))
+ bufptr = _unpack_digit(bufptr, pgdigit)
+
+ if dscale:
+ if trailing_fract_zeros_adj > 0:
+ for i in range(trailing_fract_zeros_adj):
+ bufptr[i] = <char>b'0'
+
+ # If display scale is _less_ than the number of rendered digits,
+ # trailing_fract_zeros_adj will be negative and this will strip
+ # the excess trailing zeros.
+ bufptr += trailing_fract_zeros_adj
+
+ if trail_fract_zero:
+ # Check if the number of rendered digits matches the exponent,
+ # and if so, add another trailing zero, so the result always
+ # appears with a decimal point.
+ actual_num_pydigits = bufptr - charbuf - 2
+ if sign == NUMERIC_NEG:
+ actual_num_pydigits -= 1
+
+ if actual_num_pydigits == abs_exponent:
+ bufptr[0] = <char>b'0'
+ bufptr += 1
+
+ if exponent != 0:
+ bufptr[0] = b'E'
+ if exponent < 0:
+ bufptr[1] = b'-'
+ else:
+ bufptr[1] = b'+'
+ bufptr += 2
+ snprintf(bufptr, <size_t>exponent_chars + 1, '%d',
+ <int>abs_exponent)
+ bufptr += exponent_chars
+
+ bufptr[0] = 0
+
+ pydigits = cpythonx.PyUnicode_FromString(charbuf)
+
+ return _Dec(pydigits)
+
+ finally:
+ if buf_allocated:
+ cpython.PyMem_Free(charbuf)
+
+
+cdef numeric_decode_binary(CodecContext settings, FRBuffer *buf):
+ return numeric_decode_binary_ex(settings, buf, False)
+
+
+cdef inline char *_unpack_digit_stripping_lzeros(char *buf, int64_t pgdigit):
+ cdef:
+ int64_t d
+ bint significant
+
+ d = pgdigit // 1000
+ significant = (d > 0)
+ if significant:
+ pgdigit -= d * 1000
+ buf[0] = <char>(d + <int32_t>b'0')
+ buf += 1
+
+ d = pgdigit // 100
+ significant |= (d > 0)
+ if significant:
+ pgdigit -= d * 100
+ buf[0] = <char>(d + <int32_t>b'0')
+ buf += 1
+
+ d = pgdigit // 10
+ significant |= (d > 0)
+ if significant:
+ pgdigit -= d * 10
+ buf[0] = <char>(d + <int32_t>b'0')
+ buf += 1
+
+ buf[0] = <char>(pgdigit + <int32_t>b'0')
+ buf += 1
+
+ return buf
+
+
+cdef inline char *_unpack_digit(char *buf, int64_t pgdigit):
+ cdef:
+ int64_t d
+
+ d = pgdigit // 1000
+ pgdigit -= d * 1000
+ buf[0] = <char>(d + <int32_t>b'0')
+
+ d = pgdigit // 100
+ pgdigit -= d * 100
+ buf[1] = <char>(d + <int32_t>b'0')
+
+ d = pgdigit // 10
+ pgdigit -= d * 10
+ buf[2] = <char>(d + <int32_t>b'0')
+
+ buf[3] = <char>(pgdigit + <int32_t>b'0')
+ buf += 4
+
+ return buf
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/pg_snapshot.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/pg_snapshot.pyx
new file mode 100644
index 00000000..d96107cc
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/pg_snapshot.pyx
@@ -0,0 +1,63 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef pg_snapshot_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ ssize_t nxip
+ uint64_t xmin
+ uint64_t xmax
+ int i
+ WriteBuffer xip_buf = WriteBuffer.new()
+
+ if not (cpython.PyTuple_Check(obj) or cpython.PyList_Check(obj)):
+ raise TypeError(
+ 'list or tuple expected (got type {})'.format(type(obj)))
+
+ if len(obj) != 3:
+ raise ValueError(
+ 'invalid number of elements in txid_snapshot tuple, expecting 4')
+
+ nxip = len(obj[2])
+ if nxip > _MAXINT32:
+ raise ValueError('txid_snapshot value is too long')
+
+ xmin = obj[0]
+ xmax = obj[1]
+
+ for i in range(nxip):
+ xip_buf.write_int64(
+ <int64_t>cpython.PyLong_AsUnsignedLongLong(obj[2][i]))
+
+ buf.write_int32(20 + xip_buf.len())
+
+ buf.write_int32(<int32_t>nxip)
+ buf.write_int64(<int64_t>xmin)
+ buf.write_int64(<int64_t>xmax)
+ buf.write_buffer(xip_buf)
+
+
+cdef pg_snapshot_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ int32_t nxip
+ uint64_t xmin
+ uint64_t xmax
+ tuple xip_tup
+ int32_t i
+ object xip
+
+ nxip = hton.unpack_int32(frb_read(buf, 4))
+ xmin = <uint64_t>hton.unpack_int64(frb_read(buf, 8))
+ xmax = <uint64_t>hton.unpack_int64(frb_read(buf, 8))
+
+ xip_tup = cpython.PyTuple_New(nxip)
+ for i in range(nxip):
+ xip = cpython.PyLong_FromUnsignedLongLong(
+ <uint64_t>hton.unpack_int64(frb_read(buf, 8)))
+ cpython.Py_INCREF(xip)
+ cpython.PyTuple_SET_ITEM(xip_tup, i, xip)
+
+ return (xmin, xmax, xip_tup)
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/text.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/text.pyx
new file mode 100644
index 00000000..79f375d6
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/text.pyx
@@ -0,0 +1,48 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef inline as_pg_string_and_size(
+ CodecContext settings, obj, char **cstr, ssize_t *size):
+
+ if not cpython.PyUnicode_Check(obj):
+ raise TypeError('expected str, got {}'.format(type(obj).__name__))
+
+ if settings.is_encoding_utf8():
+ cstr[0] = <char*>cpythonx.PyUnicode_AsUTF8AndSize(obj, size)
+ else:
+ encoded = settings.get_text_codec().encode(obj)[0]
+ cpython.PyBytes_AsStringAndSize(encoded, cstr, size)
+
+ if size[0] > 0x7fffffff:
+ raise ValueError('string too long')
+
+
+cdef text_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef:
+ char *str
+ ssize_t size
+
+ as_pg_string_and_size(settings, obj, &str, &size)
+
+ buf.write_int32(<int32_t>size)
+ buf.write_cstr(str, size)
+
+
+cdef inline decode_pg_string(CodecContext settings, const char* data,
+ ssize_t len):
+
+ if settings.is_encoding_utf8():
+ # decode UTF-8 in strict mode
+ return cpython.PyUnicode_DecodeUTF8(data, len, NULL)
+ else:
+ bytes = cpython.PyBytes_FromStringAndSize(data, len)
+ return settings.get_text_codec().decode(bytes)[0]
+
+
+cdef text_decode(CodecContext settings, FRBuffer *buf):
+ cdef ssize_t buf_len = buf.len
+ return decode_pg_string(settings, frb_read_all(buf), buf_len)
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/tid.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/tid.pyx
new file mode 100644
index 00000000..b39bddc4
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/tid.pyx
@@ -0,0 +1,51 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef tid_encode(CodecContext settings, WriteBuffer buf, obj):
+ cdef int overflow = 0
+ cdef unsigned long block, offset
+
+ if not (cpython.PyTuple_Check(obj) or cpython.PyList_Check(obj)):
+ raise TypeError(
+ 'list or tuple expected (got type {})'.format(type(obj)))
+
+ if len(obj) != 2:
+ raise ValueError(
+ 'invalid number of elements in tid tuple, expecting 2')
+
+ try:
+ block = cpython.PyLong_AsUnsignedLong(obj[0])
+ except OverflowError:
+ overflow = 1
+
+ # "long" and "long long" have the same size for x86_64, need an extra check
+ if overflow or (sizeof(block) > 4 and block > UINT32_MAX):
+ raise OverflowError('tuple id block value out of uint32 range')
+
+ try:
+ offset = cpython.PyLong_AsUnsignedLong(obj[1])
+ overflow = 0
+ except OverflowError:
+ overflow = 1
+
+ if overflow or offset > 65535:
+ raise OverflowError('tuple id offset value out of uint16 range')
+
+ buf.write_int32(6)
+ buf.write_int32(<int32_t>block)
+ buf.write_int16(<int16_t>offset)
+
+
+cdef tid_decode(CodecContext settings, FRBuffer *buf):
+ cdef:
+ uint32_t block
+ uint16_t offset
+
+ block = <uint32_t>hton.unpack_int32(frb_read(buf, 4))
+ offset = <uint16_t>hton.unpack_int16(frb_read(buf, 2))
+
+ return (block, offset)
diff --git a/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/uuid.pyx b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/uuid.pyx
new file mode 100644
index 00000000..0bc45679
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/asyncpg/pgproto/codecs/uuid.pyx
@@ -0,0 +1,27 @@
+# Copyright (C) 2016-present the asyncpg authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of asyncpg and is released under
+# the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
+
+
+cdef uuid_encode(CodecContext settings, WriteBuffer wbuf, obj):
+ cdef:
+ char buf[16]
+
+ if type(obj) is pg_UUID:
+ wbuf.write_int32(<int32_t>16)
+ wbuf.write_cstr((<UUID>obj)._data, 16)
+ elif cpython.PyUnicode_Check(obj):
+ pg_uuid_bytes_from_str(obj, buf)
+ wbuf.write_int32(<int32_t>16)
+ wbuf.write_cstr(buf, 16)
+ else:
+ bytea_encode(settings, wbuf, obj.bytes)
+
+
+cdef uuid_decode(CodecContext settings, FRBuffer *buf):
+ if buf.len != 16:
+ raise TypeError(
+ f'cannot decode UUID, expected 16 bytes, got {buf.len}')
+ return pg_uuid_from_buf(frb_read_all(buf))