-
-
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
Expand imports in classes #11344
Expand imports in classes #11344
Conversation
This comment has been minimized.
This comment has been minimized.
Aha, I forgot about imports in methods. Whoops. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm!
Hello! I pushed some changes that should have resolved the comments! (I actually did this 24 days ago, but didn't realize it was probably best to leave a comment...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! This fixes a fairly nasty issue, but I think that we either need a somewhat more involved fix, or we can fall back to an even simpler workaround where we just reject this but don't crash.
if imported_id not in self.type.names.keys() and isinstance(defn, FuncDef): | ||
if not defn.is_decorated and not defn.is_overload: | ||
defn.info = self.type | ||
self.add_symbol(defn.name, defn, imp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately this doesn't seem right/enough. We modify the function as defined in the original module, but it should only be treated as a method in this class, not elsewhere. I wonder what would happen if import the same function into multiple classes. For completeness, we should probably do this for Decorator
and OverloadedFuncDef
as well.
Implementing this in a full and correct way seems somewhat complicated. We could perhaps take a copy of the original FuncDef
(or other node) and only modify the copy.
Alternatively, you could detect this and generate a blocking error, and not add anything to the symbol table. This would be the easiest fix. The error message can contain a note that suggests doing something like name = mod.func
instead.
class Foo: | ||
from a import func | ||
|
||
reveal_type(Foo().func) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test what happens if we import two functions with the same name (from different modules)?
Also test what happens if we import a function over an existing name.
Test multiple classes that import the same function.
Test calling the original function via module and instance.
I was running into this issue at work and foolishly missed this excellent PR. I ended up with something very similar to this, here's my patch:
It differs from this PR in that:
Curious if @A5rocks @JukkaL this looks workable to you? Edit: I was wrong about self binding. We do bind self if we import a Python function, but I tested with a C import. |
Just went through issues and updated the PR body with things I think are duplicate reports of this crash. It's quite a lot! |
Looks quite good to me (as long as it works); I haven't worked much on this PR as I ran into the mutable problem and couldn't figure it out.
Edit: I must have lost that stash :S |
Superseded by #12023 |
Description
(each on their own line since I don't know what GitHub does for syntax for these :P)
Fixes #11045, external reference huggingface/transformers#13390
Fixes #10488
Fixes #7045
Fixes #7806
Fixes #11641
Fixes #11351
Fixes #10488
(Sadly this does not fix the crash in #8891)
This PR makes
from module import function
in a class assign that function to the class.Explicitly out of scope (right now) is
import name
in a class makingClassThing.name.func_in_name
work.Test Plan
I verified these changes by running the reproduction steps of the issues listed as fixed, and put one of them in the unit tests.