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 by issubclass(pymysql.connections.Connection, pep249.Connection) == True.
- 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
Bug Report
It seems that whereas Python's structural subtyping works (using Python 3.7 and
typing_extensions.Protocol) at runtime (see below),mypydoesn't recognize the subtype relationship in the following scenario:pep249.Connection(I'm creating this).pymysql.connections.Connectionthat conforms to this protocol, as evidenced byissubclass(pymysql.connections.Connection, pep249.Connection) == True.DatabaseAdapterthat's generic in aConnectionTtype variable that haspep249.Connectionas an upper bound (DatabaseAdapter(Generic[ConnectionT])), and defining a subclassMySQLAdapterthat parameterizes the generic base class with
pymysql.connections.Connection(MySQLAdapter(DatabaseAdapter[pymysql.connections.Connection])),mypycomplains thatpymysql.connections.Connectionis not a subtype ofpep249.Connection.To Reproduce
https://gist.github.com/jmehnle/37ece52f9dbbec439ed8d0c11db47f41
Expected Behavior
pymysql.connections.Connectionshould be recognized as a (structural) subtype ofpep249.Connection.Actual Behavior
Your Environment
mypy.ini(and other config files): (none)