diff tests/test-extension.t @ 19933:621a26eb3a99

demandimport: allow extensions to import own modules by absolute name Before this patch, python modules of each extensions can't import another one in own extension by absolute name, because root modules of each extensions are loaded with "hgext_" prefix. For example, "import extroot.bar" in "extroot/foo.py" of "extroot" extension fails, even though "import bar" in it succeeds. Installing extensions into site-packages of python library path can avoid this problem, but this solution is not reasonable in some cases: using binary package of Mercurial on Windows, for example. This patch retries to import with "hgext_" prefix after ImportError, if the module in the extension may try to import another one in own extension. This patch doesn't change some "_import()"/"_origimport()" invocations below, because ordinary extensions shouldn't cause such invocations. - invocation of "_import()" when root module imports sub-module by absolute path without "fromlist" for example, "import a.b" in "a.__init__.py". extensions are loaded with "hgext_" prefix, and this causes execution of another (= fixed by this patch) code path. - invocation of "_origimport()" when "level != -1" with "fromlist" for example, importing after "from __future__ import absolute_import" (level == 0), or "from . import b" or "from .a import b" (0 < level), for portability between python versions and environments, extensions shouldn't cause "level != -1".
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Sat, 05 Oct 2013 01:02:22 +0900
parents e3a5922e18c3
children a1f99a7f2d72
line wrap: on
line diff
--- a/tests/test-extension.t	Sat Oct 05 01:02:22 2013 +0900
+++ b/tests/test-extension.t	Sat Oct 05 01:02:22 2013 +0900
@@ -168,6 +168,97 @@
   $TESTTMP/a
 #endif
 
+Check absolute/relative import of extension specific modules
+
+  $ mkdir $TESTTMP/extroot
+  $ cat > $TESTTMP/extroot/bar.py <<EOF
+  > s = 'this is extroot.bar'
+  > EOF
+  $ mkdir $TESTTMP/extroot/sub1
+  $ cat > $TESTTMP/extroot/sub1/__init__.py <<EOF
+  > s = 'this is extroot.sub1.__init__'
+  > EOF
+  $ cat > $TESTTMP/extroot/sub1/baz.py <<EOF
+  > s = 'this is extroot.sub1.baz'
+  > EOF
+  $ cat > $TESTTMP/extroot/__init__.py <<EOF
+  > s = 'this is extroot.__init__'
+  > import foo
+  > def extsetup(ui):
+  >     ui.write('(extroot) ', foo.func(), '\n')
+  > EOF
+
+  $ cat > $TESTTMP/extroot/foo.py <<EOF
+  > # test absolute import
+  > buf = []
+  > def func():
+  >     # "not locals" case
+  >     import extroot.bar
+  >     buf.append('import extroot.bar in func(): %s' % extroot.bar.s)
+  > 
+  >     return '\n(extroot) '.join(buf)
+  > 
+  > # "fromlist == ('*',)" case
+  > from extroot.bar import *
+  > buf.append('from extroot.bar import *: %s' % s)
+  > 
+  > # "not fromlist" and "if '.' in name" case
+  > import extroot.sub1.baz
+  > buf.append('import extroot.sub1.baz: %s' % extroot.sub1.baz.s)
+  > 
+  > # "not fromlist" and NOT "if '.' in name" case
+  > import extroot
+  > buf.append('import extroot: %s' % extroot.s)
+  > 
+  > # NOT "not fromlist" and NOT "level != -1" case
+  > from extroot.bar import s
+  > buf.append('from extroot.bar import s: %s' % s)
+  > EOF
+  $ hg --config extensions.extroot=$TESTTMP/extroot root
+  (extroot) from extroot.bar import *: this is extroot.bar
+  (extroot) import extroot.sub1.baz: this is extroot.sub1.baz
+  (extroot) import extroot: this is extroot.__init__
+  (extroot) from extroot.bar import s: this is extroot.bar
+  (extroot) import extroot.bar in func(): this is extroot.bar
+  $TESTTMP/a
+
+#if no-py3k
+  $ rm -f $TESTTMP/extroot/foo.*
+  $ cat > $TESTTMP/extroot/foo.py <<EOF
+  > # test relative import
+  > buf = []
+  > def func():
+  >     # "not locals" case
+  >     import bar
+  >     buf.append('import bar in func(): %s' % bar.s)
+  > 
+  >     return '\n(extroot) '.join(buf)
+  > 
+  > # "fromlist == ('*',)" case
+  > from bar import *
+  > buf.append('from bar import *: %s' % s)
+  > 
+  > # "not fromlist" and "if '.' in name" case
+  > import sub1.baz
+  > buf.append('import sub1.baz: %s' % sub1.baz.s)
+  > 
+  > # "not fromlist" and NOT "if '.' in name" case
+  > import sub1
+  > buf.append('import sub1: %s' % sub1.s)
+  > 
+  > # NOT "not fromlist" and NOT "level != -1" case
+  > from bar import s
+  > buf.append('from bar import s: %s' % s)
+  > EOF
+  $ hg --config extensions.extroot=$TESTTMP/extroot root
+  (extroot) from bar import *: this is extroot.bar
+  (extroot) import sub1.baz: this is extroot.sub1.baz
+  (extroot) import sub1: this is extroot.sub1.__init__
+  (extroot) from bar import s: this is extroot.bar
+  (extroot) import bar in func(): this is extroot.bar
+  $TESTTMP/a
+#endif
+
   $ cd ..
 
 hide outer repo