[cwconfig] create a virtual "cubes" package
authorPhilippe Pepiot <philippe.pepiot@logilab.fr>
Mon, 23 Jan 2017 15:35:19 +0100
changeset 11920 f13799fbcfea
parent 11919 3a6746dfc57f
child 11929 fcbd6b251d81
[cwconfig] create a virtual "cubes" package _CubesImporter now handle import of "cubes" and return a virtual module so that "cubes" is always importable without having to create a __init__.py in CUBES_DIR and add CUBES_DIR/.. to sys.path. Drop custom code in setup.py used to create CUBES_DIR/__init__.py and drop now useless warning when cubicweb is installed in develop mode Update test_cubes_path() and ensure 'cubes.file' is not loaded before testing its import. This test seems to have mistakes because cubes are loaded automatically when discovering cw commands (cubes.<x>.ccplugin), not sure how this should be fixed definitely.
cubicweb/__init__.py
cubicweb/cwconfig.py
cubicweb/test/unittest_cwconfig.py
setup.py
--- a/cubicweb/__init__.py	Fri Jan 20 18:17:04 2017 +0100
+++ b/cubicweb/__init__.py	Mon Jan 23 15:35:19 2017 +0100
@@ -26,6 +26,7 @@
 import pickle
 import pkgutil
 import sys
+import types
 import warnings
 import zlib
 
@@ -294,7 +295,9 @@
             sys.meta_path.append(self)
 
     def find_module(self, fullname, path=None):
-        if fullname.startswith('cubes.'):
+        if fullname == 'cubes':
+            return self
+        elif fullname.startswith('cubes.'):
             modname = 'cubicweb_' + fullname.split('.', 1)[1]
             try:
                 modinfo = imp.find_module(modname)
@@ -302,3 +305,9 @@
                 return None
             else:
                 return pkgutil.ImpLoader(fullname, *modinfo)
+
+    def load_module(self, fullname):
+        if fullname != 'cubes':
+            raise ImportError('No module named {0}'.format(fullname))
+        mod = sys.modules[fullname] = types.ModuleType(fullname, doc='CubicWeb cubes')
+        return mod
--- a/cubicweb/cwconfig.py	Fri Jan 20 18:17:04 2017 +0100
+++ b/cubicweb/cwconfig.py	Mon Jan 23 15:35:19 2017 +0100
@@ -698,14 +698,8 @@
         """update python path if necessary"""
         from cubicweb import _CubesImporter
         _CubesImporter.install()
-        cubes_parent_dir = normpath(join(cls.CUBES_DIR, '..'))
-        if not cubes_parent_dir in sys.path:
-            sys.path.insert(0, cubes_parent_dir)
-        try:
-            import cubes
-            cubes.__path__ = cls.cubes_search_path()
-        except ImportError:
-            return # cubes dir doesn't exists
+        import cubes
+        cubes.__path__ = cls.cubes_search_path()
 
     @classmethod
     def load_available_configs(cls):
--- a/cubicweb/test/unittest_cwconfig.py	Fri Jan 20 18:17:04 2017 +0100
+++ b/cubicweb/test/unittest_cwconfig.py	Mon Jan 23 15:35:19 2017 +0100
@@ -241,7 +241,8 @@
         from cubes import mycube
         self.assertEqual(mycube.__path__, [join(self.custom_cubes_dir, 'mycube')])
         # file cube should be overriden by the one found in data/cubes
-        if sys.modules.pop('cubes.file', None) and PY3:
+        sys.modules.pop('cubes.file')
+        if hasattr(cubes, 'file'):
             del cubes.file
         from cubes import file
         self.assertEqual(file.__path__, [join(self.custom_cubes_dir, 'file')])
--- a/setup.py	Fri Jan 20 18:17:04 2017 +0100
+++ b/setup.py	Mon Jan 23 15:35:19 2017 +0100
@@ -149,40 +149,16 @@
                 dest = join(self.install_dir, src)
                 export(src, dest, verbose=self.verbose)
 
-# write required share/cubicweb/cubes/__init__.py
-class MyInstallData(install_data.install_data):
-    """A class That manages data files installation"""
-    def run(self):
-        """overridden from install_data class"""
-        install_data.install_data.run(self)
-        path = join(self.install_dir, 'share', 'cubicweb', 'cubes', '__init__.py')
-        ini = open(path, 'w')
-        ini.write('# Cubicweb cubes directory\n')
-        ini.close()
-
-
-class CWDevelop(develop.develop):
-    """Custom "develop" command warning about (legacy) cubes directory not
-    installed.
-    """
-
-    def run(self):
-        cubespath = join(sys.prefix, 'share', 'cubicweb', 'cubes')
-        self.warn('develop command does not install (legacy) cubes directory (%s)'
-                  % cubespath)
-        return develop.develop.run(self)
-
 
 # re-enable copying data files in sys.prefix
-# overwrite MyInstallData to use sys.prefix instead of the egg directory
-MyInstallMoreData = MyInstallData
-class MyInstallData(MyInstallMoreData): # pylint: disable=E0102
+# overwrite install_data to use sys.prefix instead of the egg directory
+class MyInstallData(install_data.install_data):
     """A class that manages data files installation"""
     def run(self):
         _old_install_dir = self.install_dir
         if self.install_dir.endswith('egg'):
             self.install_dir = sys.prefix
-        MyInstallMoreData.run(self)
+        install_data.install_data.run(self)
         self.install_dir = _old_install_dir
 try:
     import setuptools.command.easy_install # only if easy_install available
@@ -263,7 +239,6 @@
     cmdclass={
         'install_lib': MyInstallLib,
         'install_data': MyInstallData,
-        'develop': CWDevelop,
     },
     zip_safe=False,
 )