[pypy-commit] pypy py3k: In python3.2, the import statement is absolute,
amauryfa
noreply at buildbot.pypy.org
Fri Jun 28 22:50:07 CEST 2013
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: py3k
Changeset: r65084:d2cb525d01f4
Date: 2013-06-28 22:18 +0200
http://bitbucket.org/pypy/pypy/changeset/d2cb525d01f4/
Log: In python3.2, the import statement is absolute, but __import__()
still tries both relative and absolute. Test and fix.
This is needed by IDLE.
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -145,6 +145,9 @@
if ctxt_package is not None:
# __package__ is set, so use it
+ if ctxt_package == '' and level < 0:
+ return None, 0
+
dot_position = _get_dot_position(ctxt_package, level - 1)
if dot_position < 0:
if len(ctxt_package) == 0:
@@ -226,9 +229,9 @@
@unwrap_spec(name='str0', level=int)
def importhook(space, name, w_globals=None,
- w_locals=None, w_fromlist=None, level=0):
+ w_locals=None, w_fromlist=None, level=-1):
modulename = name
- if not modulename and level == 0:
+ if not modulename and level < 0:
raise OperationError(
space.w_ValueError,
space.wrap("Empty module name"))
@@ -240,15 +243,31 @@
fromlist_w = None
rel_modulename = None
- if (level > 0 and
+ if (level != 0 and
w_globals is not None and
space.isinstance_w(w_globals, space.w_dict)):
rel_modulename, rel_level = _get_relative_name(space, modulename, level, w_globals)
if rel_modulename:
- w_mod = absolute_import(space, rel_modulename, rel_level,
- fromlist_w, tentative=False)
+ # if no level was set, ignore import errors, and
+ # fall back to absolute import at the end of the
+ # function.
+ if level == -1:
+ # This check is a fast path to avoid redoing the
+ # following absolute_import() in the common case
+ w_mod = check_sys_modules_w(space, rel_modulename)
+ if w_mod is not None and space.is_w(w_mod, space.w_None):
+ # if we already find space.w_None, it means that we
+ # already tried and failed and fell back to the
+ # end of this function.
+ w_mod = None
+ else:
+ w_mod = absolute_import(space, rel_modulename, rel_level,
+ fromlist_w, tentative=True)
+ else:
+ w_mod = absolute_import(space, rel_modulename, rel_level,
+ fromlist_w, tentative=False)
if w_mod is not None:
return w_mod
diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -59,6 +59,9 @@
relative_c = "from __future__ import absolute_import\nfrom .struct import inpackage",
relative_f = "from .imp import get_magic",
relative_g = "import imp; from .imp import get_magic",
+ inpackage = "inpackage = 1",
+ function_a = "g = {'__name__': 'pkg.a'}; __import__('inpackage', g); print(g)",
+ function_b = "g = {'__name__': 'not.a'}; __import__('inpackage', g); print(g)",
)
setuppkg("pkg.pkg1",
__init__ = 'from . import a',
@@ -552,6 +555,16 @@
check_absolute()
raises(ValueError, check_relative)
+ def test_import_function(self):
+ # More tests for __import__
+ import sys
+ if sys.version < '3.3':
+ from pkg import function_a
+ assert function_a.g['__package__'] == 'pkg'
+ raises(ImportError, "from pkg import function_b")
+ else:
+ raises(ImportError, "from pkg import function_a")
+
def test_universal_newlines(self):
import pkg_univnewlines
assert pkg_univnewlines.a == 5
More information about the pypy-commit
mailing list