-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
mypy not coping well with a variable changing type #2589
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
Regardless of whether we allow changing the type of a variable, the errors reported on lines 10 and 12 are a bug. (And I agree it's especially confusing when the extraneous errors appear before the real issue.) Changing the declared type of a variable can get tricky. What if your type-changing assignment to There's also an argument that it's bad style to have a variable hold different types of value over its lifetime; though I tend to think that's less true if the change in type is marked by an explicit new type annotation. |
@rwbarton, the errors on lines 10 and 12 are misleading but the bug is that we need a better message, not that they appear. @rhettinger, the issue here is that when Mypy is parsing the source to assign types to names, it only ever holds a single slot for a name within a given scope. It reads from top to bottom so the last type declared wins. Type checking is performed later, thus the confusing error message. Mutating the type of a name within a single scope is considered an error. As you admit, if changes to the type are very far apart, the reader of the code might get the wrong idea about a name's type when making changes or using an API later. The simplest example of this is:
Mypy will currently output the following errors:
Note what's going on: it correctly warns that the type was redefined within a single scope. But it also confusingly warns that lines 1 and 2 have incorrect types, since at this point the recorded type for the name I have two suggestions:
This doesn't produce any Mypy errors. Why bother with casting? Well, usually Mypy is smart enough to infer specializations of the types within the flow of the code but in the Consider usage of the types:
As annotated, Mypy will produce the following output here:
All of those are valid and helpful error messages! Note that if you comment out the
Does that clear things up? |
I don't agree, because...
... the subsequent type declarations are erroneous, so mypy ought to just ignore them. It's very odd if lines 10 and 12 are okay, but then after adding a wrong line on line 15, line 12 is no longer okay. And there's no need for it; we should just report the error on line 15. |
@rwbarton, so you're essentially suggesting that in cases where |
I agree with @rwbarton. If we prohibit the redefinition/re-declaration then we should keep the first declared type, not the last one. |
Suggested fix for the spurious warnings is in PR #2591. My advice on how to solve the |
Sometimes, it is necessary to accumulate data using a mutable structure and then recast the data into an immutable object suitable for use as a dictionary key. If the transformation switching data types while using the same variable name, mypy emits an inscrutable error message that doesn't hint at what the actual problem is.
The solution was to use another variable name for the transmuted data.
Recommendation: Let variables be rebound to different types as needed. Barring that, provide a better error message.
Simplified example:
The error message is:
Note, the message for line 10 makes no sense until you see the later message for line 15. In my client's code base, these two we very far apart and made it difficult to figure out why line 10 gets an error message even though it is correct code.
The solution was to change the last lines to use new variable names:
It would be nice if the error message applied only to the redefinition line rather than the initial correct declaration. It would be even nicer if mypy supported patterns that allowed a tranformation in-place or re-use of a variable name for cases like converting a list of lists into a list of tuples. The latter example is not uncommon in my client's code base (because the inner lists need to be used as dict keys).
The text was updated successfully, but these errors were encountered: