From : """ runpy needs a non-standard PEP 302 extension to set __file__ correctly in the modules it runs. The pkgutil stuff it uses to find pure Python modules in the filesystem supports that extension, but zipimport doesn't (yet). """ -- Nick Coghlan I am working on a patch.
I have attached a rough patch implementing the get_filename. I deliberately copied code from get_source method that finds the filename inside the zip archive and simply prefixed that with the archive path. I could not find any detailed discussion of what get_filename is supposed to do. Pkgutil's get_filename is not documented and not unit- tested. Google search revealed an old thread at <http://mail.python.org/pipermail/python-dev/2006-April/063626.html>, but it only says """ >runpy needs a get_filename() method, so it knows what to set __file__ too - >currently its emulation supports that, but it isn't officially part of the >PEP >302 API. It sounds like maybe a new PEP is needed to document all the extensions to the importer/loader protocols. :( """ I don't think a brand new PEP is needed, but an amendment to PEP 302 would be helpful. Nick, do you have any notes on what get_filename should do in various cases? My implementation fixes one of the problems in : $ ./python.exe testmodule.zip ********************************************************************** File "testmodule.zip/__main__.py", line ?, in __main__.c Failed example: 'line 2' Expected nothing Got: 'line 2' ********************************************************************** 1 items had failures: 1 of 1 in __main__.c ***Test Failed*** 1 failures. Note that line number is still reported as '?', but there is no crash.
The spec get_filename is pretty simple: Return whatever __file__ would be set to if load_module() was called for this module. (runpy's problem is that it never actually loads the module in question, so it never gets the chance to interrogate __file__)
Correction - added as _get_filename() in that revision. Documenting it and making it public (i.e. removing the underscore) is still to be done, and will only be done for 2.7/3.1