Closed
Description
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:
- There is a protocol class
pep249.Connection
(I'm creating this). - There is a class
pymysql.connections.Connection
that conforms to this protocol, as evidenced byissubclass(pymysql.connections.Connection, pep249.Connection) == True
. - When defining a generic base class
DatabaseAdapter
that's generic in aConnectionT
type variable that haspep249.Connection
as an upper bound (DatabaseAdapter(Generic[ConnectionT])
), and defining a subclassMySQLAdapter
that parameterizes the generic base class withpymysql.connections.Connection
(MySQLAdapter(DatabaseAdapter[pymysql.connections.Connection])
),mypy
complains thatpymysql.connections.Connection
is not a subtype ofpep249.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