-
Notifications
You must be signed in to change notification settings - Fork 114
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
Class is not compatible with protocol because it has no attribute named ... #499
Comments
I think that check may be hard to due at runtime because the |
But is it a bug? The class does not have a value for |
The way it works now is according to my interpretation of how protocols should work. I could of course be mistaken, but I'd like to see someone point that out in the spec. |
That's right. But how else would I describe an instance attribute via a
Does https://peps.python.org/pep-0544/#protocol-members help? This is pretty similar to my code: class Template(Protocol):
name: str # This is a protocol member
value: int = 0 # This one too (with default)
class Concrete:
def __init__(self, name: str, value: int) -> None:
self.name = name
self.value = value
var: Template = Concrete('value', 42) # OK |
PEP 544 also says:
So I'd say anything that does not have |
This compares an instance against the protocol, which was not the failing case. |
Yes, I agree. But theoretically, if the instance type-checks against the protocol, is there any reason the instance's type should not also type-check against the protocol's type? IMHO, the latter is what static type checkers check, and mypy/pyright are okay with this code. I am not saying this check is easy to do at runtime, compared to the instance checks. But I would consider the current behavior a false-positive. |
Ok, so how about this? When checking a class against a protocol class:
|
I don't know too much about the inner workings of typeguard, but I would be okay with that, taking into account that parsing The proposed approach would go from having potential false positives (where |
I should correct my last statement. Both from typing import Protocol
class Proto(Protocol):
foo: str
class Class(Proto):
def __init__(self) -> None:
# self.foo = "bar"
pass
def function_of_instance(instance: Proto) -> None: ...
def function_of_type(type_: type[Proto]) -> None: ...
function_of_instance(Class())
function_of_type(Class) |
False negatives are way better than false positives. The run-time type checks aren't perfect, and should not be assumed to be. |
Things to check first
I have searched the existing issues and didn't find my bug already reported there
I have checked that my bug is still present in the latest release
Typeguard version
4.4.1
Python version
3.13.0
What happened?
I think #498 is not fully fixed yet.
How can we reproduce the bug?
bug.py
code.py
The text was updated successfully, but these errors were encountered: