from .waiting import Wait, Ready
from .sql import Composable
-EncodeFunc = Callable[[str], Tuple[bytes, int]]
-DecodeFunc = Callable[[bytes], Tuple[str, int]]
-
Query = Union[str, bytes, "Composable"]
Params = Union[Sequence[Any], Mapping[str, Any]]
import re
import sys
-import codecs
from datetime import date, datetime, time, timedelta
from typing import cast
from ..oids import builtins
from ..adapt import Dumper, Loader
-from ..proto import AdaptContext, EncodeFunc, DecodeFunc
+from ..proto import AdaptContext
from ..errors import InterfaceError, DataError
-
-_encode_ascii = codecs.lookup("ascii").encode
-_decode_ascii = codecs.lookup("ascii").decode
+from ..utils.codecs import EncodeFunc, DecodeFunc, encode_ascii, decode_ascii
@Dumper.text(date)
oid = builtins["date"].oid
- def dump(self, obj: date, __encode: EncodeFunc = _encode_ascii) -> bytes:
+ def dump(self, obj: date, __encode: EncodeFunc = encode_ascii) -> bytes:
# NOTE: whatever the PostgreSQL DateStyle input format (DMY, MDY, YMD)
# the YYYY-MM-DD is always understood correctly.
return __encode(str(obj))[0]
oid = builtins["timetz"].oid
- def dump(self, obj: time, __encode: EncodeFunc = _encode_ascii) -> bytes:
+ def dump(self, obj: time, __encode: EncodeFunc = encode_ascii) -> bytes:
return __encode(str(obj))[0]
oid = builtins["timestamptz"].oid
- def dump(self, obj: date, __encode: EncodeFunc = _encode_ascii) -> bytes:
+ def dump(self, obj: date, __encode: EncodeFunc = encode_ascii) -> bytes:
# NOTE: whatever the PostgreSQL DateStyle input format (DMY, MDY, YMD)
# the YYYY-MM-DD is always understood correctly.
return __encode(str(obj))[0]
setattr(self, "dump", self._dump_sql)
def dump(
- self, obj: timedelta, __encode: EncodeFunc = _encode_ascii
+ self, obj: timedelta, __encode: EncodeFunc = encode_ascii
) -> bytes:
return __encode(str(obj))[0]
super().__init__(oid, context)
self._format = self._format_from_context()
- def load(self, data: bytes, __decode: DecodeFunc = _decode_ascii) -> date:
+ def load(self, data: bytes, __decode: DecodeFunc = decode_ascii) -> date:
try:
return datetime.strptime(__decode(data)[0], self._format).date()
except ValueError as e:
_format = "%H:%M:%S.%f"
_format_no_micro = _format.replace(".%f", "")
- def load(self, data: bytes, __decode: DecodeFunc = _decode_ascii) -> time:
+ def load(self, data: bytes, __decode: DecodeFunc = decode_ascii) -> time:
# check if the data contains microseconds
fmt = self._format if b"." in data else self._format_no_micro
try:
super().__init__(oid, context)
- def load(self, data: bytes, __decode: DecodeFunc = _decode_ascii) -> time:
+ def load(self, data: bytes, __decode: DecodeFunc = decode_ascii) -> time:
# Hack to convert +HH in +HHMM
if data[-3] in (43, 45):
data += b"00"
return dt.time().replace(tzinfo=dt.tzinfo)
def _load_py36(
- self, data: bytes, __decode: DecodeFunc = _decode_ascii
+ self, data: bytes, __decode: DecodeFunc = decode_ascii
) -> time:
# Drop seconds from timezone for Python 3.6
# Also, Python 3.6 doesn't support HHMM, only HH:MM
self._format_no_micro = self._format.replace(".%f", "")
def load(
- self, data: bytes, __decode: DecodeFunc = _decode_ascii
+ self, data: bytes, __decode: DecodeFunc = decode_ascii
) -> datetime:
# check if the data contains microseconds
fmt = (
return ""
def load(
- self, data: bytes, __decode: DecodeFunc = _decode_ascii
+ self, data: bytes, __decode: DecodeFunc = decode_ascii
) -> datetime:
# Hack to convert +HH in +HHMM
if data[-3] in (43, 45):
return super().load(data)
def _load_py36(
- self, data: bytes, __decode: DecodeFunc = _decode_ascii
+ self, data: bytes, __decode: DecodeFunc = decode_ascii
) -> datetime:
# Drop seconds from timezone for Python 3.6
# Also, Python 3.6 doesn't support HHMM, only HH:MM
# Copyright (C) 2020 The Psycopg Team
import json
-import codecs
from typing import Any, Callable, Optional
from ..oids import builtins
from ..adapt import Dumper, Loader
-from ..proto import EncodeFunc
from ..errors import DataError
-
-_encode_utf8 = codecs.lookup("utf8").encode
+from ..utils.codecs import EncodeFunc, encode_utf8
JSON_OID = builtins["json"].oid
JSONB_OID = builtins["jsonb"].oid
class _JsonDumper(Dumper):
def dump(
- self, obj: _JsonWrapper, __encode: EncodeFunc = _encode_utf8
+ self, obj: _JsonWrapper, __encode: EncodeFunc = encode_utf8
) -> bytes:
return __encode(obj.dumps())[0]
@Dumper.binary(Jsonb)
class JsonbBinaryDumper(JsonbDumper):
def dump(
- self, obj: _JsonWrapper, __encode: EncodeFunc = _encode_utf8
+ self, obj: _JsonWrapper, __encode: EncodeFunc = encode_utf8
) -> bytes:
return b"\x01" + __encode(obj.dumps())[0]
# Copyright (C) 2020 The Psycopg Team
-import codecs
import struct
from typing import Any, Callable, Dict, Tuple, cast
from decimal import Decimal
from ..oids import builtins
from ..adapt import Dumper, Loader
-from ..proto import EncodeFunc, DecodeFunc
+from ..utils.codecs import EncodeFunc, DecodeFunc, encode_ascii, decode_ascii
UnpackInt = Callable[[bytes], Tuple[int]]
UnpackFloat = Callable[[bytes], Tuple[float]]
-_encode_ascii = codecs.lookup("ascii").encode
-_decode_ascii = codecs.lookup("ascii").decode
-
class NumberDumper(Dumper):
_special: Dict[bytes, bytes] = {}
- def dump(self, obj: Any, __encode: EncodeFunc = _encode_ascii) -> bytes:
+ def dump(self, obj: Any, __encode: EncodeFunc = encode_ascii) -> bytes:
return __encode(str(obj))[0]
def quote(self, obj: Any) -> bytes:
@Loader.text(builtins["int8"].oid)
@Loader.text(builtins["oid"].oid)
class IntLoader(Loader):
- def load(self, data: bytes, __decode: DecodeFunc = _decode_ascii) -> int:
+ def load(self, data: bytes, __decode: DecodeFunc = decode_ascii) -> int:
return int(__decode(data)[0])
@Loader.text(builtins["numeric"].oid)
class NumericLoader(Loader):
def load(
- self, data: bytes, __decode: DecodeFunc = _decode_ascii
+ self, data: bytes, __decode: DecodeFunc = decode_ascii
) -> Decimal:
return Decimal(__decode(data)[0])
# Copyright (C) 2020 The Psycopg Team
-import codecs
from typing import Optional, Union, TYPE_CHECKING
+from ..pq import Escaping
from ..oids import builtins, INVALID_OID
from ..adapt import Dumper, Loader
-from ..proto import AdaptContext, EncodeFunc, DecodeFunc
+from ..proto import AdaptContext
from ..errors import DataError
-from ..pq import Escaping
+from ..utils.codecs import EncodeFunc, DecodeFunc, encode_utf8, decode_utf8
if TYPE_CHECKING:
from ..pq.proto import Escaping as EscapingProto
if self.connection.client_encoding != "SQL_ASCII":
self._encode = self.connection.codec.encode
else:
- self._encode = codecs.lookup("utf8").encode
+ self._encode = encode_utf8
else:
- self._encode = codecs.lookup("utf8").encode
+ self._encode = encode_utf8
@Dumper.binary(str)
else:
self.decode = None
else:
- self.decode = codecs.lookup("utf8").decode
+ self.decode = decode_utf8
def load(self, data: bytes) -> Union[bytes, str]:
if self.decode is not None:
if self.connection is not None:
self.decode = self.connection.codec.decode
else:
- self.decode = codecs.lookup("utf8").decode
+ self.decode = decode_utf8
def load(self, data: bytes) -> str:
return self.decode(data)[0]
# Should implement lazy dumper registration.
from uuid import UUID
-import codecs
-
from ..oids import builtins
from ..adapt import Dumper, Loader
-from ..proto import DecodeFunc, EncodeFunc
-
-_encode_ascii = codecs.lookup("ascii").encode
-_decode_ascii = codecs.lookup("ascii").decode
+from ..utils.codecs import EncodeFunc, DecodeFunc, encode_ascii, decode_ascii
@Dumper.text(UUID)
oid = builtins["uuid"].oid
- def dump(self, obj: UUID, __encode: EncodeFunc = _encode_ascii) -> bytes:
+ def dump(self, obj: UUID, __encode: EncodeFunc = encode_ascii) -> bytes:
return __encode(obj.hex)[0]
@Loader.text(builtins["uuid"].oid)
class UUIDLoader(Loader):
- def load(self, data: bytes, __decode: DecodeFunc = _decode_ascii) -> UUID:
+ def load(self, data: bytes, __decode: DecodeFunc = decode_ascii) -> UUID:
return UUID(__decode(data)[0])
--- /dev/null
+"""
+Utility module to access fast encoders/decoders
+"""
+
+# Copyright (C) 2020 The Psycopg Team
+
+import codecs
+from typing import Callable, Tuple
+
+EncodeFunc = Callable[[str], Tuple[bytes, int]]
+DecodeFunc = Callable[[bytes], Tuple[str, int]]
+
+encode_ascii = codecs.lookup("ascii").encode
+decode_ascii = codecs.lookup("ascii").decode
+encode_utf8 = codecs.lookup("utf8").encode
+decode_utf8 = codecs.lookup("utf8").decode