Issue 4438: Given a module hierarchy string 'a.b.c', add an easy way to import tail module 'c' (original) (raw)

Created on 2008-11-26 11:58 by mrts, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
issue4438.diff mrts,2008-11-26 14:23 Add 'submodule' argument to __import__()
imp_import_module.diff mrts,2008-11-28 19:01
Messages (8)
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) * (Python committer) 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.
History
Date User Action Args
2022-04-11 14:56:41 admin set github: 48688
2009-04-01 18:46:48 georg.brandl set status: open -> closednosy: + georg.brandlmessages: + resolution: out of date
2008-11-28 19:09:09 mrts set components: - Interpreter Coretitle: Add an easy way to __import___ submodules -> Given a module hierarchy string 'a.b.c', add an easy way to import tail module 'c'
2008-11-28 19:05:43 mrts set messages: +
2008-11-28 19:02:09 mrts set files: + imp_import_module.diffmessages: +
2008-11-27 20:49:07 mrts set messages: +
2008-11-27 12:53:31 mrts set messages: +
2008-11-26 15:15:53 mrts set messages: +
2008-11-26 14:23:58 mrts set files: + issue4438.diffkeywords: + patchmessages: +
2008-11-26 11:58:38 mrts create