-
Notifications
You must be signed in to change notification settings - Fork 771
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
Pylance doesn't recognize a variable's type from certain kinds of assert statements #557
Comments
Pylint is too forgiving (how is it that you do not get pyright instead under pylance? I have disabled all other linters...) but your |
That would work, except in reality |
Thanks for the bug report. There is an inconsistency in the way pylance is applying type narrowing to an Any/Unknown type and a type that is a union that happens to contain an Any/Unknown type. In your case, the type inferred for |
What's the meaning of Indeed, when I annotate the type of I see what you mean about the inconsistent behavior with regard to unions... ...
key = bar.get("a")
# pylance says key is Unknown | None
assert isinstance(key, str)
# after this pylance says key is Unknown
assert isinstance(key, str)
# now pylance says key is str
return FOO_MAP[key] Perhaps you could treat the type narrowing procedure as a fixed-point algorithm? |
The reason a double assert works here is because the first assert narrows the type from |
Thanks for the clarification! |
I've updated the This fix will be included in the next release of pylance. Thanks again for reporting the problem. |
Glad to hear it! def foo(bar: Dict):
key = bar.get("a")
FOO_MAP = { # type is Dict[str, str]
'b': 'somestr',
'c': 'otherstr'
}
assert key in FOO_MAP # for this assertion to pass, key must be a str
return FOO_MAP[key] In this case, the type of |
No, this isn't support. In general, "type narrowing" refers to a process by which a known type is made "narrower" either by eliminating subtypes of a union or by choosing a subclass of a provided class. For example, The |
This is surprising to me, since the example I gave has the same narrowing power as a call to Pylance has been quite helpful in pointing out ambiguities and outright wrong code in our projects, so I'm thankful for all the work you all do! |
No, this case is quite different. The implementation of the |
This issue has been fixed in version 2020.11.0, which we've just released. You can find the changelog here: https://github.com/microsoft/pylance-release/blob/master/CHANGELOG.md#2020110-4-november-2020 |
Environment data
Expected behaviour
Pylint should constrain the variable's type based on the assertion statement, like this:
Actual behaviour
If we have a lot of data coming in from external sources, we need a way of communicating to Pylance that a variable is of a certain type, and preferably in the most concise way possible. Naturally, I could say
but it's irksome to write that extra line (or just an
and
expression) when the information is implied by the type ofFOO_MAP
.Furthermore, it seems that even straightforward assertions like
are communicating no more information than a very loose
Why is that? Is this expected behavior?
Logs
Will provide if necessary.
The text was updated successfully, but these errors were encountered: