I want to manipulate python source code using the inspect module.
Given some source text I can create a module from it
from types import ModuleType
mod = ModuleType('sample','Sample module doc')
exec('i=13\nj=14*i',mod.__dict__)
mod.__file__ = '<something>'
however inspect cannot give information about the source because ‘<something>’ is not a real filesystem thing.
Is there a way to spoof the inspect module source handling so it knows about my generated module? I tried a couple of things eg mod. __file__ = StringIO(…) etc, but did not succeed.
You can see that there are specific conditions for allowing fake files of the format <something>, they just need to be added to linecache.cache. I haven’t actually tried this myself and can’t right now, but that should be a working solution.
Thanks for the advice. I had already looked at using linecache, but although ‘<something>’ is a pass through in inspect.findsource it seems to be a nogo in linecache.lazycache so I have to use a more regular name. This seems to work
from types import ModuleType
mod = ModuleType('sample','Sample module doc')
src = 'i=13\nj=14*i'
exec(src,mod.__dict__)
class _502Loader:
def __init__(self,src):
self._src = src
def get_source(self,filename):
return self._src
mod.__file__ = 'sample-fn'
mod.__loader__ = _502Loader(src)
linecache.lazycache(mod.__file__,mod.__dict__)
print(f'{mod.__name__=} {inspect.getsource(mod)=!r}')
``` and produces