]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
refactor(enum): rename python_type -> enum, enum_labels -> labels on EnumInfo
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 18 Apr 2022 17:23:32 +0000 (19:23 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Fri, 22 Apr 2022 03:03:24 +0000 (05:03 +0200)
The previous name were lifted from the composite adapters. However, that
class would have had a more ambiguous "type" attribute, and "types" for
the fields, hence the decision of using "python_" and "fields_" prefix
to disambiguate.

In the enum adapters context, enum is not ambiguous, so a more natural
name seems preferred.

docs/basic/adapt.rst
psycopg/psycopg/_typeinfo.py
psycopg/psycopg/types/enum.py
tests/types/test_enum.py

index 139c5effc5eedaa6c1ab8a6ad165bdd9557a236f..d1988141857af3c9b5d072ceec6d45746a355a19 100644 (file)
@@ -395,11 +395,11 @@ using `~psycopg.types.enum.register_enum()`.
    documentation for the generic usage, especially the
    `~psycopg.types.TypeInfo.fetch()` method.
 
-   .. attribute:: enum_labels
+   .. attribute:: labels
 
        Contains labels available in the PostgreSQL enum type.
 
-   .. attribute:: python_type
+   .. attribute:: enum
 
        After `register_enum()` is called, it will contain the python type
        mapping to the registered enum.
@@ -409,7 +409,7 @@ using `~psycopg.types.enum.register_enum()`.
    After registering, fetching data of the registered enum will cast
    PostgreSQL enum labels into corresponding Python enum labels.
 
-   If no ``python_type`` is specified, a `Enum` is created based on
+   If no `!enum` is specified, a new `Enum` is created based on
    PostgreSQL enum labels.
 
 Example::
@@ -427,7 +427,7 @@ Example::
     >>> info = EnumInfo.fetch(conn, "user_role")
     >>> register_enum(info, UserRole, conn)
 
-    >>> some_editor = info.python_type.EDITOR
+    >>> some_editor = info.enum.EDITOR
     >>> some_editor
     <UserRole.EDITOR: 2>
 
index dfe770edc5c727699f46bbd75595509e9a37eac2..933cb47988274486321ac12c741441cc3460927b 100644 (file)
@@ -295,12 +295,12 @@ class EnumInfo(TypeInfo):
         name: str,
         oid: int,
         array_oid: int,
-        enum_labels: Sequence[str],
+        labels: Sequence[str],
     ):
         super().__init__(name, oid, array_oid)
-        self.enum_labels = enum_labels
+        self.labels = labels
         # Will be set by register_enum()
-        self.python_type: Optional[Type[Enum]] = None
+        self.enum: Optional[Type[Enum]] = None
 
     @classmethod
     def _get_info_query(
@@ -309,7 +309,7 @@ class EnumInfo(TypeInfo):
         return """\
 SELECT
     t.typname AS name, t.oid AS oid, t.typarray AS array_oid,
-    array_agg(x.enumlabel) AS enum_labels
+    array_agg(x.enumlabel) AS labels
 FROM pg_type t
 LEFT JOIN (
     SELECT e.enumtypid, e.enumlabel
index aa99ab52f97d44233d68397fc9452ad7d991e661..c71fc19e3ac3a25a23a128c333cd1426c5bff8aa 100644 (file)
@@ -18,7 +18,7 @@ E = TypeVar("E", bound=Enum)
 
 class EnumLoader(Loader, Generic[E]):
     _encoding = "utf-8"
-    python_type: Type[E]
+    enum: Type[E]
 
     def __init__(self, oid: int, context: Optional[AdaptContext] = None):
         super().__init__(oid, context)
@@ -32,7 +32,7 @@ class EnumLoader(Loader, Generic[E]):
         else:
             label = data.decode(self._encoding)
 
-        return self.python_type[label]
+        return self.enum[label]
 
 
 class EnumBinaryLoader(EnumLoader[E]):
@@ -59,14 +59,14 @@ class EnumBinaryDumper(EnumDumper):
 
 def register_enum(
     info: EnumInfo,
-    python_type: Optional[Type[E]] = None,
+    enum: Optional[Type[E]] = None,
     context: Optional[AdaptContext] = None,
 ) -> None:
     """Register the adapters to load and dump a enum type.
 
     :param info: The object with the information about the enum to register.
-    :param python_type: Python enum type matching to the Postgres one. If `!None`,
-        the type will be generated and put into info.python_type.
+    :param enum: Python enum type matching to the Postgres one. If `!None`,
+        a new enum will be generated and exposed as `EnumInfo.enum`.
     :param context: The context where to register the adapters. If `!None`,
         register it globally.
     """
@@ -74,39 +74,34 @@ def register_enum(
     if not info:
         raise TypeError("no info passed. Is the requested enum available?")
 
-    if python_type is None:
-        python_type = cast(
-            Type[E],
-            Enum(info.name.title(), {label: label for label in info.enum_labels}),
-        )
+    if enum is None:
+        enum = cast(Type[E], Enum(info.name.title(), info.labels, module=__name__))
 
-    info.python_type = python_type
+    info.enum = enum
     adapters = context.adapters if context else postgres.adapters
     info.register(context)
 
-    attribs: Dict[str, Any] = {"python_type": info.python_type}
+    attribs: Dict[str, Any] = {"enum": info.enum}
 
     loader_base = EnumLoader
-    name = f"{info.name.title()}{loader_base.__name__}"
+    name = f"{info.name.title()}Loader"
     loader = type(name, (loader_base,), attribs)
     adapters.register_loader(info.oid, loader)
 
     loader_base = EnumBinaryLoader
-    name = f"{info.name.title()}{loader_base.__name__}"
+    name = f"{info.name.title()}BinaryLoader"
     loader = type(name, (loader_base,), attribs)
     adapters.register_loader(info.oid, loader)
 
     attribs = {"oid": info.oid}
 
-    dumper_base: Type[Dumper] = EnumBinaryDumper
-    name = f"{info.name.title()}{dumper_base.__name__}"
-    dumper = type(name, (dumper_base,), attribs)
-    adapters.register_dumper(info.python_type, dumper)
+    name = f"{enum.__name__}BinaryDumper"
+    dumper = type(name, (EnumBinaryDumper,), attribs)
+    adapters.register_dumper(info.enum, dumper)
 
-    dumper_base = EnumDumper
-    name = f"{info.name.title()}{dumper_base.__name__}"
-    dumper = type(name, (dumper_base,), attribs)
-    adapters.register_dumper(info.python_type, dumper)
+    name = f"{enum.__name__}Dumper"
+    dumper = type(name, (EnumDumper,), attribs)
+    adapters.register_dumper(info.enum, dumper)
 
 
 def register_default_adapters(context: AdaptContext) -> None:
index eda761ee58d2620dbe651cad2542888cd55e6ba0..7301ce0f9cd632fa2498100182d56afc139587d6 100644 (file)
@@ -59,18 +59,18 @@ def test_fetch_info(conn, testenum):
     assert info.name == name
     assert info.oid > 0
     assert info.oid != info.array_oid > 0
-    assert len(info.enum_labels) == len(labels)
-    assert info.enum_labels == labels
+    assert len(info.labels) == len(labels)
+    assert info.labels == labels
 
 
 def test_register_makes_a_type(conn, testenum):
     name, enum, labels = testenum
     info = EnumInfo.fetch(conn, name)
     assert info
-    assert info.python_type is None
+    assert info.enum is None
     register_enum(info, context=conn)
-    assert info.python_type is not None
-    assert [e.name for e in info.python_type] == [e.name for e in enum]
+    assert info.enum is not None
+    assert [e.name for e in info.enum] == [e.name for e in enum]
 
 
 @pytest.mark.parametrize("encoding", encodings)
@@ -143,7 +143,7 @@ def test_generic_enum_loader(conn, testenum, encoding, fmt_in, fmt_out):
 
     for label in labels:
         cur = conn.execute(f"select %{fmt_in}::{name}", [label], binary=fmt_out)
-        assert cur.fetchone()[0] == info.python_type(label)
+        assert cur.fetchone()[0] == info.enum(label)
 
 
 @pytest.mark.parametrize("encoding", encodings)
@@ -183,7 +183,7 @@ def test_generic_enum_array_loader(conn, testenum, encoding, fmt_in, fmt_out):
     register_enum(info, enum, conn)
 
     cur = conn.execute(f"select %{fmt_in}::{name}[]", [labels], binary=fmt_out)
-    assert cur.fetchone()[0] == list(info.python_type)
+    assert cur.fetchone()[0] == list(info.enum)
 
 
 @pytest.mark.asyncio
@@ -194,8 +194,8 @@ async def test_fetch_info_async(aconn, testenum):
     assert info.name == name
     assert info.oid > 0
     assert info.oid != info.array_oid > 0
-    assert len(info.enum_labels) == len(labels)
-    assert info.enum_labels == labels
+    assert len(info.labels) == len(labels)
+    assert info.labels == labels
 
 
 @pytest.mark.asyncio