diff options
author | Sylvain Th?nault <sylvain.thenault@logilab.fr> | 2009-06-03 16:48:11 +0200 |
---|---|---|
committer | Sylvain Th?nault <sylvain.thenault@logilab.fr> | 2009-06-03 16:48:11 +0200 |
commit | b7e234f9993a61cf496a9955ddc4969a455f1982 (patch) | |
tree | 1bc65e8c5e0ef5a17bfba7847e210e8fdca04a59 | |
parent | db8f43a27308232acbc1ecb2becd0c9c04975822 (diff) | |
download | logilab-common-b7e234f9993a61cf496a9955ddc4969a455f1982.tar.gz |
new extrapath argument to modpath_from_file (see function's docstring for explanation)
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | modutils.py | 42 | ||||
-rw-r--r-- | test/unittest_modutils.py | 71 |
3 files changed, 69 insertions, 46 deletions
@@ -2,6 +2,8 @@ ChangeLog for logilab.common ============================ -- + * modutils: new extrapath argument to modpath_from_file (see function's + docstring for explanation) * adbh: new alter_column_support flag, sql_set_null_allowed and sql_change_col_type methods diff --git a/modutils.py b/modutils.py index 9db0b99..5755a4f 100644 --- a/modutils.py +++ b/modutils.py @@ -169,13 +169,28 @@ def load_module_from_file(filepath, path=None, use_sys=1): return load_module_from_modpath(modpath_from_file(filepath), path, use_sys) -def modpath_from_file(filename): +def _check_init(path, mod_path): + """check there are some __init__.py all along the way""" + for part in mod_path: + path = join(path, part) + if not _has_init(path): + return False + return True + + +def modpath_from_file(filename, extrapath=None): """given a file path return the corresponding splitted module's name (i.e name of a module or package splitted on '.') :type filename: str :param filename: file's path for which we want the module's name + :type extrapath: dict + :param extrapath: + optional extra search path, with path as key and package name for the path + as value. This is usually useful to handle package splited in multiple + directories using __path__ trick. + :raise ImportError: if the corresponding module's name has not been found @@ -184,24 +199,25 @@ def modpath_from_file(filename): :return: the corresponding splitted module's name """ base = splitext(abspath(filename))[0] + if extrapath is not None: + for path_ in extrapath: + path = abspath(path_) + if path and base[:len(path)] == path: + submodpath = [pkg for pkg in base[len(path):].split(os.sep) + if pkg] + if _check_init(path, submodpath[:-1]): + return extrapath[path_].split('.') + submodpath for path in sys.path: path = abspath(path) if path and base[:len(path)] == path: if filename.find('site-packages') != -1 and \ path.find('site-packages') == -1: continue - mod_path = [module for module in base[len(path):].split(os.sep) - if module] - for part in mod_path[:-1]: - path = join(path, part) - if not _has_init(path): - break - else: - break - else: - raise ImportError('Unable to find module for %s in %s' % ( - filename, ', \n'.join(sys.path))) - return mod_path + modpath = [pkg for pkg in base[len(path):].split(os.sep) if pkg] + if _check_init(path, modpath[:-1]): + return modpath + raise ImportError('Unable to find module for %s in %s' % ( + filename, ', \n'.join(sys.path))) diff --git a/test/unittest_modutils.py b/test/unittest_modutils.py index 248bd86..acf0e3e 100644 --- a/test/unittest_modutils.py +++ b/test/unittest_modutils.py @@ -24,7 +24,7 @@ from logilab.common.testlib import TestCase as TLTestCase, unittest_main from logilab.common import modutils from logilab.common.compat import set -from os import path +from os import path, getcwd from logilab import common from logilab.common import tree @@ -49,31 +49,31 @@ class _module_file_tc(TestCase): mtype, mfile = _module_file('mypypa', [path.join(DATADIR, 'MyPyPa-0.1.0-py2.5.zip')]) self.assertEquals(mtype, modutils.ZIPFILE) self.assertEquals(mfile, '') - + def test_find_egg_module(self): mtype, mfile = _module_file('mypypa', [path.join(DATADIR, 'MyPyPa-0.1.0-py2.5.egg')]) self.assertEquals(mtype, modutils.ZIPFILE) self.assertEquals(mfile, '') - + class load_module_from_name_tc(TestCase): """ load a python module from it's name """ - + def test_knownValues_load_module_from_name_1(self): self.assertEqual(modutils.load_module_from_name('sys'), sys) def test_knownValues_load_module_from_name_2(self): self.assertEqual(modutils.load_module_from_name('os.path'), path) - + def test_raise_load_module_from_name_1(self): - self.assertRaises(ImportError, - modutils.load_module_from_name, 'os.path', use_sys=0) + self.assertRaises(ImportError, + modutils.load_module_from_name, 'os.path', use_sys=0) class get_module_part_tc(TestCase): """given a dotted name return the module part of the name""" - + def test_knownValues_get_module_part_1(self): self.assertEqual(modutils.get_module_part('logilab.common.modutils'), 'logilab.common.modutils') @@ -81,27 +81,32 @@ class get_module_part_tc(TestCase): def test_knownValues_get_module_part_2(self): self.assertEqual(modutils.get_module_part('logilab.common.modutils.get_module_part'), 'logilab.common.modutils') - + def test_knownValues_get_module_part_3(self): self.assertEqual(modutils.get_module_part('db.get_connexion', modutils.__file__), 'db') - + def test_knownValues_get_compiled_module_part(self): self.assertEqual(modutils.get_module_part('math.log10'), 'math') self.assertEqual(modutils.get_module_part('math.log10', __file__), 'math') - + def test_knownValues_get_builtin_module_part(self): self.assertEqual(modutils.get_module_part('sys.path'), 'sys') self.assertEqual(modutils.get_module_part('sys.path', '__file__'), 'sys') - + class modpath_from_file_tc(TestCase): """ given an absolute file path return the python module's path as a list """ - + def test_knownValues_modpath_from_file_1(self): self.assertEqual(modutils.modpath_from_file(modutils.__file__), ['logilab', 'common', 'modutils']) - + + def test_knownValues_modpath_from_file_2(self): + self.assertEqual(modutils.modpath_from_file('unittest_modutils.py', + {getcwd(): 'arbitrary.pkg'}), + ['arbitrary', 'pkg', 'unittest_modutils']) + def test_raise_modpath_from_file_Exception(self): self.assertRaises(Exception, modutils.modpath_from_file, '/turlututu') @@ -110,16 +115,16 @@ class file_from_modpath_tc(TestCase): """given a mod path (i.e. splited module / package name), return the corresponding file, giving priority to source file over precompiled file if it exists""" - + def test_knownValues_file_from_modpath_1(self): self.assertEqual(path.realpath(modutils.file_from_modpath(['logilab', 'common', 'modutils'])), path.realpath(modutils.__file__.replace('.pyc', '.py'))) - + def test_knownValues_file_from_modpath_2(self): from os import path self.assertEqual(path.realpath(modutils.file_from_modpath(['os', 'path']).replace('.pyc', '.py')), path.realpath(path.__file__.replace('.pyc', '.py'))) - + def test_knownValues_file_from_modpath_3(self): try: # don't fail if pyxml isn't installed @@ -129,36 +134,36 @@ class file_from_modpath_tc(TestCase): else: self.assertEqual(path.realpath(modutils.file_from_modpath(['xml', 'dom', 'ext']).replace('.pyc', '.py')), path.realpath(ext.__file__.replace('.pyc', '.py'))) - + def test_knownValues_file_from_modpath_4(self): self.assertEqual(modutils.file_from_modpath(['sys']), None) - + def test_raise_file_from_modpath_Exception(self): self.assertRaises(ImportError, modutils.file_from_modpath, ['turlututu']) class get_source_file_tc(TestCase): - + def test(self): from os import path self.assertEqual(modutils.get_source_file(path.__file__), path.__file__.replace('.pyc', '.py')) - + def test_raise(self): self.assertRaises(modutils.NoSourceFile, modutils.get_source_file,'whatever') - + class is_standard_module_tc(TestCase): """ return true if the module may be considered as a module from the standard library """ - + def test_knownValues_is_standard_module_0(self): self.assertEqual(modutils.is_standard_module('__builtin__'), True) - + def test_knownValues_is_standard_module_1(self): self.assertEqual(modutils.is_standard_module('sys'), True) - + def test_knownValues_is_standard_module_2(self): self.assertEqual(modutils.is_standard_module('logilab'), False) @@ -172,22 +177,22 @@ class is_standard_module_tc(TestCase): self.assertEqual(modutils.is_standard_module('data.module', (DATADIR,)), True) self.assertEqual(modutils.is_standard_module('data.module', (path.abspath(DATADIR),)), True) - + class is_relative_tc(TestCase): - + def test_knownValues_is_relative_1(self): self.assertEqual(modutils.is_relative('modutils', common.__path__[0]), True) def test_knownValues_is_relative_2(self): self.assertEqual(modutils.is_relative('modutils', tree.__file__), True) - + def test_knownValues_is_relative_3(self): self.assertEqual(modutils.is_relative('logilab.common.modutils', common.__path__[0]), False) - + class get_modules_tc(TestCase): - + def test_knownValues_get_modules_1(self): # XXXFIXME: TOWRITE """given a directory return a list of all available python modules, even in subdirectories @@ -202,7 +207,7 @@ class get_modules_tc(TestCase): class get_modules_files_tc(TestCase): - + def test_knownValues_get_module_files_1(self): # XXXFIXME: TOWRITE """given a directory return a list of all available python module's files, even in subdirectories @@ -222,11 +227,11 @@ class get_modules_files_tc(TestCase): self.assert_( hasattr(logilab, 'common') ) self.assert_( hasattr(logilab.common, 'fileutils') ) self.assert_( m is logilab.common.fileutils ) - + from logilab.common.testlib import DocTest class ModuleDocTest(DocTest): """test doc test in this module""" - from logilab.common import modutils as module + from logilab.common import modutils as module del DocTest # necessary if we don't want it to be executed (we don't...) |