-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
class Z(Generic[TypeVar("XT", bound=X)])
class Z(Generic[TypeVar("XT", bound=X)])
and class ZZ(Z[X])
class Z(Generic[TypeVar("XT", bound=X)])
and class ZZ(Z[X])
class Z(Generic[TypeVar("XT", bound=X)])
and class ZZ(Z[XX])
Could this maybe be because the typeshed stubs for pymysql are incomplete?
|
I'm happy to investigate, but what exactly would I need to look for? Also, what about the fact that |
issubclass is actually pretty unsophisticated; it only checks presence of an attribute, whereas mypy checks a lot more stuff. You could take a look at the pymysql stubs: https://github.com/python/typeshed/tree/master/third_party/2and3/pymysql If you can construct a self-contained repro, that would narrow down whether there's an issue with pymysql stubs or a mypy bug. I'd also confirm whether something simpler like: There are a couple other open issues for mypy to be more helpful about diagnosing why something isn't an instance of a Protocol — I think improving this is a pretty high priority. |
@hauntsaninja, the advice to try a plain assignment was gold. It gets me some useful output:
So if I change the method definition like so: --- pep249.py 2020-10-09 01:14:44.000000000 +0000
+++ pep249.py.new 2020-10-09 01:14:48.000000000 +0000
@@ -8,4 +8,4 @@
def close(self) -> None: ...
def commit(self) -> None: ...
def rollback(self) -> None: ...
- def cursor(self, *__args: Any, **__kwargs: Any) -> Any: ...
+ def cursor(self, __cursor: Any = ...) -> Any: ... then it all works. But this puts me in a dilemma, because PEP 249 doesn't specify the signature of |
Here's a horrible hack that might help: declare from typing import *
class Pro(Protocol):
@property
def foo(self) -> Callable[..., Any]:
...
class C:
def foo(self) -> None:
pass
x: Pro = C() No errors there. |
Hot damn, that works. Thanks, @gvanrossum. I never, ever would've come up with that trick. So where does this leave us? I see at least a couple deficiencies:
|
Closing, since #5876 has been fixed |
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:pep249.Connection
(I'm creating this).pymysql.connections.Connection
that conforms to this protocol, as evidenced byissubclass(pymysql.connections.Connection, pep249.Connection) == True
.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 with
pymysql.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
Expected Behavior
pymysql.connections.Connection
should be recognized as a (structural) subtype ofpep249.Connection
.Actual Behavior
Your Environment
mypy.ini
(and other config files): (none)The text was updated successfully, but these errors were encountered: