-
Notifications
You must be signed in to change notification settings - Fork 767
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
No way to avoid an error when using isinstance with a generic class in strict mode #2128
Comments
Yeah, it's unfortunate that In practice, this isn't typically an issue because most people who use strict type checking try to avoid using def test(var: int | str | dict[str, str]):
if isinstance(var, dict):
reveal_type(var) # dict[str, str] One possible (but admittedly ugly) workaround here is: d = cast(dict[Any, Any], var)
print(d.keys()) If you don't like that, you could use a |
I guess I should have picked a better example. I used the annotation Any as a contrived example. Here's a more specific example demonstrating my exact issue, using Django 3.2.6 and django-stubs 1.9.0:
It doesn't seem to propagate the generic parameter within the isinstance block because the |
Thanks for the additional context. I agree that the type argument should be preserved here. The |
This issue has been fixed in version 2022.1.0, which we've just released. You can find the changelog here: CHANGELOG.md |
I'm not sure how to get the version number from the VSCode extension, but I am on the pre-release version with auto-update, so I should be up to date. I am seeing the following behavior which sounds a lot like the issue in this ticket: class Parent[T, U]:
def __init__(self, value: T, other: U) -> None:
self.value = value
self.other = other
class Child[T](Parent[T, T]):
def meth[U](self, other: Parent[T, U]) -> None:
print(other.value) # other: Parent[T@Child, U@meth]; .value: T@Child
if isinstance(other, Child):
print(other.value) # other: Child[Unknown]; .value: Unknown
else:
print(other.other) I've put in the inferred types by pylance in the comments above. Specifically in the Regardless of even the Shouldn't the type be inferred to Update: class Parent[T, U]:
def __init__(self, value: T, other: U) -> None:
self.value = value
self.other = other
class Sibling[T, U](Parent[T, U]):
...
class Child[T](Parent[T, T]):
def meth[U](self, other: Parent[T, U]) -> None:
print(other.value) # other: Parent[T@Child, U@meth]; .value: T@Child
if isinstance(other, Child):
print(other.value) # other: Child[Unknown]; .value: Unknown
elif isinstance(other, Sibling):
print(other.value) # other: Sibling[T@Child, U@meth]; .value: T@Child
else:
print(other.other) The Sibling class is correctly inferred. The only difference being that the |
@mheripsos can you open a new issue rather than adding to closed issue, so people can pick it up? |
Submitted (#6515 ) |
Environment data
Expected behaviour
There needs to be some way in strict mode to have an isinstance check with a generic class without getting an error. I suggest defaulting type arguments to Any after an isinstance check, rather than Unknown.
Actual behaviour
For a contrived example:
In strict mode, the
var.keys()
produces the type errorAnd adding generic parameters to the isinstance check (which I know is not how it's supposed to work)
There's no error at
var.keys()
, but the isinstance check produces the type errorThe text was updated successfully, but these errors were encountered: