Author: Ronan Lamy <ronan.l...@gmail.com>
Branch: py3k
Changeset: r87362:bdd0b2244dd3
Date: 2016-09-24 18:44 +0100
http://bitbucket.org/pypy/pypy/changeset/bdd0b2244dd3/

Log:    Set up ImportError attributes properly in _imp.load_dynamic()

diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -582,3 +582,16 @@
     if module:
         space.setattr(w_exc, space.wrap("__module__"), space.wrap(module))
     return w_exc
+
+def new_import_error(space, w_msg, w_name, w_path):
+    """Create a new instance of ImportError.
+
+    The result corresponds to ImportError(msg, name=name, path=path)
+    """
+    return space.appexec(
+        [w_msg, w_name, w_path], """(msg, name, path):
+            return ImportError(msg, name=name, path=path)""")
+
+def raise_import_error(space, w_msg, w_name, w_path):
+    w_exc = new_import_error(space, w_msg, w_name, w_path)
+    raise OperationError(space.w_ImportError, w_exc)
diff --git a/pypy/interpreter/test/test_error.py 
b/pypy/interpreter/test/test_error.py
--- a/pypy/interpreter/test/test_error.py
+++ b/pypy/interpreter/test/test_error.py
@@ -3,7 +3,7 @@
 import py, os, errno
 from pypy.interpreter.error import (
     OperationError, decompose_valuefmt, get_operrcls2, new_exception_class,
-    oefmt, wrap_oserror)
+    oefmt, wrap_oserror, new_import_error)
 
 
 def test_decompose_valuefmt():
@@ -154,3 +154,8 @@
     assert operr.match(space, space.w_ValueError)
     assert operr.match(space, space.w_TypeError)
 
+def test_import_error(space):
+    w_exc = new_import_error(
+        space, space.wrap(u'msg'), space.wrap(u'name'), space.wrap(u'path'))
+    assert space.getattr(w_exc, space.wrap(u'name')).unwrap(space) == u'name'
+    assert space.getattr(w_exc, space.wrap(u'path')).unwrap(space) == u'path'
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -20,7 +20,7 @@
 from rpython.tool.udir import udir
 from rpython.translator import platform
 from pypy.module.cpyext.state import State
-from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.error import OperationError, oefmt, raise_import_error
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.gateway import unwrap_spec
 from pypy.interpreter.nestedscope import Cell
@@ -982,7 +982,7 @@
     py_fatalerror = rffi.llexternal('%s_FatalError' % prefix,
                                     [CONST_STRING], lltype.Void,
                                     compilation_info=eci)
-    _reinit_tls = rffi.llexternal('%sThread_ReInitTLS' % prefix, [], 
+    _reinit_tls = rffi.llexternal('%sThread_ReInitTLS' % prefix, [],
                                   lltype.Void, compilation_info=eci)
     def reinit_tls(space):
         _reinit_tls()
@@ -1523,9 +1523,10 @@
         finally:
             lltype.free(ll_libname, flavor='raw')
     except rdynload.DLOpenError as e:
-        raise oefmt(space.w_ImportError,
-                    "unable to load extension module '%s': %s",
-                    path, e.msg)
+        w_name = space.newunicode(name.decode('ascii'))
+        w_path = space.wrap_fsdecoded(path)
+        raise raise_import_error(space,
+            space.wrap_fsdecoded(e.msg), w_name, w_path)
     look_for = None
     #
     if space.config.objspace.usemodules._cffi_backend:
@@ -1555,9 +1556,12 @@
             look_for += ' or ' + also_look_for
         else:
             look_for = also_look_for
-    #
-    raise oefmt(space.w_ImportError,
-                "function %s not found in library %s", look_for, path)
+    w_msg = u"function %s not found in library %s" % (
+        unicode(look_for), space.unicode_w(space.wrap_fsdecoded(path)))
+    w_name = space.newunicode(name.decode('ascii'))
+    w_path = space.wrap_fsdecoded(path)
+    raise_import_error(space, w_msg, w_name, w_path)
+
 
 initfunctype = lltype.Ptr(lltype.FuncType([], PyObject))
 
diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py
--- a/pypy/module/imp/interp_imp.py
+++ b/pypy/module/imp/interp_imp.py
@@ -50,15 +50,17 @@
         fd = space.int_w(space.call_method(w_iobase, 'fileno'))
         return streamio.fdopen_as_stream(fd, filemode)
 
-@unwrap_spec(filename='fsencode')
-def load_dynamic(space, w_modulename, filename, w_file=None):
+@unwrap_spec(modulename=unicode, filename='fsencode')
+def load_dynamic(space, modulename, filename, w_file=None):
     if not importing.has_so_extension(space):
         raise oefmt(space.w_ImportError, "Not implemented")
 
     from pypy.module.cpyext.api import load_extension_module
-    load_extension_module(space, filename, space.str_w(w_modulename))
+    # extension names must be valid C identifiers
+    modulename = modulename.encode('ascii')
+    load_extension_module(space, filename, modulename.encode('ascii'))
 
-    return importing.check_sys_modules(space, w_modulename)
+    return importing.check_sys_modules_w(space, modulename)
 
 def init_builtin(space, w_name):
     name = space.str0_w(w_name)
diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py
--- a/pypy/module/imp/test/test_app.py
+++ b/pypy/module/imp/test/test_app.py
@@ -60,11 +60,13 @@
         import _imp
         excinfo = raises(ImportError, _imp.load_dynamic, 'foo', 'bar')
         assert excinfo.value.name == 'foo'
-        assert 'bar' in excinfo.value.path
+        assert excinfo.value.path == './bar'
         # Note: On CPython, the behavior changes slightly if a 3rd argument is
         # passed in, whose value is ignored. We don't implement that.
         #raises(IOError, _imp.load_dynamic, 'foo', 'bar', 42)
 
+        raises(TypeError, _imp.load_dynamic, b'foo', 'bar')
+
     def test_suffixes(self):
         import imp
         for suffix, mode, type in imp.get_suffixes():
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to