-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Support modification of builtins module. #12860
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
I'm working on some code that will analyze all names appearing in the collection of modules, prior to semantic or type analysis of any of those modules. It will identify the object being referred to by every occurrence of a name, taking into account imports (including cyclic imports) and name resolution rules. I will leave a hook for the builtins module, populating it from typeshed. This could be used by mypy to record changes made to builtins. |
Dynamically modifying the namespace of other modules goes against the whole notion of type checking and type safety. This is especially true for That said, there are legitimate uses for declaring new (non-standard) symbols in the We decided to support this in pyright through the use of a specially-named If that sounds like a good solution to the problem you've posed, perhaps mypy could adopt this same approach. |
I started a discussion on Python Ideas. |
Yes and no.
This could be deplored as untypesafe behavior, unless there were a way, with standard Python, to get these extra names added to builtins at the time that builtins is first built in the interpreter. Perhaps a special file name like builtins.py in the project root, and a way of rigging the import system so that importing 'builtins' will invoke some special loader (perhaps). |
@erictraut Help! I made an edit to the aforementioned discussion page, and its spam filter decided to hide it. Can you do anything to unfreeze it or tell me how I can do it for myself? |
Actually, I just got email saying that my post is being reviewed and should reappear soon. So never mind the above. |
Dynamically injecting new symbols into another module's namespace — especially the What is the benefit of doing this? To save an import statement? |
Maybe — but that's well outside the purview of mypy, which is a third-party type checker independent of CPython. Until such a time as CPython makes these changes (I think it's unlikely to ever make these changes), I don't think it's reasonable to expect mypy to support the kind of thing you're looking for here. I'm closing this issue — if anybody wants to request a mypy equivalent of the more limited feature Eric's introduced over at pyright, they can open another issue to do so. For the feature request you're making, @mrolle45, I don't think there's any realistic chance of mypy ever supporting dynamic modifications of |
Another possible work-around would be to write a plugin for mypy, but I agree we are very unlikely to support this use case |
Feature
Support modification of
builtins
module. That is, the one called<module 'builtins' (built-in)>
.I don't propose use of the name
__builtins__
because that is implementation dependent.Pitch
Why would anyone want to alter
builtins
?One use case would be a program involving several modules, and you want to make a name, like
foo
visible in all of them without having to explicitly import the name from some common module (or explicitly set it globally) in each of those modules.In one of the modules, perhaps main, you would have
Alternatively, you could have:
sys.modules['builtins].foo = 42
Then in every module, the name
foo
would have the value 42, just likeint
has the value<class int>
.Or would it always??
Any time the interpreter looks up the name
foo
as a global name, and it is not in the module's globals, it will look in thebuiltins
module as it exists at that time. After the module has been imported, then certainly thebuiltins
module is now in its modified state. But during the import of a module,builtins
may or may not have been modified yet.So what's mypy to do?
I think a reasonable approach would be to treat the modification as being visible everywhere, just like any other object which is visible as the same object in several modules' global namespaces through imports. It could be considered as a nameless member of the module's global namespace. That is, multiple assignments to the attribute
foo
could be checked for compatible types, and the first one that mypy encounters can be used to infer the type.If you want to go farther into analyzing where in the import of a module something happens, it's the same deal as any other object that might be imported from somewhere else. This is easy enough to resolve, unless there are import cycles involved. I've discussed problems with import cycles in some other issues I have posted, but the gist of it is that mypy would need to see if the identity of a name would vary depending on the order of actual imports at runtime, and any ambiguity ought to be considered an error.
The text was updated successfully, but these errors were encountered: