diff options
| author | ?ric Araujo <merwok@netwok.org> | 2011-11-11 23:26:49 +0100 |
|---|---|---|
| committer | ?ric Araujo <merwok@netwok.org> | 2011-11-11 23:26:49 +0100 |
| commit | 4c44b4fcb3ba388d9eb8d9c4d0e5fdc43dc9e743 (patch) | |
| tree | 447f40db74fefbb7510c0e257a5e62f2bf8182b9 | |
| parent | 699d0309ff61a62add3b592365019bebeb9313fe (diff) | |
| download | disutils2-4c44b4fcb3ba388d9eb8d9c4d0e5fdc43dc9e743.tar.gz | |
Expand tests and fix bugs in util.resolve_name.
The code is still ugly, but at least it works better now. Patches to
make it easier to read are welcome, as well as support in #12915.
| -rw-r--r-- | distutils2/tests/test_util.py | 71 | ||||
| -rw-r--r-- | distutils2/util.py | 24 |
2 files changed, 60 insertions, 35 deletions
diff --git a/distutils2/tests/test_util.py b/distutils2/tests/test_util.py index 969b185..2c4b980 100644 --- a/distutils2/tests/test_util.py +++ b/distutils2/tests/test_util.py @@ -380,35 +380,48 @@ class UtilTestCase(support.EnvironRestorer, 'pkg1.pkg3.pkg6'])) def test_resolve_name(self): - self.assertIs(str, resolve_name('__builtin__.str')) - self.assertEqual( - UtilTestCase.__name__, - resolve_name("distutils2.tests.test_util.UtilTestCase").__name__) - self.assertEqual( - UtilTestCase.test_resolve_name.__name__, - resolve_name("distutils2.tests.test_util.UtilTestCase." - "test_resolve_name").__name__) - - self.assertRaises(ImportError, resolve_name, - "distutils2.tests.test_util.UtilTestCaseNot") - self.assertRaises(ImportError, resolve_name, - "distutils2.tests.test_util.UtilTestCase." - "nonexistent_attribute") - - def test_import_nested_first_time(self): - tmp_dir = self.mkdtemp() - os.makedirs(os.path.join(tmp_dir, 'a', 'b')) - self.write_file(os.path.join(tmp_dir, 'a', '__init__.py'), '') - self.write_file(os.path.join(tmp_dir, 'a', 'b', '__init__.py'), '') - self.write_file(os.path.join(tmp_dir, 'a', 'b', 'c.py'), - 'class Foo: pass') - - try: - sys.path.append(tmp_dir) - resolve_name("a.b.c.Foo") - # assert nothing raised - finally: - sys.path.remove(tmp_dir) + # test raw module name + tmpdir = self.mkdtemp() + sys.path.append(tmpdir) + self.addCleanup(sys.path.remove, tmpdir) + self.write_file((tmpdir, 'hello.py'), '') + + os.makedirs(os.path.join(tmpdir, 'a', 'b')) + self.write_file((tmpdir, 'a', '__init__.py'), '') + self.write_file((tmpdir, 'a', 'b', '__init__.py'), '') + self.write_file((tmpdir, 'a', 'b', 'c.py'), 'class Foo: pass') + self.write_file((tmpdir, 'a', 'b', 'd.py'), textwrap.dedent("""\ + class FooBar: + class Bar: + def baz(self): + pass + """)) + + # check Python, C and built-in module + self.assertEqual(resolve_name('hello').__name__, 'hello') + self.assertEqual(resolve_name('_csv').__name__, '_csv') + self.assertEqual(resolve_name('sys').__name__, 'sys') + + # test module.attr + self.assertIs(resolve_name('__builtin__.str'), str) + self.assertIsNone(resolve_name('hello.__doc__')) + self.assertEqual(resolve_name('a.b.c.Foo').__name__, 'Foo') + self.assertEqual(resolve_name('a.b.d.FooBar.Bar.baz').__name__, 'baz') + + # error if module not found + self.assertRaises(ImportError, resolve_name, 'nonexistent') + self.assertRaises(ImportError, resolve_name, 'non.existent') + self.assertRaises(ImportError, resolve_name, 'a.no') + self.assertRaises(ImportError, resolve_name, 'a.b.no') + self.assertRaises(ImportError, resolve_name, 'a.b.no.no') + self.assertRaises(ImportError, resolve_name, 'inva-lid') + + # looking up built-in names is not supported + self.assertRaises(ImportError, resolve_name, 'str') + + # error if module found but not attr + self.assertRaises(ImportError, resolve_name, 'a.b.Spam') + self.assertRaises(ImportError, resolve_name, 'a.b.c.Spam') @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher') def test_run_2to3_on_code(self): diff --git a/distutils2/util.py b/distutils2/util.py index d410d38..6771f1c 100644 --- a/distutils2/util.py +++ b/distutils2/util.py @@ -638,22 +638,35 @@ def find_packages(paths=(os.curdir,), exclude=()): def resolve_name(name): """Resolve a name like ``module.object`` to an object and return it. - Raise ImportError if the module or name is not found. + This functions supports packages and attributes without depth limitation: + ``package.package.module.class.class.function.attr`` is valid input. + However, looking up builtins is not directly supported: use + ``builtins.name``. + + Raises ImportError if importing the module fails or if one requested + attribute is not found. """ + if '.' not in name: + # shortcut + __import__(name) + return sys.modules[name] + + # FIXME clean up this code! parts = name.split('.') cursor = len(parts) module_name = parts[:cursor] + ret = '' while cursor > 0: try: ret = __import__('.'.join(module_name)) break except ImportError: - if cursor == 0: - raise cursor -= 1 module_name = parts[:cursor] - ret = '' + + if ret == '': + raise ImportError(parts[0]) for part in parts[1:]: try: @@ -1469,8 +1482,7 @@ def encode_multipart(fields, files, boundary=None): Returns (content_type: bytes, body: bytes) ready for httplib.HTTP. """ - # Taken from - # http://code.activestate.com/recipes/146306-http-client-to-post-using-multipartform-data/ + # Taken from http://code.activestate.com/recipes/146306 if boundary is None: boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' |
