Mercurial > hg-stable
changeset 30024:26a4e46af2bc
demandimport: error out early on missing attribute of non package (issue5373)
If the parent module isn't a package, all valid attributes must be obtained
from it. We can raise ImportError early if any attributes not found.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Mon, 26 Sep 2016 23:28:57 +0900 |
parents | 16a09ae318b4 |
children | ff17dff99295 |
files | mercurial/demandimport.py tests/test-demandimport.py tests/test-demandimport.py.out |
diffstat | 3 files changed, 18 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/demandimport.py Tue Sep 27 21:56:00 2016 +0900 +++ b/mercurial/demandimport.py Mon Sep 26 23:28:57 2016 +0900 @@ -191,11 +191,16 @@ def processfromitem(mod, attr): """Process an imported symbol in the import statement. - If the symbol doesn't exist in the parent module, it must be a - module. We set missing modules up as _demandmod instances. + If the symbol doesn't exist in the parent module, and if the + parent module is a package, it must be a module. We set missing + modules up as _demandmod instances. """ symbol = getattr(mod, attr, nothing) + nonpkg = getattr(mod, '__path__', nothing) is nothing if symbol is nothing: + if nonpkg: + # do not try relative import, which would raise ValueError + raise ImportError('cannot import name %s' % attr) mn = '%s.%s' % (mod.__name__, attr) if mn in ignore: importfunc = _origimport
--- a/tests/test-demandimport.py Tue Sep 27 21:56:00 2016 +0900 +++ b/tests/test-demandimport.py Mon Sep 26 23:28:57 2016 +0900 @@ -63,6 +63,15 @@ print("re.stderr =", f(re.stderr)) print("re =", f(re)) +import contextlib +print("contextlib =", f(contextlib)) +try: + from contextlib import unknownattr + print('no demandmod should be created for attribute of non-package ' + 'module:\ncontextlib.unknownattr =', f(unknownattr)) +except ImportError as inst: + print('contextlib.unknownattr = ImportError: %s' % inst) + demandimport.disable() os.environ['HGDEMANDIMPORT'] = 'disable' # this enable call should not actually enable demandimport!
--- a/tests/test-demandimport.py.out Tue Sep 27 21:56:00 2016 +0900 +++ b/tests/test-demandimport.py.out Mon Sep 26 23:28:57 2016 +0900 @@ -16,4 +16,6 @@ re = <unloaded module 'sys'> re.stderr = <open file '<whatever>', mode 'w' at 0x?> re = <proxied module 'sys'> +contextlib = <unloaded module 'contextlib'> +contextlib.unknownattr = ImportError: cannot import name unknownattr node = <module 'mercurial.node' from '?'>