Message 266746 - Python tracker (original) (raw)
BIKESHEDDING
Here is another concern with decorators and .__module__
(or inspect.getmodule
). (Or is it the original concern?)
If an earlier decorator creates a wrapper and doesn't set .module, you'll make the function public in the wrong module.
@public
@bad_wrapper
def f(...): ...
IMO, the correct solution is a new stdlib function, to get the currently-loading module. You wouldn't need explicit frame hacking, and it will be portable between different Python implementations because each implementation will have to define it correctly.
The problem with this solution is the lack of other usecases for such a function, though maybe someone in python-ideas can think of one.
Candidate owners: sys, importlib.
Candidate names:
- sys.getloadingmodule()
- importlib.currentimport()
- importlib.???()
Effect:
- Returns the "innermost" loading module. If no module is loading, returns None?
- In a thread, return the module being loaded in that thread (possibly None, even if other threads are loading modules).
- (I don't know what I'm talking about:) If a Python implementation uses multithreaded loading, each thread whose result could immediately be loaded into the module's namespace (i.e. it's close to the "surface" of the load) is considered to be loading that module.
- Needs to handle re-imports, such as from
importlib.reload
.
Other solutions include:
- Require explicit
@public(__all__)
(or__module__
) - Special
super()
-like treatment ofpublic
which automatically inserts the__all__
(or whatever). - Hope that bad wrappers don't come up.
I think nonexistence of module.all should be an error.
The behavior with a module with all is very different from one without, so I think that if you want your module to have all, you should be required to create it, even if it's empty.
Assuming that all is, by convention, always near the top, someone reading your code would know whether the first dozen or so functions are part of the public interface, without searching for @public
.