Just use `cls`, as the class method is available to all the subclasses.
def register(
cls,
oid: int,
- loader: LoaderType,
context: AdaptContext = None,
format: Format = Format.TEXT,
- ) -> LoaderType:
+ ) -> None:
if not isinstance(oid, int):
raise TypeError(
f"loaders should be registered on oid, got {oid} instead"
)
- if not (
- isinstance(loader, type) and issubclass(loader, _loader_classes)
- ):
- raise TypeError(
- f"loaders should be Loader subclasses, got {loader} instead"
- )
-
where = context.loaders if context is not None else Loader.globals
- where[oid, format] = loader
- return loader
+ where[oid, format] = cls
@classmethod
- def register_binary(
- cls, oid: int, loader: LoaderType, context: AdaptContext = None
- ) -> LoaderType:
- return cls.register(oid, loader, context, format=Format.BINARY)
+ def register_binary(cls, oid: int, context: AdaptContext = None) -> None:
+ cls.register(oid, context, format=Format.BINARY)
@classmethod
def text(cls, oid: int) -> Callable[[LoaderType], LoaderType]:
def text_(loader: LoaderType) -> LoaderType:
- cls.register(oid, loader)
+ loader.register(oid)
return loader
return text_
@classmethod
def binary(cls, oid: int) -> Callable[[LoaderType], LoaderType]:
def binary_(loader: LoaderType) -> LoaderType:
- cls.register_binary(oid, loader)
+ loader.register_binary(oid)
return loader
return binary_
import re
import struct
-from typing import Any, Generator, List, Optional
+from typing import Any, Generator, List, Optional, Type
from .. import errors as e
from ..adapt import Format, Dumper, Loader, Transformer
(Format.TEXT, TextArrayLoader),
(Format.BINARY, BinaryArrayLoader),
):
- tcname = f"{name.title()}Array{format.name.title()}Loader"
- t = type(tcname, (base,), {"base_oid": base_oid})
- Loader.register(array_oid, t, context=context, format=format)
+ lname = f"{name.title()}Array{format.name.title()}Loader"
+ loader: Type[Loader] = type(lname, (base,), {"base_oid": base_oid})
+ loader.register(array_oid, context=context, format=format)
def register_all_arrays() -> None:
import re
import struct
from collections import namedtuple
-from typing import Any, Callable, Generator, Sequence, Tuple
+from typing import Any, Callable, Generator, Sequence, Tuple, Type
from typing import Optional, TYPE_CHECKING
from .. import pq
info.name, [f.name for f in info.fields]
)
+ loader: Type[Loader]
+
# generate and register a customized text loader
loader = type(
f"{info.name.title()}Loader",
"fields_types": tuple(f.type_oid for f in info.fields),
},
)
- Loader.register(info.oid, loader, context=context, format=Format.TEXT)
+ loader.register(info.oid, context=context, format=Format.TEXT)
# generate and register a customized binary loader
loader = type(
(BinaryCompositeLoader,),
{"factory": factory},
)
- Loader.register(info.oid, loader, context=context, format=Format.BINARY)
+ loader.register(info.oid, context=context, format=Format.BINARY)
if info.array_oid:
array.register(
from psycopg3_c.adapt cimport cloader_func, get_context_func
from psycopg3_c cimport libpq as impl
+from psycopg3.pq.enums import Format
+
import logging
logger = logging.getLogger("psycopg3.adapt")
PyBytes_AsStringAndSize(data, &buffer, &length)
return self.cload(data, length)
+ @classmethod
+ def register(
+ cls,
+ oid: int,
+ context: "AdaptContext" = None,
+ format: Format = Format.TEXT,
+ ) -> None:
+ if not isinstance(oid, int):
+ raise TypeError(
+ f"loaders should be registered on oid, got {oid} instead"
+ )
+
+ from psycopg3.adapt import Loader
+
+ where = context.loaders if context else Loader.globals
+ where[oid, format] = cls
+
+ @classmethod
+ def register_binary(
+ cls, oid: int, context: AdaptContext = None
+ ) -> None:
+ cls.register(oid, context, format=Format.BINARY)
+
def register_builtin_c_loaders():
"""
from psycopg3.adapt import Loader
from psycopg3.types import builtins
- Loader.register(builtins["int2"].oid, TextIntLoader)
- Loader.register(builtins["int4"].oid, TextIntLoader)
- Loader.register(builtins["int8"].oid, TextIntLoader)
- Loader.register(builtins["oid"].oid, TextIntLoader)
-
- Loader.register_binary(builtins["int2"].oid, BinaryInt2Loader)
- Loader.register_binary(builtins["int4"].oid, BinaryInt4Loader)
- Loader.register_binary(builtins["int8"].oid, BinaryInt8Loader)
- Loader.register_binary(builtins["oid"].oid, BinaryOidLoader)
- Loader.register_binary(builtins["bool"].oid, BinaryBoolLoader)
+ TextIntLoader.register(builtins["int2"].oid)
+ TextIntLoader.register(builtins["int4"].oid)
+ TextIntLoader.register(builtins["int8"].oid)
+ TextIntLoader.register(builtins["oid"].oid)
+
+ BinaryInt2Loader.register_binary(builtins["int2"].oid)
+ BinaryInt4Loader.register_binary(builtins["int4"].oid)
+ BinaryInt8Loader.register_binary(builtins["int8"].oid)
+ BinaryOidLoader.register_binary(builtins["oid"].oid)
+ BinaryBoolLoader.register_binary(builtins["bool"].oid)
from psycopg3.adapt import Loader
from psycopg3.types import builtins
- Loader.register(0, StringLoader) # INVALID_OID
- Loader.register(builtins["text"].oid, StringLoader)
- Loader.register_binary(builtins["text"].oid, StringLoader)
- Loader.register(builtins["varchar"].oid, StringLoader)
- Loader.register_binary(builtins["varchar"].oid, StringLoader)
-
- Loader.register(builtins['bytea'].oid, TextByteaLoader)
- Loader.register_binary(builtins['bytea'].oid, BinaryByteaLoader)
+ StringLoader.register(0) # INVALID_OID
+ StringLoader.register(builtins["text"].oid)
+ StringLoader.register_binary(builtins["text"].oid)
+ StringLoader.register(builtins["varchar"].oid)
+ StringLoader.register_binary(builtins["varchar"].oid)
+
+ TextByteaLoader.register(builtins['bytea'].oid)
+ BinaryByteaLoader.register_binary(builtins['bytea'].oid)
def test_load_connection_ctx(conn):
- Loader.register(TEXT_OID, make_loader("t"), conn)
- Loader.register_binary(TEXT_OID, make_loader("b"), conn)
+ make_loader("t").register(TEXT_OID, conn)
+ make_loader("b").register_binary(TEXT_OID, conn)
r = conn.cursor().execute("select 'hello'::text").fetchone()
assert r == ("hellot",)
def test_load_cursor_ctx(conn):
- Loader.register(TEXT_OID, make_loader("t"), conn)
- Loader.register_binary(TEXT_OID, make_loader("b"), conn)
+ make_loader("t").register(TEXT_OID, conn)
+ make_loader("b").register_binary(TEXT_OID, conn)
cur = conn.cursor()
- Loader.register(TEXT_OID, make_loader("tc"), cur)
- Loader.register_binary(TEXT_OID, make_loader("bc"), cur)
+ make_loader("tc").register(TEXT_OID, cur)
+ make_loader("bc").register_binary(TEXT_OID, cur)
r = cur.execute("select 'hello'::text").fetchone()
assert r == ("hellotc",)
@pytest.mark.parametrize("fmt_out", [Format.TEXT, Format.BINARY])
def test_load_cursor_ctx_nested(conn, sql, obj, fmt_out):
cur = conn.cursor(format=fmt_out)
- Loader.register(TEXT_OID, make_loader("c"), cur, format=fmt_out)
+ make_loader("c").register(TEXT_OID, cur, format=fmt_out)
cur.execute(f"select {sql}")
res = cur.fetchone()[0]
assert res == obj
import pytest
from psycopg3 import sql
-from psycopg3.adapt import Loader, Transformer, Format
+from psycopg3.adapt import Transformer, Format
from psycopg3.types import builtins
from psycopg3.types.numeric import TextFloatLoader
)
def test_numeric_as_float(conn, val):
cur = conn.cursor()
- Loader.register(builtins["numeric"].oid, TextFloatLoader, cur)
+ TextFloatLoader.register(builtins["numeric"].oid, cur)
val = Decimal(val)
cur.execute("select %s", (val,))