Greetings, I'm a student that has been working lately on feature of the runpy module that I have been quite interested in: execution of extension modules using the -m switch.
Currently this requires access to the module's code, so it only works for modules written in Python. I have a proof-of-concept implementation that adds a new ExtensionFileLoader method called "exec_as_main". The runpy module then checks if the loader has this method, and if so, calls it instead of getting the the code and running that.
This new method calls into the _imp module, which executes the module as a script. I can see two ways of doing this. Both expect that the module uses PEP 489 multi-phase initialization.
The first way is having a new PyModuleDef_Slot called Py_mod_main, which names a function to execute when run as main.
The second way is running a module's Py_mod_exec inside the __main__ module's namespace, as it's done for normal modules. The module would then do a `if __name__ == "__main__"` check. This is possible for modules that don't define Py_mod_create: they expect a default module object to be created for them, so we can pass the __main__ module to their Py_mod_exec function. This way would mean that, for example, modules written in Cython would behave like their Python counterparts.
Another possibility would be to use both, allowing both easy Cython- style modules and a dedicated slot for modules that need custom Py_mod_create.
My proof of concept uses another combination: it requires Py_mod_main and runs it in the __main__ namespace. But that can change based on discussion here.
Link to the implementation: https://github.com/Traceur759/cpython/tree/ main_c_modules Diff from master: https://github.com/python/cpython/compare/master...Tr aceur759:main_c_modules
You can quickly test it with: $ ./python -m _testmultiphase This is an extension module named __main__