Author: Matti Picus <matti.pi...@gmail.com>
Branch: py3.5
Changeset: r93966:66f30ba67227
Date: 2018-03-09 14:58 +0200
http://bitbucket.org/pypy/pypy/changeset/66f30ba67227/

Log:    merge default into py3.5

diff --git a/lib_pypy/_pypy_testcapi.py b/lib_pypy/_pypy_testcapi.py
--- a/lib_pypy/_pypy_testcapi.py
+++ b/lib_pypy/_pypy_testcapi.py
@@ -3,7 +3,7 @@
 import importlib.machinery
 
 
-def get_hashed_dir(cfile):
+def _get_hashed_filename(cfile):
     with open(cfile,'r') as fid:
         content = fid.read()
     # from cffi's Verifier()
@@ -23,10 +23,28 @@
             username = os.environ['USERNAME']   #windows
         except KeyError:
             username = os.getuid()
-    output_dir = tempfile.gettempdir() + os.path.sep + 'tmp_%s_%s%s' % (
+    return tempfile.gettempdir() + os.path.sep + 'testcapi_%s_%s%s' % (
         username, k1, k2)
-    if not os.path.exists(output_dir):
+
+def get_hashed_dir(cfile):
+    hashed_fn = _get_hashed_filename(cfile)
+    try:
+        with open(hashed_fn) as f:
+            dirname = f.read(1024)
+    except IOError:
+        dirname = ''
+    tmpdir = tempfile.gettempdir()
+    if (not dirname or '/' in dirname or '\\' in dirname or '\x00' in dirname
+            or not os.path.isdir(os.path.join(tmpdir, dirname))):
+        dirname = binascii.hexlify(os.urandom(8))
+        if not isinstance(dirname, str):    # Python 3
+            dirname = dirname.decode('ascii')
+        dirname = 'testcapi_' + dirname
+    output_dir = os.path.join(tmpdir, dirname)
+    try:
         os.mkdir(output_dir)
+    except OSError:
+        pass
     return output_dir
 
 
@@ -35,13 +53,12 @@
     return suffixes[0] if suffixes else None
 
 
-def compile_shared(csource, modulename, output_dir=None):
+def compile_shared(csource, modulename, output_dir):
     """Compile '_testcapi.c' or '_ctypes_test.c' into an extension module,
     and import it.
     """
     thisdir = os.path.dirname(__file__)
-    if output_dir is None:
-        output_dir = tempfile.mkdtemp()
+    assert output_dir is not None
 
     from distutils.ccompiler import new_compiler
 
@@ -85,4 +102,16 @@
     # Now import the newly created library, it will replace the original
     # module in sys.modules
     fp, filename, description = imp.find_module(modulename, path=[output_dir])
-    imp.load_module(modulename, fp, filename, description)
+    with fp:
+        imp.load_module(modulename, fp, filename, description)
+
+    # If everything went fine up to now, write the name of this new
+    # directory to 'hashed_fn', for future processes (and to avoid a
+    # growing number of temporary directories that are not completely
+    # obvious to clean up on Windows)
+    hashed_fn = _get_hashed_filename(os.path.join(thisdir, csource))
+    try:
+        with open(hashed_fn, 'w') as f:
+            f.write(os.path.basename(output_dir))
+    except IOError:
+        pass
diff --git a/pypy/module/_cffi_backend/cdlopen.py 
b/pypy/module/_cffi_backend/cdlopen.py
--- a/pypy/module/_cffi_backend/cdlopen.py
+++ b/pypy/module/_cffi_backend/cdlopen.py
@@ -53,8 +53,7 @@
         self.libhandle = rffi.cast(DLLHANDLE, 0)
 
         if not libhandle:
-            raise oefmt(self.ffi.w_FFIError, "library '%s' is already closed",
-                        self.libname)
+            return
         self.may_unregister_rpython_finalizer(self.ffi.space)
 
         # Clear the dict to force further accesses to do cdlopen_fetch()
diff --git a/pypy/module/_cffi_backend/libraryobj.py 
b/pypy/module/_cffi_backend/libraryobj.py
--- a/pypy/module/_cffi_backend/libraryobj.py
+++ b/pypy/module/_cffi_backend/libraryobj.py
@@ -90,7 +90,6 @@
         w_ctype.convert_from_object(rffi.cast(rffi.CCHARP, cdata), w_value)
 
     def close_lib(self):
-        self.check_closed()
         self._finalize_()
 
 
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py 
b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -398,6 +398,7 @@
     #
     x.close_lib()
     py.test.raises(ValueError, x.load_function, BVoidP, 'sqrt')
+    x.close_lib()
 
 def test_no_len_on_nonarray():
     p = new_primitive_type("int")
diff --git a/pypy/module/_cffi_backend/test/test_re_python.py 
b/pypy/module/_cffi_backend/test/test_re_python.py
--- a/pypy/module/_cffi_backend/test/test_re_python.py
+++ b/pypy/module/_cffi_backend/test/test_re_python.py
@@ -114,12 +114,10 @@
         from re_python_pysrc import ffi
         lib = ffi.dlopen(self.extmod)
         ffi.dlclose(lib)
-        e = raises(ffi.error, ffi.dlclose, lib)
-        assert str(e.value) == (
-            "library '%s' is already closed" % (self.extmod,))
         e = raises(ffi.error, getattr, lib, 'add42')
         assert str(e.value) == (
             "library '%s' has been closed" % (self.extmod,))
+        ffi.dlclose(lib)   # does not raise
 
     def test_constant_via_lib(self):
         self.fix_path()
diff --git a/pypy/module/posix/test/test_posix2.py 
b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -1087,9 +1087,12 @@
             if sys.platform == 'win32':
                 os.chmod(my_path, 0o400)
                 assert (os.stat(my_path).st_mode & 0o600) == 0o400
+                os.chmod(self.path, 0700)
             else:
                 os.chmod(my_path, 0o200)
                 assert (os.stat(my_path).st_mode & 0o777) == 0o200
+                os.chmod(self.path, 0700)
+            os.unlink(self.path)
 
     if hasattr(os, 'fchmod'):
         def test_fchmod(self):
@@ -1100,6 +1103,7 @@
             assert (os.fstat(f.fileno()).st_mode & 0o777) == 0o200
             f.close()
             assert (os.stat(my_path).st_mode & 0o777) == 0o200
+            os.unlink(self.path)
 
     if hasattr(os, 'mkfifo'):
         def test_mkfifo(self):
@@ -1401,6 +1405,20 @@
             if len(e.value.args) > 2:
                 assert e.value.args[2] == "\\foo\\bar\\baz"
 
+    def test_rename(self):
+        os = self.posix
+        with open(self.path, "w") as f:
+            f.write("this is a rename test")
+        unicode_name = str(self.udir) + u'/test\u03be.txt'
+        os.rename(self.path, unicode_name)
+        with open(unicode_name) as f:
+            assert f.read() == 'this is a rename test'
+        os.rename(unicode_name, self.path)
+        with open(self.path) as f:
+            assert f.read() == 'this is a rename test'
+        os.unlink(self.path)
+
+        
     def test_device_encoding(self):
         import sys
         encoding = self.posix.device_encoding(sys.stdout.fileno())
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_function.py 
b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_function.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_function.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_function.py
@@ -508,9 +508,6 @@
         ffi.cdef("int foobar(void); int foobaz;")
         lib = ffi.dlopen(lib_m)
         ffi.dlclose(lib)
-        e = py.test.raises(ValueError, ffi.dlclose, lib)
-        assert str(e.value).startswith("library '")
-        assert str(e.value).endswith("' has already been closed")
         e = py.test.raises(ValueError, getattr, lib, 'foobar')
         assert str(e.value).startswith("library '")
         assert str(e.value).endswith("' has already been closed")
@@ -520,3 +517,4 @@
         e = py.test.raises(ValueError, setattr, lib, 'foobaz', 42)
         assert str(e.value).startswith("library '")
         assert str(e.value).endswith("' has already been closed")
+        ffi.dlclose(lib)    # does not raise
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py 
b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_re_python.py
@@ -120,12 +120,10 @@
         str_extmod = extmod.encode('utf-8')
     else:
         str_extmod = extmod
-    e = py.test.raises(ffi.error, ffi.dlclose, lib)
-    assert str(e.value).startswith(
-        "library '%s' is already closed" % (str_extmod,))
     e = py.test.raises(ffi.error, getattr, lib, 'add42')
     assert str(e.value) == (
         "library '%s' has been closed" % (str_extmod,))
+    ffi.dlclose(lib)   # does not raise
 
 def test_constant_via_lib():
     from re_python_pysrc import ffi
diff --git a/rpython/rlib/_os_support.py b/rpython/rlib/_os_support.py
--- a/rpython/rlib/_os_support.py
+++ b/rpython/rlib/_os_support.py
@@ -99,6 +99,13 @@
             return unicode_traits
         else:
             return string_traits
+
+    @specialize.argtype(0, 1)
+    def _preferred_traits2(path1, path2):
+        if _prefer_unicode(path1) or _prefer_unicode(path2):
+            return unicode_traits
+        else:
+            return string_traits
 else:
     @specialize.argtype(0)
     def _prefer_unicode(path):
@@ -107,3 +114,7 @@
     @specialize.argtype(0)
     def _preferred_traits(path):
         return string_traits
+
+    @specialize.argtype(0, 1)
+    def _preferred_traits2(path1, path2):
+        return string_traits
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -8,7 +8,7 @@
 from rpython.rlib import debug, jit, rstring, rthread, types
 from rpython.rlib._os_support import (
     _CYGWIN, _MACRO_ON_POSIX, UNDERSCORE_ON_WIN32, _WIN32,
-    _prefer_unicode, _preferred_traits)
+    _prefer_unicode, _preferred_traits, _preferred_traits2)
 from rpython.rlib.objectmodel import (
     specialize, enforceargs, register_replacement_for, NOT_CONSTANT)
 from rpython.rlib.rarithmetic import intmask, widen
@@ -1257,7 +1257,7 @@
         handle_posix_error('rename',
                            c_rename(_as_bytes0(path1), _as_bytes0(path2)))
     else:
-        traits = _preferred_traits(path1)
+        traits = _preferred_traits2(path1, path2)
         win32traits = make_win32_traits(traits)
         path1 = traits.as_str0(path1)
         path2 = traits.as_str0(path2)
@@ -1267,7 +1267,7 @@
 @specialize.argtype(0, 1)
 def replace(path1, path2):
     if _WIN32:
-        traits = _preferred_traits(path1)
+        traits = _preferred_traits2(path1, path2)
         win32traits = make_win32_traits(traits)
         path1 = traits.as_str0(path1)
         path2 = traits.as_str0(path2)
diff --git a/rpython/translator/platform/windows.py 
b/rpython/translator/platform/windows.py
--- a/rpython/translator/platform/windows.py
+++ b/rpython/translator/platform/windows.py
@@ -171,17 +171,17 @@
 
     def __init__(self, cc=None, x64=False, ver0=None):
         self.x64 = x64
+        patch_os_env(self.externals)
+        self.c_environ = os.environ.copy()
         if cc is None:
             msvc_compiler_environ, self.vsver = find_msvc_env(x64, ver0=ver0)
             Platform.__init__(self, 'cl.exe')
             if msvc_compiler_environ:
+                self.c_environ.update(msvc_compiler_environ)
                 if x64:
                     self.externals_branch = 'win34_%d' % self.vsver
                 else:
                     self.externals_branch = 'win32_%d' % self.vsver
-                patch_env(msvc_compiler_environ, self.externals)
-                self.c_environ = os.environ.copy()
-                self.c_environ.update(msvc_compiler_environ)
         else:
             self.cc = cc
 
@@ -543,17 +543,18 @@
 
 # These are the external libraries, created and maintained by get_externals.py
 # The buildbot runs get_externals before building
-def patch_env(env, externals = Platform.externals):
+def patch_os_env(externals = Platform.externals):
     #print 'adding %s to PATH, INCLUDE, LIB' % basepath
     binpath = externals + r'\bin'
     path = os.environ['PATH']
-    if binpath not in path.split(';'):
+    if binpath not in path:
         path = binpath + ';' + path
-    # make sure externals is in current path for tests and translating
-    os.environ['PATH'] = path
-    env['PATH'] = binpath + ';' + env.get('PATH', '')
-    env['INCLUDE'] = externals + r'\include;' + env.get('INCLUDE', '')
-    env['LIB'] = externals + r'\lib;' + env.get('LIB', '')
+        # make sure externals is in current path for tests and translating
+        os.environ['PATH'] = path
+    if externals not in os.environ.get('INCLUDE', ''):
+        os.environ['INCLUDE'] = externals + r'\include;' + 
os.environ.get('INCLUDE', '')
+    if externals not in os.environ.get('LIB', ''):
+        os.environ['LIB'] = externals + r'\lib;' + os.environ.get('LIB', '')
     return None
 
 class WinDefinition(posix.Definition):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to