Replies: 1 comment 14 replies
-
|
Question 1 Mypy and pyright differ slightly in how they interpret class variables vs instance variables. Mypy, in particular, is a bit sloppy and inconsistent in how it handles these. There are multiple open issues in the mypy issue tracker on this topic. You can read more about this here. I suspect that the reason mypy rejects Question 2 from typing import Any, reveal_type
class IntDescriptor:
def __get__(self, instance: object | None, owner: Any) -> int:
return 0
class Foo:
@property
def parent(self) -> IntDescriptor:
return IntDescriptor()
f = Foo()
reveal_type(f.parent) # pyright reveals "IntDescriptor", mypy reveals "int"
print(f.parent) # Runtime prints "IntDescriptor, which is consistent with pyrightQuestion 3 Pyright's nested error message is a bit misleading here. While I'll look at improving the error message to eliminate the confusion. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi,
I've noticed a difference between how mypy and pyright handles descriptors when using protocols.
I'm creating a discussion since I'm not sure if mypy or pyright has the correct behavior.
I noticed this in sqlalchemy, in the example posted in this issue sqlalchemy/sqlalchemy#10288.
Let's start with a setup of a descriptor that's equivalent to the one used by sqlalchemy
Let's also define a couple of classes and a protocol
First question
pyright reports the following
while mypy reports
It seems that pyright has a different behavior when using a protocol versus a class. I'm not sure what the correct behaviour is in this case, but different behaviour seems strange.
Second question
pyright reports the following
while mypy does this
Here the difference are two:
get_parent_name(Item)since the function is typed with a protocol. Same consideration as abovechild.parenta descriptor instance, while mypy uses the gets defined in the descriptor.Not sure what's the correct behaviour here, but since pyright accepts
Item()as aPropProtocolit seems that the correct behaviour should be the mypy oneThird question
pyright reports the following
mypy instead reports
Here there seems to a bug in pyright since it reports
Type parameter "_T_co@Mapped" is covariant, but "Parent" is not a subtype of "ParentProtocol"but previously it was fine incheck_parentOtherwise I'm not sure if AttrProtocol should be preferred over PropProtocol. It seems to me that it should be the least ambiguous way of defining a protocol, but since nighter mypy nor pyright likes it suggests that it's not.
Sorry for the long post, but I kept finding differences in this case. Thanks for reading
Complete file to reproduce
Beta Was this translation helpful? Give feedback.
All reactions