Can Python's import
statement return a subclass of types.ModuleType
using import hooks? I would like to override __getattribute__
to display a runtime warning when code outside a certain module reference names that aren't in __all__
.
I know how to replace sys.modules['foo']
after it's been imported. What I want is to instrument modules that match a pattern as they are imported so the importing code has an opportunity to trigger the warning.
Python frowns on the idea of making things public and private. This idea isn't about preventing your module's users from typing from somemodule import sys
; instead, it is a documentation tool. This kind of instrumentation should make it much easier to document your module's API by including a correct __all__
. It should help you avoid accidentally referencing sys
as somemodule.sys
instead of simply import sys
.
This means all semantics of the function are derived from importlib. __import__() . The most important difference between these two functions is that import_module() returns the specified package or module (e.g. pkg. mod ), while __import__() returns the top-level package or module (e.g. pkg ).
In Python, import * means you are importing all the classes and functions from a library. E.g from maths import * will import all the classes and functions in the maths library.
The types module contains type objects for all object types defined by the standard interpreter, as Example 1-86 demonstrates. All objects of the same type share a single type object. You can use is to test if an object has a given type.
__loader__ is an attribute that is set on an imported module by its loader. Accessing it should return the loader object itself. In Python versions before 3.3, __loader__ was not set by the built-in import machinery. Instead, this attribute was only available on modules that were imported using a custom loader.
Since I missed the point of your question before you edited it, I thought I'd take another whack (while leaving my original answer for posterity).
Here's an alternative that also doesn't need the import hook. It can easily be used on a module-by-module basis: a module that includes this code will have the special __getattribute__()
behavior, while other modules will behave as usual.
class StrictModule(types.ModuleType):
def __getattribute__(self, key):
if key is "__dict__": # fake __dict__ with only visible attributes
return dict((k, v) for k, v in globals().iteritems()
if k.startswith("__") or k in __all__)
if (key.startswith("__") or key in __all__) and key in globals():
return globals()[key]
else:
raise AttributeError("'module' object has no attribute '%s'" % key)
def __setattr__(self, key, value):
globals()[key] = value
sys.modules[__name__] = StrictModule(__name__)
Keep in mind this "restriction" is easy to get around by simply calling the regular module
type's __getattribute__()
(or for that matter, the object
type's). I get the impression that you are trying to provide some kind of "private member" restriction for your modules. There's almost never any point to this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With