-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Make each assignment to define a distinct variable with independent type #18516
Comments
Cool! Do you think it makes sense and would be sufficiently easy to implement to differentiate between annotated and unannotated variables (eventually depending on another option)? I mean something like this: --allow-redefinition-soft
x = 1
x = ""
reveal_type(x) # `str`
y: int = 1
y = "" # error
reveal_type(y) # `int`
z: int = 1
z: str = "" # error
reveal_type(z) # `int` --allow-redefinition-medium
x = 1
x = ""
reveal_type(x) # `str`
y: int = 1
y = "" # error
reveal_type(y) # `int`
z: int = 1
z: str = ""
reveal_type(z) # `str` --allow-redefinition-strong
x = 1
x = ""
reveal_type(x) # `str`
y: int = 1
y = ""
reveal_type(y) # `str`
z: int = 1
z: str = ""
reveal_type(z) # `str` |
My current work-in-progress implementation behaves almost like your if f():
x: int = 0
else:
x: str = "" I'm still figuring out what the exact rules should be. |
@JukkaL I was thinking about our today's discussion on implementing this using binder. I found one case where we need to be careful, imagine we have a conditional definition at class level that must be deferred: class C:
if bool():
x = 1
else:
x = somehow.defer then after deferring and processing some other code involving
|
Created another issue which explains in some detail how to implement this using the binder: I'm currently prototyping both approaches, and the binder based approach seems much simpler (but less powerful) so far, which is probably a good tradeoff. Using renaming for this seems pretty complicated. |
These long-standing issues can be solved by generalizing the variable renaming pass that is used by
--allow-redefinition
:Each assignment to a name would generate a separate internal variable. We will use "phi nodes" to merge these variables when different control flow paths assign to different variants. Here is a simple example:
The new variable renaming pass would produce a new AST that resembles this program (note that
phi(...)
is a new special AST node type and not a function call):This resembles the static single assignment form (SSA) used by many compilers, but probably would not conform to it 100% due to various practical reasons.
I'm working on a prototype implementation.
I hope that we can make this sufficiently compatible with the current semantics so that we can enable it by default (in mypy 2.0, possibly).
An alternative way to provide similar functionality would be to infer variable types from multiple assignments, similar to what already happens if a variable is declared as
x: object
. The renaming approach has a few notable benefits:x.append
call).--allow-redefinition
.The text was updated successfully, but these errors were encountered: