]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Add AdaptersMap.types map
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Fri, 5 Feb 2021 02:13:23 +0000 (03:13 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Fri, 5 Feb 2021 02:52:13 +0000 (03:52 +0100)
Use the map from the adapters when it's needed to look up for a type
info.

Probably there are other places where to make use of it.

28 files changed:
docs/copy.rst
psycopg3/psycopg3/_column.py
psycopg3/psycopg3/adapt.py
psycopg3/psycopg3/copy.py
psycopg3/psycopg3/dbapi20.py
psycopg3/psycopg3/oids.py
psycopg3/psycopg3/types/__init__.py
psycopg3/psycopg3/types/array.py
psycopg3/psycopg3/types/composite.py
psycopg3/psycopg3/types/date.py
psycopg3/psycopg3/types/json.py
psycopg3/psycopg3/types/network.py
psycopg3/psycopg3/types/numeric.py
psycopg3/psycopg3/types/range.py
psycopg3/psycopg3/types/singletons.py
psycopg3/psycopg3/types/text.py
psycopg3/psycopg3/types/uuid.py
psycopg3_c/psycopg3_c/_psycopg3/adapt.pyx
tests/fix_faker.py
tests/test_adapt.py
tests/test_copy.py
tests/test_copy_async.py
tests/test_cursor.py
tests/types/test_array.py
tests/types/test_composite.py
tests/types/test_numeric.py
tests/types/test_range.py
tests/types/test_singletons.py

index c9665cb80587443b3ed002ef0373c7350da2d418..f8045ade574fd96d2c1ea3c04e82acea4137433b 100644 (file)
@@ -104,13 +104,6 @@ you have to specify them yourselves.
         for row in copy.rows():
             print(row)  # (10, datetime.date(2046, 12, 24))
 
-.. admonition:: TODO
-
-    Currently only builtin names are recognised; custom types must be
-    specified by numeric oid. This wll change after the `TypeRegistry` and
-    `AdaptContext` get integrated, none of which I have documented, so you
-    haven't seen anything... ðŸ‘€
-
 
 Copying block-by-block
 ----------------------
index e5b7d98734004e6725e8845eb8349c6e1e2844a2..260c399136465c5a5f3c5d2134b64ef4ea868dea 100644 (file)
@@ -8,7 +8,6 @@ from typing import Any, NamedTuple, Optional, Sequence, TYPE_CHECKING
 from operator import attrgetter
 
 from . import errors as e
-from .oids import builtins
 
 if TYPE_CHECKING:
     from .cursor import BaseCursor
@@ -39,6 +38,7 @@ class Column(Sequence[Any]):
             fmod=res.fmod(index),
             fsize=res.fsize(index),
         )
+        self._type = cursor.adapters.types.get(self._data.ftype)
 
     _attrs = tuple(
         attrgetter(attr)
@@ -55,8 +55,7 @@ class Column(Sequence[Any]):
 
     def _type_display(self) -> str:
         parts = []
-        t = builtins.get(self.type_code)
-        parts.append(t.name if t else str(self.type_code))
+        parts.append(self._type.name if self._type else str(self.type_code))
 
         mod1 = self.precision
         if mod1 is None:
@@ -67,7 +66,7 @@ class Column(Sequence[Any]):
                 parts.append(f", {self.scale}")
             parts.append(")")
 
-        if t and self.type_code == t.array_oid:
+        if self._type and self.type_code == self._type.array_oid:
             parts.append("[]")
 
         return "".join(parts)
@@ -91,11 +90,10 @@ class Column(Sequence[Any]):
     @property
     def display_size(self) -> Optional[int]:
         """The field size, for :sql:`varchar(n)`, None otherwise."""
-        t = builtins.get(self.type_code)
-        if not t:
+        if not self._type:
             return None
 
-        if t.name in ("varchar", "char"):
+        if self._type.name in ("varchar", "char"):
             fmod = self._data.fmod
             if fmod >= 0:
                 return fmod - 4
@@ -111,17 +109,16 @@ class Column(Sequence[Any]):
     @property
     def precision(self) -> Optional[int]:
         """The number of digits for fixed precision types."""
-        t = builtins.get(self.type_code)
-        if not t:
+        if not self._type:
             return None
 
         dttypes = ("time", "timetz", "timestamp", "timestamptz", "interval")
-        if t.name == "numeric":
+        if self._type.name == "numeric":
             fmod = self._data.fmod
             if fmod >= 0:
                 return fmod >> 16
 
-        elif t.name in dttypes:
+        elif self._type.name in dttypes:
             fmod = self._data.fmod
             if fmod >= 0:
                 return fmod & 0xFFFF
@@ -134,7 +131,7 @@ class Column(Sequence[Any]):
 
         TODO: probably better than precision for datetime objects? review.
         """
-        if self.type_code == builtins["numeric"].oid:
+        if self._type and self._type.name == "numeric":
             fmod = self._data.fmod - 4
             if fmod >= 0:
                 return fmod & 0xFFFF
index fc8a9cbbff8948d405e183b1b397b319b00d444b..0b4ffe43d52d23424f9ed218ef1690656249cdfb 100644 (file)
@@ -12,7 +12,7 @@ from . import pq
 from . import proto
 from . import errors as e
 from ._enums import Format as Format
-from .oids import builtins
+from .oids import TypesRegistry, postgres_types
 from .proto import AdaptContext, Buffer as Buffer
 
 if TYPE_CHECKING:
@@ -124,8 +124,6 @@ class Loader(ABC):
         """
         Configure *context* to use this loader to convert values with OID *oid*.
         """
-        if isinstance(oid, str):
-            oid = builtins[oid].oid
         adapters = context.adapters if context else global_adapters
         adapters.register_loader(oid, cls)
 
@@ -142,21 +140,28 @@ class AdaptersMap(AdaptContext):
 
     _dumpers: List[Dict[Union[type, str], Type["Dumper"]]]
     _loaders: List[Dict[int, Type["Loader"]]]
+    types: TypesRegistry
 
     # Record if a dumper or loader has an optimised version.
     _optimised: Dict[type, type] = {}
 
-    def __init__(self, extend: Optional["AdaptersMap"] = None):
-        if extend:
-            self._dumpers = extend._dumpers[:]
+    def __init__(
+        self,
+        template: Optional["AdaptersMap"] = None,
+        types: Optional[TypesRegistry] = None,
+    ):
+        if template:
+            self._dumpers = template._dumpers[:]
             self._own_dumpers = [False, False]
-            self._loaders = extend._loaders[:]
+            self._loaders = template._loaders[:]
             self._own_loaders = [False, False]
+            self.types = TypesRegistry(template.types)
         else:
             self._dumpers = [{}, {}]
             self._own_dumpers = [True, True]
             self._loaders = [{}, {}]
             self._own_loaders = [True, True]
+            self.types = types or TypesRegistry()
 
     # implement the AdaptContext protocol too
     @property
@@ -186,10 +191,14 @@ class AdaptersMap(AdaptContext):
 
         self._dumpers[fmt][cls] = dumper
 
-    def register_loader(self, oid: int, loader: Type[Loader]) -> None:
+    def register_loader(
+        self, oid: Union[int, str], loader: Type[Loader]
+    ) -> None:
         """
         Configure the context to use *loader* to convert data of oid *oid*.
         """
+        if isinstance(oid, str):
+            oid = self.types[oid].oid
         if not isinstance(oid, int):
             raise TypeError(
                 f"loaders should be registered on oid, got {oid} instead"
@@ -282,7 +291,7 @@ class AdaptersMap(AdaptContext):
         return cls
 
 
-global_adapters = AdaptersMap()
+global_adapters = AdaptersMap(types=postgres_types)
 
 
 Transformer: Type[proto.Transformer]
index b55506906b1bdaa1cf5cb53cfaadc6e4d39ab83c..996b8e5d46a4502c4b8b3c1f16562b815a463056 100644 (file)
@@ -17,7 +17,6 @@ from typing import Any, Dict, List, Match, Optional, Sequence, Type, Tuple
 from . import pq
 from . import errors as e
 from .pq import ExecStatus
-from .oids import builtins
 from .adapt import Format
 from .proto import ConnectionType, PQGen, Transformer
 from .generators import copy_from, copy_to, copy_end
@@ -95,10 +94,9 @@ class BaseCopy(Generic[ConnectionType]):
             custom data types you must use their oid.
 
         """
-        # TODO: should allow names of non-builtin types
-        # Must put a types map on the context.
+        registry = self.cursor.adapters.types
         oids = [
-            t if isinstance(t, int) else builtins.get_oid(t) for t in types
+            t if isinstance(t, int) else registry.get_oid(t) for t in types
         ]
         self.formatter.transformer.set_row_types(
             oids, [self.formatter.format] * len(types)
index 8972662d4f4200c2d23e3ffc470e780db43a896d..dc7e55156350e7e73f3715ee5e05c598537a6962 100644 (file)
@@ -10,7 +10,7 @@ from math import floor
 from typing import Any, Sequence
 
 from .pq import Format
-from .oids import builtins
+from .oids import postgres_types as builtins
 from .adapt import Dumper
 
 
index daedcf3121ab3f6e05d9a7a9ab622b5442fabd7d..2942f3b56b0c967b74f9a7e851992df3d704a7e6 100644 (file)
@@ -43,12 +43,24 @@ class TypesRegistry:
     Container for the information about types in a database.
     """
 
-    def __init__(self) -> None:
-        self._by_oid: Dict[int, TypeInfo] = {}
-        self._by_name: Dict[str, TypeInfo] = {}
-        self._by_range_subtype: Dict[int, TypeInfo] = {}
+    def __init__(self, template: Optional["TypesRegistry"] = None):
+        self._by_oid: Dict[int, TypeInfo]
+        self._by_name: Dict[str, TypeInfo]
+        self._by_range_subtype: Dict[int, TypeInfo]
+
+        if template:
+            self._by_oid = template._by_oid
+            self._by_name = template._by_name
+            self._by_range_subtype = template._by_range_subtype
+            self._own_state = False
+        else:
+            self._by_oid = {}
+            self._by_name = {}
+            self._by_range_subtype = {}
+            self._own_state = True
 
     def add(self, info: TypeInfo) -> None:
+        self._ensure_own_state()
         self._by_oid[info.oid] = info
         if info.array_oid:
             self._by_oid[info.array_oid] = info
@@ -126,8 +138,16 @@ class TypesRegistry:
             return None
         return self._by_range_subtype.get(info.oid)
 
+    def _ensure_own_state(self) -> None:
+        # Time to write! so, copy.
+        if not self._own_state:
+            self._by_oid = self._by_oid.copy()
+            self._by_name = self._by_name.copy()
+            self._by_range_subtype = self._by_range_subtype.copy()
+            self._own_state = True
+
 
-builtins = TypesRegistry()
+postgres_types = TypesRegistry()
 
 # Use tools/update_oids.py to update this data.
 for r in [
@@ -220,10 +240,10 @@ for r in [
     ("xml", 142, 143, 0, "xml", ","),
     # autogenerated: end
 ]:
-    builtins.add(BuiltinTypeInfo(*r))
+    postgres_types.add(BuiltinTypeInfo(*r))
 
 
 # A few oids used a bit everywhere
 INVALID_OID = 0
-TEXT_OID = builtins["text"].oid
-TEXT_ARRAY_OID = builtins["text"].array_oid
+TEXT_OID = postgres_types["text"].oid
+TEXT_ARRAY_OID = postgres_types["text"].array_oid
index 828c3642144fe01964313c7cafab0e816737da1c..dc70082b9b3dd89b14683b4c4236ade5b02e160b 100644 (file)
@@ -4,7 +4,7 @@ psycopg3 types package
 
 # Copyright (C) 2020-2021 The Psycopg Team
 
-from ..oids import builtins, INVALID_OID
+from ..oids import INVALID_OID
 from ..proto import AdaptContext
 
 # Register default adapters
@@ -227,4 +227,4 @@ def register_default_globals(ctx: AdaptContext) -> None:
     RecordLoader.register("record", ctx)
     RecordBinaryLoader.register("record", ctx)
 
-    array.register_all_arrays()
+    array.register_all_arrays(ctx)
index 6baa3b2a545c04d5b38d75dc6807fe5e502d593c..b68bf77c35bec2305b985f6ea406ea5f181a0538 100644 (file)
@@ -10,7 +10,7 @@ from typing import Any, Iterator, List, Optional, Set, Tuple, Type
 
 from .. import pq
 from .. import errors as e
-from ..oids import builtins, TEXT_OID, TEXT_ARRAY_OID, INVALID_OID
+from ..oids import postgres_types, TEXT_OID, TEXT_ARRAY_OID, INVALID_OID
 from ..adapt import Buffer, Dumper, Loader, Transformer
 from ..adapt import Format as Pg3Format
 from ..proto import AdaptContext
@@ -21,6 +21,7 @@ class BaseListDumper(Dumper):
         super().__init__(cls, context)
         self._tx = Transformer(context)
         self.sub_dumper: Optional[Dumper] = None
+        self._types = context.adapters.types if context else postgres_types
 
     def get_key(self, obj: List[Any], format: Pg3Format) -> Tuple[type, ...]:
         item = self._find_list_element(obj)
@@ -87,12 +88,10 @@ class BaseListDumper(Dumper):
         Return the oid of the array from the oid of the base item.
 
         Fall back on text[].
-        TODO: we shouldn't consider builtins only, but other adaptation
-        contexts too
         """
         oid = 0
         if base_oid:
-            info = builtins.get(base_oid)
+            info = self._types.get(base_oid)
             if info:
                 oid = info.array_oid
 
@@ -332,14 +331,14 @@ def register(
         loader.register(array_oid, context=context)
 
 
-def register_all_arrays() -> None:
+def register_all_arrays(ctx: AdaptContext) -> None:
     """
     Associate the array oid of all the types in Loader.globals.
 
     This function is designed to be called once at import time, after having
     registered all the base loaders.
     """
-    for t in builtins:
+    for t in ctx.adapters.types:
         # TODO: handle different delimiters (box)
         if t.array_oid and getattr(t, "delimiter", None) == ",":
             register(t.array_oid, t.oid, name=t.name)
index 612a547ec1777e9247061e0711bdb8cd8e5ecd08..c43a68b1c7393b33edb6e46ae2e1258043c59032 100644 (file)
@@ -186,7 +186,7 @@ class SequenceDumper(Dumper):
 class TupleDumper(SequenceDumper):
 
     # Should be this, but it doesn't work
-    # _oid = builtins["record"].oid
+    # _oid = postgres_types["record"].oid
 
     def dump(self, obj: Tuple[Any, ...]) -> bytes:
         return self._dump_sequence(obj, b"(", b")", b",")
index ad918dbd0af2f27180089496907d2db93e2f6588..478e969d38fc0c0262ce00773fee9480ba5e1166 100644 (file)
@@ -10,7 +10,7 @@ from datetime import date, datetime, time, timedelta
 from typing import cast, Optional, Tuple, Union
 
 from ..pq import Format
-from ..oids import builtins
+from ..oids import postgres_types as builtins
 from ..adapt import Buffer, Dumper, Loader, Format as Pg3Format
 from ..proto import AdaptContext
 from ..errors import InterfaceError, DataError
index 85ad0728928b0a868a28464fff643fe2447e69da..1e021cabcd1d8cbc1078882942c637b9095ad58f 100644 (file)
@@ -8,7 +8,7 @@ import json
 from typing import Any, Callable, Optional
 
 from ..pq import Format
-from ..oids import builtins
+from ..oids import postgres_types as builtins
 from ..adapt import Buffer, Dumper, Loader
 from ..errors import DataError
 
index 9166a74bed605746813d04870445d82def572399..c08e6971d3bbf23f8cd169c5054bb6e385862c46 100644 (file)
@@ -7,7 +7,7 @@ Adapters for network types.
 from typing import Callable, Optional, Union, TYPE_CHECKING
 
 from ..pq import Format
-from ..oids import builtins
+from ..oids import postgres_types as builtins
 from ..adapt import Buffer, Dumper, Loader
 from ..proto import AdaptContext
 
index 13c02252d5b3e8f0d543a83a25958fbecee0b8f4..36b4e9cd4eae62ef3ee92b854476e096192c75d6 100644 (file)
@@ -9,7 +9,7 @@ from typing import Any, Callable, Dict, Tuple, cast
 from decimal import Decimal
 
 from ..pq import Format
-from ..oids import builtins
+from ..oids import postgres_types as builtins
 from ..adapt import Buffer, Dumper, Loader
 from ..adapt import Format as Pg3Format
 from ..wrappers.numeric import Int2, Int4, Int8, IntNumeric
index 37c7e0af0f599778c3fafd0c1cca7ad60247a5c4..5e2165ee079841b1c9eeb27c23becb534c689fe0 100644 (file)
@@ -13,7 +13,7 @@ from datetime import date, datetime
 from .. import sql
 from .. import errors as e
 from ..pq import Format
-from ..oids import builtins, TypeInfo, INVALID_OID
+from ..oids import postgres_types as builtins, TypeInfo, INVALID_OID
 from ..adapt import Buffer, Dumper, Loader, Format as Pg3Format
 from ..proto import AdaptContext
 
@@ -227,6 +227,7 @@ class RangeDumper(SequenceDumper):
     def __init__(self, cls: type, context: Optional[AdaptContext] = None):
         super().__init__(cls, context)
         self.sub_dumper: Optional[Dumper] = None
+        self._types = context.adapters.types if context else builtins
 
     def dump(self, obj: Range[Any]) -> bytes:
         if not obj:
@@ -283,7 +284,7 @@ class RangeDumper(SequenceDumper):
         TODO: we shouldn't consider builtins only, but other adaptation
         contexts too
         """
-        info = builtins.get_range(sub_oid)
+        info = self._types.get_range(sub_oid)
         return info.oid if info else INVALID_OID
 
 
index 443a4ec319fe8a7134bfa1551d9f75d98a2f7859..539c150527c620c48ce99d660ea168c55500411b 100644 (file)
@@ -5,7 +5,7 @@ Adapters for None and boolean.
 # Copyright (C) 2020-2021 The Psycopg Team
 
 from ..pq import Format
-from ..oids import builtins
+from ..oids import postgres_types as builtins
 from ..adapt import Buffer, Dumper, Loader
 
 
index d87cf8ea7a02250b395b1d0c273f1570a731f553..c298b1cc45d51401cbe587d719029acf5cf7f771 100644 (file)
@@ -7,7 +7,7 @@ Adapters for textual types.
 from typing import Optional, Union, TYPE_CHECKING
 
 from ..pq import Format, Escaping
-from ..oids import builtins
+from ..oids import postgres_types as builtins
 from ..adapt import Buffer, Dumper, Loader
 from ..proto import AdaptContext
 from ..errors import DataError
index ec973ecacd4291fcd0bd18f4d1b9faa45babf8e0..67987322bcc796412badfee767b455bc3c75527b 100644 (file)
@@ -7,7 +7,7 @@ Adapters for the UUID type.
 from typing import Callable, Optional, TYPE_CHECKING
 
 from ..pq import Format
-from ..oids import builtins
+from ..oids import postgres_types as builtins
 from ..adapt import Buffer, Dumper, Loader
 from ..proto import AdaptContext
 
index 1a1c188c6c2e3f4d98b66cb55aceaa5980b5cd13..e75fb426a5d72f8e2e4ce5e34fc96a3bd9eca2da 100644 (file)
@@ -160,10 +160,6 @@ cdef class CLoader:
         context: Optional["AdaptContext"] = None,
         int format = PQ_TEXT,
     ) -> None:
-        if isinstance(oid, str):
-            from psycopg3.oids import builtins
-            oid = builtins[oid].oid
-
         if context is not None:
             adapters = context.adapters
         else:
index fbd806bec9c0d6d8233d13e873b018ad6342939f..17cc5803b2865e3dc6777e07b2b3391dbdb81ea6 100644 (file)
@@ -8,7 +8,6 @@ import pytest
 
 import psycopg3
 from psycopg3 import sql
-from psycopg3.oids import builtins
 from psycopg3.adapt import Format
 
 
@@ -70,10 +69,11 @@ class Faker:
         record = self.make_record(nulls=0)
         tx = psycopg3.adapt.Transformer(self.conn)
         types = []
+        registry = self.conn.adapters.types
         for value in record:
             dumper = tx.get_dumper(value, self.format)
             dumper.dump(value)  # load the oid if it's dynamic (e.g. array)
-            info = builtins.get(dumper.oid) or builtins.get("text")
+            info = registry.get(dumper.oid) or registry.get("text")
             if dumper.oid == info.array_oid:
                 types.append(sql.SQL("{}[]").format(sql.Identifier(info.name)))
             else:
index 11759560d39072cfbf01b0cbfd1bd174fa6f4652..27607d92618e888024b32bf13cd385d1c967270f 100644 (file)
@@ -5,7 +5,7 @@ import pytest
 import psycopg3
 from psycopg3 import pq
 from psycopg3.adapt import Transformer, Format, Dumper, Loader
-from psycopg3.oids import builtins, TEXT_OID
+from psycopg3.oids import postgres_types as builtins, TEXT_OID
 
 
 @pytest.mark.parametrize(
index 0ff86ea83a5808a2a4a0536da37a293579199516..f0aca994055e9ac9d9f933620f7e6a396be97e2a 100644 (file)
@@ -11,7 +11,6 @@ from psycopg3 import pq
 from psycopg3 import sql
 from psycopg3 import errors as e
 from psycopg3.pq import Format
-from psycopg3.oids import builtins
 from psycopg3.adapt import Format as PgFormat
 from psycopg3.types.numeric import Int4
 
@@ -94,10 +93,7 @@ def test_read_rows(conn, format, typetype):
             select 10::int4, 'hello'::text, '{{0.0,1.0}}'::float8[]
         ) to stdout (format {format.name})"""
     ) as copy:
-        types = ["int4", "text", "float8[]"]
-        if typetype == "oids":
-            types = [builtins.get_oid(t) for t in types]
-        copy.set_types(types)
+        copy.set_types(["int4", "text", "float8[]"])
         row = copy.read_row()
         assert copy.read_row() is None
 
@@ -111,9 +107,7 @@ def test_rows(conn, format):
     with cur.copy(
         f"copy ({sample_values}) to stdout (format {format.name})"
     ) as copy:
-        copy.set_types(
-            [builtins["int4"].oid, builtins["int4"].oid, builtins["text"].oid]
-        )
+        copy.set_types(["int4", "int4", "text"])
         rows = list(copy.rows())
 
     assert rows == sample_records
@@ -130,7 +124,7 @@ def test_copy_out_allchars(conn, format):
         "copy (select unnest({}::text[])) to stdout (format {})"
     ).format(chars, sql.SQL(format.name))
     with cur.copy(query) as copy:
-        copy.set_types([builtins["text"].oid])
+        copy.set_types(["text"])
         while 1:
             row = copy.read_row()
             if not row:
index 236b86d6d1fc0e116b475a0ad9add81af773bff5..bf3a5ef905772ca9ad8c1f0d3abb605c016bb918 100644 (file)
@@ -11,7 +11,6 @@ from psycopg3 import pq
 from psycopg3 import sql
 from psycopg3 import errors as e
 from psycopg3.pq import Format
-from psycopg3.oids import builtins
 from psycopg3.adapt import Format as PgFormat
 
 from .test_copy import sample_text, sample_binary, sample_binary_rows  # noqa
@@ -72,12 +71,7 @@ async def test_read_rows(aconn, format):
     async with cur.copy(
         f"copy ({sample_values}) to stdout (format {format.name})"
     ) as copy:
-        # TODO: should be passed by name
-        # big refactoring to be had, to have builtins not global and merged
-        # to adaptation context I guess...
-        copy.set_types(
-            [builtins["int4"].oid, builtins["int4"].oid, builtins["text"].oid]
-        )
+        copy.set_types("int4 int4 text".split())
         rows = []
         while 1:
             row = await copy.read_row()
@@ -95,9 +89,7 @@ async def test_rows(aconn, format):
     async with cur.copy(
         f"copy ({sample_values}) to stdout (format {format.name})"
     ) as copy:
-        copy.set_types(
-            [builtins["int4"].oid, builtins["int4"].oid, builtins["text"].oid]
-        )
+        copy.set_types("int4 int4 text".split())
         rows = []
         async for row in copy.rows():
             rows.append(row)
@@ -116,7 +108,7 @@ async def test_copy_out_allchars(aconn, format):
         "copy (select unnest({}::text[])) to stdout (format {})"
     ).format(chars, sql.SQL(format.name))
     async with cur.copy(query) as copy:
-        copy.set_types([builtins["text"].oid])
+        copy.set_types(["text"])
         while 1:
             row = await copy.read_row()
             if not row:
index b2d905b1bf5b39a1dd8a6e5283820bf73aa71b21..481dbf5e496098c3208bc8d038714a862d1bc938 100644 (file)
@@ -7,7 +7,7 @@ import pytest
 
 import psycopg3
 from psycopg3 import sql
-from psycopg3.oids import builtins
+from psycopg3.oids import postgres_types as builtins
 from psycopg3.adapt import Format
 
 
index f1b19ae7a2d79dd0eee120d625c25f3ad4f9052d..22087683143fc8acc10849567ef1b83f05e866be 100644 (file)
@@ -2,7 +2,7 @@ import pytest
 import psycopg3
 from psycopg3 import pq
 from psycopg3 import sql
-from psycopg3.oids import builtins
+from psycopg3.oids import postgres_types as builtins
 from psycopg3.adapt import Format, Transformer
 from psycopg3.types import array
 
index b9aadbd3c6013d0fa8e4437d75fdf662ce4c5705..32d2ad75a5f8e3c975351949cceb3a4cbe70ffcc 100644 (file)
@@ -2,7 +2,7 @@ import pytest
 
 from psycopg3 import pq
 from psycopg3.sql import Identifier
-from psycopg3.oids import builtins
+from psycopg3.oids import postgres_types as builtins
 from psycopg3.adapt import Format, global_adapters
 from psycopg3.types.composite import CompositeInfo
 
index e02e3db8108d84478766b8d13a439de79c69868f..437601504d2d72b606e978286faee084b3924967 100644 (file)
@@ -5,7 +5,6 @@ import pytest
 
 from psycopg3 import pq
 from psycopg3 import sql
-from psycopg3.oids import builtins
 from psycopg3.adapt import Transformer, Format
 from psycopg3.types.numeric import FloatLoader
 
@@ -115,7 +114,7 @@ def test_load_int(conn, val, pgtype, want, fmt_out):
     cur = conn.cursor(binary=fmt_out)
     cur.execute(f"select %s::{pgtype}", (val,))
     assert cur.pgresult.fformat(0) == fmt_out
-    assert cur.pgresult.ftype(0) == builtins[pgtype].oid
+    assert cur.pgresult.ftype(0) == conn.adapters.types[pgtype].oid
     result = cur.fetchone()[0]
     assert result == want
     assert type(result) is type(want)
@@ -123,7 +122,7 @@ def test_load_int(conn, val, pgtype, want, fmt_out):
     # arrays work too
     cur.execute(f"select array[%s::{pgtype}]", (val,))
     assert cur.pgresult.fformat(0) == fmt_out
-    assert cur.pgresult.ftype(0) == builtins[pgtype].array_oid
+    assert cur.pgresult.ftype(0) == conn.adapters.types[pgtype].array_oid
     result = cur.fetchone()[0]
     assert result == [want]
     assert type(result[0]) is type(want)
@@ -232,7 +231,7 @@ def test_load_float(conn, val, pgtype, want, fmt_out):
     cur = conn.cursor(binary=fmt_out)
     cur.execute(f"select %s::{pgtype}", (val,))
     assert cur.pgresult.fformat(0) == fmt_out
-    assert cur.pgresult.ftype(0) == builtins[pgtype].oid
+    assert cur.pgresult.ftype(0) == conn.adapters.types[pgtype].oid
     result = cur.fetchone()[0]
 
     def check(result, want):
@@ -249,7 +248,7 @@ def test_load_float(conn, val, pgtype, want, fmt_out):
 
     cur.execute(f"select array[%s::{pgtype}]", (val,))
     assert cur.pgresult.fformat(0) == fmt_out
-    assert cur.pgresult.ftype(0) == builtins[pgtype].array_oid
+    assert cur.pgresult.ftype(0) == conn.adapters.types[pgtype].array_oid
     result = cur.fetchone()[0]
     assert isinstance(result, list)
     check(result[0], want)
@@ -357,7 +356,7 @@ def test_load_numeric_binary(conn):
 )
 def test_numeric_as_float(conn, val):
     cur = conn.cursor()
-    FloatLoader.register(builtins["numeric"].oid, cur)
+    FloatLoader.register(conn.adapters.types["numeric"].oid, cur)
 
     val = Decimal(val)
     cur.execute("select %s as val", (val,))
index 294b6b5c8463ca579e04b8c35e4e47fd64456ba6..b69371c91614b79a98608857b72c4edd42abe3ad 100644 (file)
@@ -5,7 +5,6 @@ from decimal import Decimal
 import pytest
 
 from psycopg3.sql import Identifier
-from psycopg3.oids import builtins
 from psycopg3.types import range as mrange
 from psycopg3.types.range import Range
 
@@ -164,7 +163,7 @@ def test_fetch_info(conn, testrange, name, subtype):
     assert info.name == "testrange"
     assert info.oid > 0
     assert info.oid != info.array_oid > 0
-    assert info.range_subtype == builtins[subtype].oid
+    assert info.range_subtype == conn.adapters.types[subtype].oid
 
 
 def test_fetch_info_not_found(conn):
@@ -179,7 +178,7 @@ async def test_fetch_info_async(aconn, testrange, name, subtype):
     assert info.name == "testrange"
     assert info.oid > 0
     assert info.oid != info.array_oid > 0
-    assert info.range_subtype == builtins[subtype].oid
+    assert info.range_subtype == aconn.adapters.types[subtype].oid
 
 
 @pytest.mark.asyncio
index 03b26d06849032362e5d97414256d45050df36ce..8ec3102fe0a3ec8b00fac5b613b9d67612b65787 100644 (file)
@@ -2,7 +2,7 @@ import pytest
 
 from psycopg3 import pq
 from psycopg3 import sql
-from psycopg3.oids import builtins
+from psycopg3.oids import postgres_types as builtins
 from psycopg3.adapt import Transformer, Format