Reputation: 2427
There is a nice way to get a path for a module where a class was defined, just do
inspect.getfile(obj.__class__)
Unfortunately, it seems to break down for files loaded by importlib:
spec = importlib.util.spec_from_file_location('loaded_module', module_path)
M = importlib.util.module_from_spec(spec)
spec.loader.exec_module(M)
obj = M.MyClass()
inspect.getfile(obj.__class__)
results in
File "/nix/store/z65l1jqvxa58zzwwa3bvglb6asj4y8cv-python3-3.8.5/lib/python3.8/inspect.py", line 665, in getfile
raise TypeError('{!r} is a built-in class'.format(object))
TypeError: <class 'loaded_module.MyClass'> is a built-in class
Any ideas how to fix this?
Upvotes: 1
Views: 621
Reputation: 69844
The expectation of inspect.getfile
is that the class
object (which has a string __module__
attribute which is the module name) has its module in sys.modules
(where a module can be looked up by name)
without the module in sys.modules
it cannot use that chain to find your file
to put it into sys.modules
you'd do something like:
sys.modules[M.__name__] = M
but if you have access to the M
object somewhere, you can access .__file__
directly, or if you have access to the loader
alternatively, if you know some method is defined on the class in that file, you can interrogate the code object of that function:
>>> M.C.__init__.__code__.co_filename
t.py
Upvotes: 1