Important: Pyodide takes time to initialize. Initialization completion is indicated by a red border around Run all button.

In the previous post I discussed how to implement simple parsing expression grammar based parsing, and I mentioned that the notebook is available in runnable source form. This brings a question however. How do we make use of this notebook in later posts? A way forward is to hook into the Python import system. We start with our prerequisites


Python finds and imports modules using a two step process. In the first step, it searches through objects in sys.meta_path. These are MetaPathFinder objects that implement a single method find_spec() and will respond with a module spec if that object serves this particular module. Hence, we define our meta path finder, which if present in the system meta-path, will allow us to substitute our own module loaders.


Next we define our own loaders. A loader only needs to provide two functions create_module(self, spec) which returns an new module e.g. types.ModuleType(m_name) and exec_module(self, module) which executes the code of our module in the module object passed in as the parameter. While we can do this, there is a better way. Python provides a number of specialized implementations of this class that provides a lot of functionalities we need. SourceLoader class is one such. It needs us to implement get_filename() that takes the module_name and returns the file location of the module. Next is get_data() which takes that file location, and returns the source code. So, we implement a subclass that contains a few utility methods.


Provides basic services for module loading. It requires another method to be defined. fetch() when given the module location, fetches the module source (if it can’t find it, it returns None). If we have the fetch() method defined in a subclass, it is used to find which modules we can serve. For any module we can serve, we register ourselves and return True for has().


The simplest loader. Checks for existence in the local file system.


The web loader checks for accessibility of the module through URL given.


The pyodide loader is active only if the environment is a browser.


The imorter class holds everything together.

Testing it.

As before the source code is available here.