8000 Structural subtype XX of X not recognized as subclass of X in `class Z(Generic[TypeVar("XT", bound=X)])` and `class ZZ(Z[XX])` · Issue #9560 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content
Structural subtype XX of X not recognized as subclass of X in class Z(Generic[TypeVar("XT", bound=X)]) and class ZZ(Z[XX]) #9560
Closed
@jmehnle

Description

@jmehnle

Bug Report

It seems that whereas Python's structural subtyping works (using Python 3.7 and typing_extensions.Protocol) at runtime (see below), mypy doesn't recognize the subtype relationship in the following scenario:

  1. There is a protocol class pep249.Connection (I'm creating this).
  2. There is a class pymysql.connections.Connection that conforms to this protocol, as evidenced by issubclass(pymysql.connections.Connection, pep249.Connection) == True.
  3. When defining a generic base class DatabaseAdapter that's generic in a ConnectionT type variable that has pep249.Connection as an upper bound (DatabaseAdapter(Generic[ConnectionT])), and defining a subclass MySQLAdapter
    that parameterizes the generic base class with pymysql.connections.Connection (MySQLAdapter(DatabaseAdapter[pymysql.connections.Connection])), mypy complains that pymysql.connections.Connection is not a subtype of pep249.Connection.

To Reproduce

https://gist.github.com/jmehnle/37ece52f9dbbec439ed8d0c11db47f41

# pep249.py

from typing import Any
from typing_extensions import Protocol, runtime_checkable

@runtime_checkable
class Connection(Protocol):
    def close(self) -> None: ...
    def commit(self) -> None: ...
    def rollback(self) -> None: ...
    def cursor(self, *__args: Any, **__kwargs: Any) -> Any: ...
# main.py

from typing import Generic, TypeVar
import pep249
import pymysql

ConnectionT = TypeVar("ConnectionT", bound=pep249.Connection)

class DatabaseAdapter(Generic[ConnectionT]): ...

class MySQLAdapter(DatabaseAdapter[pymysql.connections.Connection]): ...

Expected Behavior

pymysql.connections.Connection should be recognized as a (structural) subtype of pep249.Connection.

Actual Behavior

(py3.7-typing-protocol) jbook:~/scratch> mypy --version
mypy 0.790+dev.7273e9ab1664b59a74d9bd1d2361bbeb9864b7ab

(py3.7-typing-protocol) jbook:~/scratch> mypy .
main.py:11: error: Type argument "pymysql.connections.Connection" of "DatabaseAdapter" must be a subtype of "pep249.Connection"
Found 1 error in 1 file (checked 2 source files)

(py3.7-typing-protocol) jbook:~/scratch> python
Python 3.7.9 (default, Sep  6 2020, 13:20:25)
[Clang 11.0.3 (clang-1103.0.32.62)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pep249
>>> import pymysql
>>> pymysql.connections.Connection
<class 'pymysql.connections.Connection'>
>>> issubclass(pymysql.connections.Connection, pep249.Connection)
True

Your Environment

  • Mypy version used: 0.790+dev.7273e9ab1664b59a74d9bd1d2361bbeb9864b7ab (latest master)
  • Mypy command-line flags: (none)
  • Mypy configuration options from mypy.ini (and other config files): (none)
  • Python version used: 3.7.9
  • Operating system and version: macOS 10.15.6 with MacPorts

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0