P
Paul Moore
I'm trying to write my own loader using importlib. And frankly, I'm getting nowhere. I'm struggling to understand precisely which methods of the various ABCs I need to implement, and in some cases what they should do.
Could anyone point me to a simple example (say, something that implements zip imports using the zipfile module - that was what I initially tried to get working as a proof of concept).
Where I've got to is the following stub implementation to try to log the sequence of calls:
from importlib.abc import PathEntryFinder, SourceLoader
class MyFinder(PathEntryFinder):
def __init__(self, pathentry):
"""Create a finder for the given `pathentry`"""
if pathentry == 'foo':
return
raise ImportError
def find_loader(self, fullname):
"""Return a loader for the module `fullname`"""
print("find_loader('{}')".format(fullname))
return MyLoader(), ['foo']
class MyLoader(SourceLoader):
def module_repr(self):
print("module_repr()")
return True
def is_package(self, fullname):
print("is_package('{}')".format(fullname))
return True
def get_data(self, path):
"""Return an open binary file object for `path`"""
print("get_data('{}')".format(path))
return b"print('hello from foo!')"
def get_filename(self, fullname):
"""Return the filename for module `fullname`"""
print("get_filename('{}')".format(fullname))
return '/this/is/foo'
if __name__ == '__main__':
import sys
sys.path_hooks.append(lambda p: MyFinder(p))
sys.path.insert(0, 'foo')
import a
import a.b
from a.b.c import x
It prints out
is_package('a')
get_filename('a')
get_data('/this/is/foo')
get_filename('a')
is_package('a')
hello from foo!
Traceback (most recent call last):
File ".\loader.py", line 46, in <module>
import a.b
ImportError: No module named 'a.b'
which is a good start, but I don't know why it isn't willing to check for 'a.b' (after all, I tell it that 'a' is a package).
I'm quite probably doing something trivially wrong here - after all, I'm not even *trying* to implement a sane view of a package structure here. But I'd have expected at least a find_loader('a.b') call...
Thanks for any help,
Paul.
Could anyone point me to a simple example (say, something that implements zip imports using the zipfile module - that was what I initially tried to get working as a proof of concept).
Where I've got to is the following stub implementation to try to log the sequence of calls:
from importlib.abc import PathEntryFinder, SourceLoader
class MyFinder(PathEntryFinder):
def __init__(self, pathentry):
"""Create a finder for the given `pathentry`"""
if pathentry == 'foo':
return
raise ImportError
def find_loader(self, fullname):
"""Return a loader for the module `fullname`"""
print("find_loader('{}')".format(fullname))
return MyLoader(), ['foo']
class MyLoader(SourceLoader):
def module_repr(self):
print("module_repr()")
return True
def is_package(self, fullname):
print("is_package('{}')".format(fullname))
return True
def get_data(self, path):
"""Return an open binary file object for `path`"""
print("get_data('{}')".format(path))
return b"print('hello from foo!')"
def get_filename(self, fullname):
"""Return the filename for module `fullname`"""
print("get_filename('{}')".format(fullname))
return '/this/is/foo'
if __name__ == '__main__':
import sys
sys.path_hooks.append(lambda p: MyFinder(p))
sys.path.insert(0, 'foo')
import a
import a.b
from a.b.c import x
It prints out
find_loader('a')py .\loader.py
is_package('a')
get_filename('a')
get_data('/this/is/foo')
get_filename('a')
is_package('a')
hello from foo!
Traceback (most recent call last):
File ".\loader.py", line 46, in <module>
import a.b
ImportError: No module named 'a.b'
which is a good start, but I don't know why it isn't willing to check for 'a.b' (after all, I tell it that 'a' is a package).
I'm quite probably doing something trivially wrong here - after all, I'm not even *trying* to implement a sane view of a package structure here. But I'd have expected at least a find_loader('a.b') call...
Thanks for any help,
Paul.