__module__ = "psycopg3.adapt"
_adapters: "AdaptersMap"
_pgresult: Optional["PGresult"] = None
- make_row: Optional[RowMaker] = None
+ make_row: RowMaker = tuple
def __init__(self, context: Optional[AdaptContext] = None):
f"rows must be included between 0 and {self._ntuples}"
)
- records: List[Row]
- records = [None] * (row1 - row0) # type: ignore[list-item]
- if self.make_row:
- mkrow = self.make_row
- else:
- mkrow = tuple
+ records: List[Row] = []
for row in range(row0, row1):
record: List[Any] = [None] * self._nfields
for col in range(self._nfields):
val = res.get_value(row, col)
if val is not None:
record[col] = self._row_loaders[col](val)
- records[row - row0] = mkrow(record)
+ records.append(self.make_row(record))
return records
if val is not None:
record[col] = self._row_loaders[col](val)
- return self.make_row(record) if self.make_row else tuple(record)
+ return self.make_row(record) # type: ignore[no-any-return]
def load_sequence(
self, record: Sequence[Optional[bytes]]
class RowFactory(Protocol):
- def __call__(self, __cursor: "BaseCursor[Any]") -> Optional[RowMaker]:
+ def __call__(self, __cursor: "BaseCursor[Any]") -> RowMaker:
...
class Transformer(Protocol):
- make_row: Optional[RowMaker] = None
-
def __init__(self, context: Optional[AdaptContext] = None):
...
+ make_row: RowMaker
+
@property
def connection(self) -> Optional["BaseConnection"]:
...
import functools
import re
from collections import namedtuple
-from typing import Any, Callable, Dict, Sequence, Type, NamedTuple
+from typing import Any, Callable, Dict, NamedTuple, Sequence, Tuple, Type
from typing import TYPE_CHECKING
from . import errors as e
from .cursor import BaseCursor
-def tuple_row(cursor: "BaseCursor[Any]") -> None:
+def tuple_row(
+ cursor: "BaseCursor[Any]",
+) -> Callable[[Sequence[Any]], Tuple[Any, ...]]:
"""Row factory to represent rows as simple tuples.
This is the default factory.
"""
- # Implementation detail: just return None instead of a callable because
- # the Transformer knows how to use this value.
- return None
+ # Implementation detail: make sure this is the tuple type itself, not an
+ # equivalent function, because the C code fast-paths on it.
+ return tuple
def dict_row(
class Transformer(proto.AdaptContext):
def __init__(self, context: Optional[proto.AdaptContext] = None): ...
+ make_row: proto.RowMaker
@property
def connection(self) -> Optional[BaseConnection]: ...
@property
def adapters(self) -> AdaptersMap: ...
@property
- def make_row(self) -> Optional[proto.RowMaker]: ...
- @make_row.setter
- def make_row(self, row_maker: proto.RowMaker) -> None: ...
- @property
def pgresult(self) -> Optional[PGresult]: ...
def set_pgresult(
self, result: Optional["PGresult"], set_loaders: bool = True
cdef int _nfields, _ntuples
cdef list _row_dumpers
cdef list _row_loaders
- cdef object _make_row
+ cdef public object make_row
def __cinit__(self, context: Optional["AdaptContext"] = None):
if context is not None:
self.adapters = global_adapters
self.connection = None
- @property
- def make_row(self) -> Optional[RowMaker]:
- return self._make_row
-
- @make_row.setter
- def make_row(self, row_maker: Optional[RowMaker]) -> None:
- self._make_row = row_maker
-
@property
def pgresult(self) -> Optional[PGresult]:
return self._pgresult
Py_INCREF(pyval)
PyTuple_SET_ITEM(<object>brecord, col, pyval)
- if self.make_row:
- return list(map(self.make_row, records))
+ cdef object make_row = self.make_row
+ if make_row is not tuple:
+ for i in range(len(records)):
+ records[i] = make_row(records[i])
return records
def load_row(self, int row) -> Optional[Row]:
Py_INCREF(pyval)
PyTuple_SET_ITEM(record, col, pyval)
- if self.make_row:
- return self.make_row(record)
+ cdef object make_row = self.make_row
+ if make_row is not tuple:
+ record = make_row(record)
return record
cpdef object load_sequence(self, record: Sequence[Optional[bytes]]):