From 2e9c820c9f9a5ef8facae7b4683d4dd5553f17d3 Mon Sep 17 00:00:00 2001 From: Dimitrios Semitsoglou-Tsiapos Date: Fri, 22 May 2015 14:41:15 +0200 Subject: [PATCH] Better traceback for bad imports in custom path --- tests/test_utils.py | 20 ++++++++++++++++++++ werkzeug/utils.py | 8 +------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index add8aa40c..824ee3af7 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -186,6 +186,26 @@ def test_import_string(): pytest.raises(ImportError, utils.import_string, 'cgi.XXXXXXXXXX') +def test_import_string_provides_traceback(tmpdir, monkeypatch): + monkeypatch.syspath_prepend(str(tmpdir)) + # Couple of packages + dir_a = tmpdir.mkdir('a') + dir_b = tmpdir.mkdir('b') + # Totally packages, I promise + dir_a.join('__init__.py').write('') + dir_b.join('__init__.py').write('') + # 'aa.a' that depends on 'bb.b', which in turn has a broken import + dir_a.join('aa.py').write('from b import bb') + dir_b.join('bb.py').write('from os import a_typo') + + # Do we get all the useful information in the traceback? + with pytest.raises(ImportError) as baz_exc: + utils.import_string('a.aa') + traceback = ''.join((str(line) for line in baz_exc.traceback)) + assert 'bb.py\':1' in traceback # a bit different than typical python tb + assert 'from os import a_typo' in traceback + + def test_import_string_attribute_error(tmpdir, monkeypatch): monkeypatch.syspath_prepend(str(tmpdir)) tmpdir.join('foo_test.py').write('from bar_test import value') diff --git a/werkzeug/utils.py b/werkzeug/utils.py index 935029e85..bd593108b 100644 --- a/werkzeug/utils.py +++ b/werkzeug/utils.py @@ -423,13 +423,7 @@ def import_string(import_name, silent=False): return sys.modules[import_name] module_name, obj_name = import_name.rsplit('.', 1) - try: - module = __import__(module_name, None, None, [obj_name]) - except ImportError: - # support importing modules not yet set up by the parent module - # (or package for that matter) - module = import_string(module_name) - + module = __import__(module_name, globals(), locals(), [obj_name]) try: return getattr(module, obj_name) except AttributeError as e: