python - Get source script details, similar to inspect.getmembers() without importing the script -
i'm trying source, callee list, defaults, keywords, args , varargs of functions in python script.
currently, i'm importing module , using python inspect
module's getmembers
function , passing isfunction
parameter so:
members = inspect.getmembers(mymodule, inspect.isfunction)
however, method doesn't work if mymodule
's imports aren't available me (since mymodule
has imported first).
i tried using python ast
module parse
, dump
syntax tree, getting function source involved hacky techniques and/or questionable , far maintainable third party libraries. believe i've scoured documentation , stackoverflow pretty thoroughly , have failed find suitable solution. missing something?
a possible workaround monkeypatch __import__
function custom function never throws importerror , returns dummy module instead:
def force_import(module): original_import = __import__ def fake_import(*args): try: return original_import(*args) except importerror: return __builtins__ __builtins__.__import__ = fake_import module = original_import(module) __builtins__.__import__ = original_import return module
this allow import mymodule
if dependencies cannot imported. can use inspect.getmembers
would:
mymodule = force_import('mymodule') members = inspect.getmembers(mymodule, inspect.isfunction)
a problem solution works around failing imports. if mymodule
tries access members of imported modules, import fail:
# mymodule.py import this_module_doesnt_exist # works print(this_module_doesnt_exist.variable) # fails
force_import('mymodule') # attributeerror: module 'builtins' has no attribute 'variable'
in order work around this, can create dummy class never throws attributeerror:
class dummyvalue: def __call__(self, *args, **kwargs): return self __getitem__ = __setitem__ = __delitem__ = __call__ __len__ = __length_hint__ = __bool__ = __call__ __iter__ = __next__ = __call__ __getattribute__ = __call__ __enter__ = __leave__ = __call__ __str__ = __repr__ = __format__ = __bytes__ = __call__ # etc
(see the data model documentation list of dunder methods may have implement.)
now if force_import
returns instance of class (change return __builtins__
return dummyvalue()
), importing mymodule
succeed.
Comments
Post a Comment