msg76460 - (view) |
Author: Mart Sõmermaa (mrts) |
Date: 2008-11-26 11:58 |
The need to dynamically import module foo given a module name string 'bar.baz.foo' is quite common. Quite often, the hack described in http://bugs.python.org/issue2090 is used (see e.g. the Google code results linked from the issue). Quoting Brett Cannon from the issue: "I plan to add a much simpler API to the imp module for people to use directly so that these abuses don't continue." Although there are reasonable workarounds, let the current ticket be a remainder for Brett that his plan is indeed needed. Perhaps the easiest thing to do would be to add yet another argument, e.g. 'toplevel', to __import__, such that: >>> __import__('imprt.foo.foo') # toplevel=True by default <module 'imprt' from 'imprt/__init__.pyc'> >>> __import__('imprt.foo.foo', toplevel=False) <module 'imprt.foo.foo' from 'imprt/foo/foo.pyc'> The latter can currently be achieved by >>> __import__('imprt.foo.foo', {}, {}, ['foo']) <module 'imprt.foo.foo' from 'imprt/foo/foo.pyc'> which is cumbersome if the module name is given in a string, resulting in unnecessarily complex code: modname = "imprt.foo.foo" >>> __import__(modname, {}, {}, [modname.rsplit(".", 1)[-1]]) <module 'imprt.foo.foo' from 'imprt/foo/foo.pyc'> |
|
|
msg76466 - (view) |
Author: Mart Sõmermaa (mrts) |
Date: 2008-11-26 14:23 |
Attached is a naive proof-of-concept implementation (that breaks things, i.e. the real implementation should strive for better general compatibility), but works as expected: >>> __import__('imprt.foo.foo', submodule=True) <module 'imprt.foo.foo' from 'imprt/foo/foo.py'> >>> __import__('imprt.foo.foo', submodule=False) <module 'imprt' from 'imprt/__init__.py'> >>> __import__('imprt.foo.foo') <module 'imprt' from 'imprt/__init__.py'> # Die on unexpected arguments like strings, lists etc to # avoid confusion >>> __import__('imprt.foo.foo', submodule='z') Traceback (most recent call last): File "", line 1, in TypeError: an integer is required |
|
|
msg76468 - (view) |
Author: Mart Sõmermaa (mrts) |
Date: 2008-11-26 15:15 |
Just a note that `make test` passes: 322 tests OK. 38 tests skipped: test_aepack test_al test_applesingle test_bsddb test_bsddb185 test_bsddb3 test_cd test_cl test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_curses test_dbm test_dl test_gl test_imageop test_imgfile test_kqueue test_linuxaudiodev test_macos test_macostools test_normalization test_ossaudiodev test_pep277 test_py3kwarn test_scriptpackages test_socketserver test_startfile test_sunaudiodev test_tcl test_timeout test_urllib2net test_urllibnet test_winreg test_winsound test_zipfile64 3 skips unexpected on linux2: test_tcl test_dbm test_bsddb |
|
|
msg76497 - (view) |
Author: Mart Sõmermaa (mrts) |
Date: 2008-11-27 12:53 |
Corrections and clarifications: * I'd say labeling the patch naive and "breaking things" was misleading (there was a breakage that resulted from stale files with incorrect permissions from my previous build of Python 2.6; after a make distclean all tests passed as described above). The patch is correct and backwards-compatible in Python level, but it introduces a change in the C API: PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(char *name, - PyObject *globals, PyObject *locals, PyObject *fromlist, int level); + PyObject *globals, PyObject *locals, PyObject *fromlist, + int level, char submodule); * The patch was made against Python 2.6 release source. * The argument is named 'submodule' instead of 'toplevel' to avoid confusion with 'level'. |
|
|
msg76515 - (view) |
Author: Mart Sõmermaa (mrts) |
Date: 2008-11-27 20:49 |
See also http://mail.python.org/pipermail/python-dev/2008-November/083727.html |
|
|
msg76549 - (view) |
Author: Mart Sõmermaa (mrts) |
Date: 2008-11-28 18:59 |
Implement imp.import_module() instead. See http://mail.python.org/pipermail/python-dev/2008-November/083758.html |
|
|
msg76550 - (view) |
Author: Mart Sõmermaa (mrts) |
Date: 2008-11-28 19:05 |
Note that the hack described in http://bugs.python.org/issue2090 should be disabled once this gets integrated. |
|
|
msg85071 - (view) |
Author: Georg Brandl (georg.brandl) *  |
Date: 2009-04-01 18:46 |
This feature is implemented as importlib.import_modules() in 2.7 and 3.1; for earlier versions there is also a backport on PyPI. |
|
|