Mercurial > hg
diff hgdemandimport/demandimportpy2.py @ 33531:9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
In general, the attribute of the same name is overwritten by executing an
import statement.
import a.b
print(a.b.c) # 'c' of a/b/__init__.py
from a.b.c import d
print(a.b.c) # a/b/c.py
However, this appears not true for the scenario described in the test case,
and surprisingly, "from a.b.c import d" works even if "a.b.c" is not a module.
This patch works around the problem by taking the right module from sys.modules
if available.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 16 Jul 2017 17:38:39 +0900 |
parents | 05e3fa254b6b |
children | 8fb5212652ec |
line wrap: on
line diff
--- a/hgdemandimport/demandimportpy2.py Sun Jul 16 17:19:22 2017 +0900 +++ b/hgdemandimport/demandimportpy2.py Sun Jul 16 17:38:39 2017 +0900 @@ -227,10 +227,14 @@ # recurse down the module chain, and return the leaf module mod = rootmod for comp in modname.split('.')[1:]: - if getattr(mod, comp, nothing) is nothing: - setattr(mod, comp, _demandmod(comp, mod.__dict__, - mod.__dict__, level=1)) - mod = getattr(mod, comp) + obj = getattr(mod, comp, nothing) + if obj is nothing: + obj = _demandmod(comp, mod.__dict__, mod.__dict__, level=1) + setattr(mod, comp, obj) + elif mod.__name__ + '.' + comp in sys.modules: + # prefer loaded module over attribute (issue5617) + obj = sys.modules[mod.__name__ + '.' + comp] + mod = obj return mod if level >= 0: