From patchwork Mon Nov 2 14:10:53 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: demandimport: fix level passed to loader of sub-modules From: Yuya Nishihara X-Patchwork-Id: 11258 Message-Id: To: mercurial-devel@selenic.com Date: Mon, 02 Nov 2015 23:10:53 +0900 # HG changeset patch # User Yuya Nishihara # Date 1446380349 -32400 # Sun Nov 01 21:19:09 2015 +0900 # Node ID d779ddd9edd51273de2754748dfcc0db1e1e0f72 # Parent 58b7f3e93bbab749ab16c09df12aae5ba7880708 demandimport: fix level passed to loader of sub-modules As the fromlist gives the names of sub-modules, they should be searched in the parent directory of the package's __init__.py, which is level=1. I got the following error by rewriting hgweb to use absolute_import, where the "mercurial" package is referenced as ".." (level=2): ValueError: Attempted relative import beyond toplevel package I know little about the import mechanism, but this change seems correct. Before this patch, the following code did import the os module with no error: from mercurial import demandimport demandimport.enable() from mercurial import os print os.name diff --git a/mercurial/demandimport.py b/mercurial/demandimport.py --- a/mercurial/demandimport.py +++ b/mercurial/demandimport.py @@ -164,7 +164,7 @@ def _demandimport(name, globals=None, lo # The name of the module the import statement is located in. globalname = globals.get('__name__') - def processfromitem(mod, attr, **kwargs): + 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 @@ -172,7 +172,7 @@ def _demandimport(name, globals=None, lo """ symbol = getattr(mod, attr, nothing) if symbol is nothing: - symbol = _demandmod(attr, mod.__dict__, locals, **kwargs) + symbol = _demandmod(attr, mod.__dict__, locals, level=1) setattr(mod, attr, symbol) # Record the importing module references this symbol so we can @@ -194,7 +194,7 @@ def _demandimport(name, globals=None, lo mod = _hgextimport(_origimport, name, globals, locals, level=level) for x in fromlist: - processfromitem(mod, x, level=level) + processfromitem(mod, x) return mod