19 |
19 |
20 from contextlib import contextmanager |
20 from contextlib import contextmanager |
21 import os |
21 import os |
22 from os import path |
22 from os import path |
23 import sys |
23 import sys |
24 import unittest |
|
25 |
24 |
26 from six import PY2 |
25 from six import PY2 |
27 |
26 |
28 from cubicweb import _CubesImporter |
27 from cubicweb import _CubesImporter |
29 from cubicweb.cwconfig import CubicWebConfiguration |
28 from cubicweb.cwconfig import CubicWebConfiguration |
30 from cubicweb.devtools.testlib import TemporaryDirectory |
29 from cubicweb.devtools.testlib import TemporaryDirectory, TestCase |
31 |
30 |
32 |
31 |
33 @contextmanager |
32 @contextmanager |
34 def temp_cube(): |
33 def temp_cube(): |
35 with TemporaryDirectory() as tempdir: |
34 with TemporaryDirectory() as tempdir: |
36 try: |
35 try: |
37 libdir = path.join(tempdir, 'libpython') |
36 libdir = path.join(tempdir, 'libpython') |
38 cubedir = path.join(libdir, 'cubicweb_foo') |
37 cubedir = path.join(libdir, 'cubicweb_foo') |
39 os.makedirs(cubedir) |
38 os.makedirs(cubedir) |
|
39 check_code = ("import logging\n" |
|
40 "logging.getLogger('cubicweb_foo')" |
|
41 ".warn('imported %s', __name__)\n") |
40 with open(path.join(cubedir, '__init__.py'), 'w') as f: |
42 with open(path.join(cubedir, '__init__.py'), 'w') as f: |
41 f.write('"""cubicweb_foo application package"""') |
43 f.write("'cubicweb_foo application package'\n" + check_code) |
42 with open(path.join(cubedir, 'bar.py'), 'w') as f: |
44 with open(path.join(cubedir, 'bar.py'), 'w') as f: |
43 f.write('baz = 1') |
45 f.write(check_code + 'baz = 1\n') |
44 sys.path.append(libdir) |
46 sys.path.append(libdir) |
45 yield cubedir |
47 yield cubedir |
46 finally: |
48 finally: |
47 sys.path.remove(libdir) |
49 sys.path.remove(libdir) |
48 |
50 |
49 |
51 |
50 class CubesImporterTC(unittest.TestCase): |
52 class CubesImporterTC(TestCase): |
51 |
53 |
52 def setUp(self): |
54 def setUp(self): |
53 # During discovery, CubicWebConfiguration.cls_adjust_sys_path may be |
55 # During discovery, CubicWebConfiguration.cls_adjust_sys_path may be |
54 # called (probably because of cubicweb.devtools's __init__.py), so |
56 # called (probably because of cubicweb.devtools's __init__.py), so |
55 # uninstall _CubesImporter. |
57 # uninstall _CubesImporter. |
102 else: |
104 else: |
103 import importlib |
105 import importlib |
104 new = importlib.reload(cubes) |
106 new = importlib.reload(cubes) |
105 self.assertIs(new, cubes) |
107 self.assertIs(new, cubes) |
106 |
108 |
|
109 def test_no_double_import(self): |
|
110 """Check new and legacy import the same module once""" |
|
111 with temp_cube(): |
|
112 CubicWebConfiguration.cls_adjust_sys_path() |
|
113 with self.assertLogs('cubicweb_foo', 'WARNING') as cm: |
|
114 from cubes.foo import bar |
|
115 from cubicweb_foo import bar as bar2 |
|
116 self.assertIs(bar, bar2) |
|
117 self.assertIs(sys.modules['cubes.foo'], |
|
118 sys.modules['cubicweb_foo']) |
|
119 self.assertEqual(cm.output, [ |
|
120 'WARNING:cubicweb_foo:imported cubicweb_foo', |
|
121 # module __name__ for subpackage differ along python version |
|
122 # for PY2 it's based on how the module was imported "from |
|
123 # cubes.foo import bar" and for PY3 based on __name__ of parent |
|
124 # module "cubicweb_foo". Not sure if it's an issue, but PY3 |
|
125 # behavior looks better. |
|
126 'WARNING:cubicweb_foo:imported ' + ( |
|
127 'cubes.foo.bar' if PY2 else 'cubicweb_foo.bar') |
|
128 ]) |
|
129 |
107 def test_import_legacy_cube(self): |
130 def test_import_legacy_cube(self): |
108 """Check that importing a legacy cube works when sys.path got adjusted. |
131 """Check that importing a legacy cube works when sys.path got adjusted. |
109 """ |
132 """ |
110 CubicWebConfiguration.cls_adjust_sys_path() |
133 CubicWebConfiguration.cls_adjust_sys_path() |
111 import cubes.card # noqa |
134 import cubes.card # noqa |