Skip to content

Commit

Permalink
fix: use a correct recursive definition for DumperKey
Browse files Browse the repository at this point in the history
Already supported in current Mypy: python/mypy#731.

The definition of DumperKey was wrong anyway, in a way causing mypy to
crash: see python/mypy#14000.
  • Loading branch information
dvarrazzo committed Nov 4, 2022
1 parent 5acb614 commit 2e924a2
Show file tree
Hide file tree
Showing 7 changed files with 9 additions and 17 deletions.
5 changes: 1 addition & 4 deletions psycopg/psycopg/abc.py
Expand Up @@ -29,10 +29,7 @@
Params: TypeAlias = Union[Sequence[Any], Mapping[str, Any]]
ConnectionType = TypeVar("ConnectionType", bound="BaseConnection[Any]")
PipelineCommand: TypeAlias = Callable[[], None]

# TODO: make it recursive when mypy will support it
# DumperKey: TypeAlias = Union[type, Tuple[Union[type, "DumperKey"]]]
DumperKey: TypeAlias = Union[type, Tuple[type, ...]]
DumperKey: TypeAlias = Union[type, Tuple["DumperKey", ...]]

# Waiting protocol types

Expand Down
4 changes: 2 additions & 2 deletions psycopg/psycopg/adapt.py
Expand Up @@ -5,7 +5,7 @@
# Copyright (C) 2020 The Psycopg Team

from abc import ABC, abstractmethod
from typing import Any, Optional, Type, Tuple, Union, TYPE_CHECKING
from typing import Any, Optional, Type, TYPE_CHECKING

from . import pq, abc
from . import _adapters_map
Expand Down Expand Up @@ -91,7 +91,7 @@ def quote(self, obj: Any) -> Buffer:
rv = rv.replace(b"\\", b"\\\\")
return rv

def get_key(self, obj: Any, format: PyFormat) -> Union[type, Tuple[type, ...]]:
def get_key(self, obj: Any, format: PyFormat) -> abc.DumperKey:
"""
Implementation of the `~psycopg.abc.Dumper.get_key()` member of the
`~psycopg.abc.Dumper` protocol. Look at its definition for details.
Expand Down
4 changes: 2 additions & 2 deletions psycopg/psycopg/types/array.py
Expand Up @@ -121,7 +121,7 @@ def get_key(self, obj: List[Any], format: PyFormat) -> DumperKey:
return self.cls

sd = self._tx.get_dumper(item, format)
return (self.cls, sd.get_key(item, format)) # type: ignore
return (self.cls, sd.get_key(item, format))

def upgrade(self, obj: List[Any], format: PyFormat) -> "BaseListDumper":
# If we have an oid we don't need to upgrade
Expand Down Expand Up @@ -223,7 +223,7 @@ def get_key(self, obj: List[Any], format: PyFormat) -> DumperKey:
return (self.cls,)

sd = self._tx.get_dumper(item, format)
return (self.cls, sd.get_key(item, format)) # type: ignore
return (self.cls, sd.get_key(item, format))

def upgrade(self, obj: List[Any], format: PyFormat) -> "BaseListDumper":
# If we have an oid we don't need to upgrade
Expand Down
2 changes: 1 addition & 1 deletion psycopg/psycopg/types/multirange.py
Expand Up @@ -154,7 +154,7 @@ def get_key(self, obj: Multirange[Any], format: PyFormat) -> DumperKey:
item = self._get_item(obj)
if item is not None:
sd = self._tx.get_dumper(item, self._adapt_format)
return (self.cls, sd.get_key(item, format)) # type: ignore
return (self.cls, sd.get_key(item, format))
else:
return (self.cls,)

Expand Down
2 changes: 1 addition & 1 deletion psycopg/psycopg/types/range.py
Expand Up @@ -259,7 +259,7 @@ def get_key(self, obj: Range[Any], format: PyFormat) -> DumperKey:
item = self._get_item(obj)
if item is not None:
sd = self._tx.get_dumper(item, self._adapt_format)
return (self.cls, sd.get_key(item, format)) # type: ignore
return (self.cls, sd.get_key(item, format))
else:
return (self.cls,)

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Expand Up @@ -35,6 +35,7 @@ files = [
warn_unused_ignores = true
show_error_codes = true
strict = true
enable_recursive_aliases = true

[[tool.mypy.overrides]]
module = [
Expand Down
8 changes: 1 addition & 7 deletions tests/adapters_example.py
@@ -1,4 +1,4 @@
from typing import Optional, Tuple, Union
from typing import Optional

from psycopg import pq
from psycopg.abc import Dumper, Loader, AdaptContext, PyFormat, Buffer
Expand Down Expand Up @@ -43,9 +43,3 @@ def __init__(self, oid: int, context: Optional[AdaptContext] = None):

def load(self, data: Buffer) -> str:
return (bytes(data) * 2).decode()


# This should be the definition of psycopg.adapt.DumperKey, but mypy doesn't
# support recursive types. When it will, this statement will give an error
# (unused type: ignore) so we can fix our definition.
_DumperKey = Union[type, Tuple[Union[type, "_DumperKey"]]] # type: ignore

0 comments on commit 2e924a2

Please sign in to comment.