From: Daniele Varrazzo Date: Tue, 1 Dec 2020 00:55:02 +0000 (+0000) Subject: Dumper and Loader made abstract classes X-Git-Tag: 3.0.dev0~298 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=652cfd024f1ef560d1bac9409acf8509a1fd4c53;p=thirdparty%2Fpsycopg.git Dumper and Loader made abstract classes --- diff --git a/docs/adaptation.rst b/docs/adaptation.rst index 4eaa66faa..0a560b70c 100644 --- a/docs/adaptation.rst +++ b/docs/adaptation.rst @@ -102,6 +102,12 @@ Objects involved in types adaptation .. autoclass:: Dumper(src, context=None) + This is an abstract base class: subclasses *must* implement the `dump()` + method. They *may* implement `oid` (as attribute or property) in order to + override the oid type oid; if not PostgreSQL will try to infer the type + from the context, but this may fail in some contexts and may require a + cast. + :param src: The type that will be managed by this dumper. :type src: type :param context: The context where the transformation is performed. If not @@ -133,6 +139,10 @@ Objects involved in types adaptation .. autoattribute:: oid :annotation: int + .. admonition:: todo + + Document how to find type OIDs in a database. + .. automethod:: register(src, context=None, format=Format.TEXT) You should call this method on the `Dumper` subclass you create, @@ -154,6 +164,9 @@ Objects involved in types adaptation .. autoclass:: Loader(oid, context=None) + This is an abstract base class: subclasses *must* implement the `load()` + method. + :param oid: The type that will be managed by this dumper. :type oid: int :param context: The context where the transformation is performed. If not diff --git a/psycopg3/psycopg3/adapt.py b/psycopg3/psycopg3/adapt.py index 669a2984e..7938d4118 100644 --- a/psycopg3/psycopg3/adapt.py +++ b/psycopg3/psycopg3/adapt.py @@ -4,6 +4,7 @@ Entry point into the adaptation system. # Copyright (C) 2020 The Psycopg Team +from abc import ABC, abstractmethod from typing import Any, cast, Callable, Optional, Type, Union from . import pq @@ -17,7 +18,7 @@ from .connection import BaseConnection TEXT_OID = builtins["text"].oid -class Dumper: +class Dumper(ABC): """ Convert Python object of the type *src* to PostgreSQL representation. """ @@ -30,9 +31,10 @@ class Dumper: self.context = context self.connection = _connection_from_context(context) + @abstractmethod def dump(self, obj: Any) -> bytes: """Convert the object *obj* to PostgreSQL representation.""" - raise NotImplementedError() + ... def quote(self, obj: Any) -> bytes: """Convert the object *obj* to escaped representation.""" @@ -87,7 +89,7 @@ class Dumper: return binary_ -class Loader: +class Loader(ABC): """ Convert PostgreSQL objects with OID *oid* to Python objects. """ @@ -100,9 +102,10 @@ class Loader: self.context = context self.connection = _connection_from_context(context) + @abstractmethod def load(self, data: bytes) -> Any: """Convert a PostgreSQL value to a Python object.""" - raise NotImplementedError() + ... @classmethod def register( diff --git a/psycopg3/psycopg3/types/singletons.py b/psycopg3/psycopg3/types/singletons.py index 0c6e04e95..dd374b474 100644 --- a/psycopg3/psycopg3/types/singletons.py +++ b/psycopg3/psycopg3/types/singletons.py @@ -36,6 +36,9 @@ class NoneDumper(Dumper): quote(), so it can be used in sql composition. """ + def dump(self, obj: None) -> bytes: + raise NotImplementedError("NULL is passed to Postgres in other ways") + def quote(self, obj: None) -> bytes: return b"NULL"