[pypy-commit] pypy py3.7: merge py3.6

cfbolz pypy.commits at gmail.com
Mon Feb 3 12:00:09 EST 2020


Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: py3.7
Changeset: r98646:db4cbac378ec
Date: 2020-02-03 14:01 +0100
http://bitbucket.org/pypy/pypy/changeset/db4cbac378ec/

Log:	merge py3.6

diff --git a/extra_tests/test_posix.py b/extra_tests/test_posix.py
new file mode 100644
--- /dev/null
+++ b/extra_tests/test_posix.py
@@ -0,0 +1,39 @@
+# Tests variant functions which also accept file descriptors,
+# dir_fd and follow_symlinks.
+def test_have_functions():
+    import os
+    assert os.stat in os.supports_fd  # fstat() is supported everywhere
+    if os.name != 'nt':
+        assert os.chdir in os.supports_fd  # fchdir()
+    else:
+        assert os.chdir not in os.supports_fd
+    if os.name == 'posix':
+        assert os.open in os.supports_dir_fd  # openat()
+
+def test_popen():
+    import os
+    for i in range(5):
+        stream = os.popen('echo 1')
+        res = stream.read()
+        assert res == '1\n'
+        assert stream.close() is None
+
+def test_popen_with():
+    import os
+    stream = os.popen('echo 1')
+    with stream as fp:
+        res = fp.read()
+        assert res == '1\n'
+
+def test_pickle():
+    import pickle
+    import os
+    st = os.stat('.')
+    # print(type(st).__module__)
+    s = pickle.dumps(st)
+    # print(repr(s))
+    new = pickle.loads(s)
+    assert new == st
+    assert type(new) is type(st)
+
+
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -649,6 +649,7 @@
         w_errno = space.w_None
         w_winerror = space.newint(winerror)
         w_msg = space.newtext(msg, lgt)
+        w_exc = space.w_WindowsError
     else:
         errno = e.errno
         if errno == EINTR:
diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py
--- a/pypy/module/_io/interp_textio.py
+++ b/pypy/module/_io/interp_textio.py
@@ -8,12 +8,14 @@
     interp_attrproperty_w)
 from pypy.module._codecs import interp_codecs
 from pypy.module._io.interp_iobase import W_IOBase, convert_size, trap_eintr
+from pypy.module.posix.interp_posix import device_encoding
 from rpython.rlib.rarithmetic import intmask, r_uint, r_ulonglong
 from rpython.rlib.rbigint import rbigint
 from rpython.rlib.rstring import StringBuilder
 from rpython.rlib.rutf8 import (check_utf8, next_codepoint_pos,
                                 codepoints_in_utf8, codepoints_in_utf8,
                                 Utf8StringBuilder)
+from rpython.rlib import rlocale
 
 
 STATE_ZERO, STATE_OK, STATE_DETACHED = range(3)
@@ -235,7 +237,7 @@
     if encoding is not None:
         return space.newtext(encoding)
 
-    # Try os.device_encoding(fileno)
+    # Try os.device_encoding(fileno) which is interp_posix.device_encoding
     try:
         w_fileno = space.call_method(w_buffer, 'fileno')
     except OperationError as e:
@@ -244,11 +246,22 @@
                 e.match(space, space.fromcache(Cache).w_unsupportedoperation)):
             raise
     else:
-        w_os = space.call_method(space.builtin, '__import__', space.newtext('os'))
-        w_encoding = space.call_method(w_os, 'device_encoding', w_fileno)
+        w_encoding = device_encoding(space, space.int_w(w_fileno))
         if space.isinstance_w(w_encoding, space.w_unicode):
             return w_encoding
 
+    # Try to shortcut the app-level call if locale.CODESET works
+    if _WINDOWS:
+        return space.newtext(rlocale.getdefaultlocale()[1])
+    else:
+        if rlocale.HAVE_LANGINFO:
+            codeset = rlocale.nl_langinfo(rlocale.CODESET)
+            if codeset:
+                return space.newtext(codeset)
+
+    
+    # On legacy systems or darwin, try app-level 
+    # _bootlocale.getprefferedencoding(False)
     try:
         w_locale = space.call_method(space.builtin, '__import__',
                                      space.newtext('_bootlocale'))
diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -140,6 +140,12 @@
         self.as_unicode = unicode
         self.w_path = w_path
 
+    def __repr__(self):
+        # For debugging
+        return ''.join(['Path(', str(self.as_fd), ', ', str(self.as_bytes),
+                        ', ', str(self.as_unicode), ', [', str(self.w_path),
+                        ', ', str(getattr(self.w_path, '_length', 'bytes')), '])'])
+
 @specialize.arg(2)
 def _unwrap_path(space, w_value, allow_fd=True):
     # equivalent of posixmodule.c:path_converter() in CPython
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
@@ -16,7 +16,7 @@
 if os.name != 'nt':
     USEMODULES += ['fcntl', 'select', '_posixsubprocess', '_socket']
 else:
-    USEMODULES += ['_rawffi', 'thread', 'signal', '_cffi_backend']
+    USEMODULES += ['_rawffi', 'thread', '_cffi_backend']
 
 def setup_module(mod):
     mod.space = gettestobjspace(usemodules=USEMODULES)
@@ -65,7 +65,6 @@
         space = cls.space
         cls.w_runappdirect = space.wrap(cls.runappdirect)
         cls.w_posix = space.appexec([], GET_POSIX)
-        cls.w_os = space.appexec([], "(): import os as m ; return m")
         cls.w_path = space.wrap(str(path))
         cls.w_path2 = space.wrap(str(path2))
         cls.w_path3 = space.wrap(str(path3))
@@ -100,6 +99,7 @@
             cls.w_expected_major_12345 = space.wrap(os.major(12345))
             cls.w_expected_minor_12345 = space.wrap(os.minor(12345))
         cls.w_udir = space.wrap(str(udir))
+        cls.w_env_path = space.wrap(os.environ['PATH'])
         cls.w_Path = space.appexec([], """():
             class Path:
                 def __init__(self, _path):
@@ -240,16 +240,6 @@
             ]:
                 assert hasattr(st, field)
 
-    def test_pickle(self):
-        import pickle, os
-        st = self.posix.stat(os.curdir)
-        # print(type(st).__module__)
-        s = pickle.dumps(st)
-        # print(repr(s))
-        new = pickle.loads(s)
-        assert new == st
-        assert type(new) is type(st)
-
     def test_open_exception(self):
         posix = self.posix
         try:
@@ -326,15 +316,27 @@
             ex(self.posix.dup, UNUSEDFD)
 
     def test_getcwd(self):
-        os, posix = self.os, self.posix
+        posix = self.posix
+        import sys
+
+        # avoid importing stdlib os, copy fsencode instead
+        def fsencode(filename):
+            encoding = sys.getfilesystemencoding()
+            errors = sys.getfilesystemencodeerrors()
+            filename = posix.fspath(filename)  # Does type-checking of `filename`.
+            if isinstance(filename, str):
+                return filename.encode(encoding, errors)
+            else:
+                return filename
+
         assert isinstance(posix.getcwd(), str)
         cwdb = posix.getcwdb()
-        os.chdir(self.esurrogate_dir)
+        posix.chdir(self.esurrogate_dir)
         try:
             cwd = posix.getcwd()
-            assert os.fsencode(cwd) == posix.getcwdb()
+            assert fsencode(cwd) == posix.getcwdb()
         finally:
-            os.chdir(cwdb)
+            posix.chdir(cwdb)
 
     def test_getcwdb(self):
         assert isinstance(self.posix.getcwdb(), bytes)
@@ -363,13 +365,27 @@
         assert expected in result
 
     def test_listdir_memoryview_returns_unicode(self):
+        import sys
         # XXX unknown why CPython has this behaviour
+
+        # avoid importing stdlib os, copy fsencode instead
+        def fsencode(filename):
+            encoding = sys.getfilesystemencoding()
+            errors = sys.getfilesystemencodeerrors()
+            filename = posix.fspath(filename)  # Does type-checking of `filename`.
+            if isinstance(filename, str):
+                return filename.encode(encoding, errors)
+            else:
+                return filename
+
+
         bytes_dir = self.bytes_dir
-        os, posix = self.os, self.posix
+        posix = self.posix
         result1 = posix.listdir(bytes_dir)              # -> list of bytes
         result2 = posix.listdir(memoryview(bytes_dir))  # -> list of unicodes
-        assert [os.fsencode(x) for x in result2] == result1
+        assert [fsencode(x) for x in result2] == result1
 
+    @py.test.mark.skipif("sys.platform == 'win32'")
     def test_fdlistdir(self):
         posix = self.posix
         dirfd = posix.open('.', posix.O_RDONLY)
@@ -568,42 +584,24 @@
     if hasattr(__import__(os.name), "spawnv"):
         def test_spawnv(self):
             os = self.posix
+            P_WAIT = 0
             import sys
             print(self.python)
-            ret = os.spawnv(os.P_WAIT, self.python,
+            ret = os.spawnv(P_WAIT, self.python,
                             ['python', '-c', 'raise(SystemExit(42))'])
             assert ret == 42
 
     if hasattr(__import__(os.name), "spawnve"):
         def test_spawnve(self):
             os = self.posix
-            env = {'PATH':os.environ['PATH'], 'FOOBAR': '42'}
-            ret = os.spawnve(os.P_WAIT, self.python,
+            P_WAIT = 0
+            env = {'PATH':self.env_path, 'FOOBAR': '42'}
+            ret = os.spawnve(P_WAIT, self.python,
                              ['python', '-c',
                               "raise(SystemExit(int(__import__('os').environ['FOOBAR'])))"],
                              env)
             assert ret == 42
 
-    def test_popen(self):
-        os = self.os
-        for i in range(5):
-            stream = os.popen('echo 1')
-            res = stream.read()
-            assert res == '1\n'
-            assert stream.close() is None
-
-    def test_popen_with(self):
-        os = self.os
-        stream = os.popen('echo 1')
-        with stream as fp:
-            res = fp.read()
-            assert res == '1\n'
-
-    if sys.platform == "win32":
-        # using startfile in app_startfile creates global state
-        test_popen.dont_track_allocations = True
-        test_popen_with.dont_track_allocations = True
-
     if hasattr(__import__(os.name), '_getfullpathname'):
         def test__getfullpathname(self):
             # nt specific
@@ -936,11 +934,11 @@
 
     if hasattr(rposix, 'posix_fallocate'):
         def test_os_posix_posix_fallocate(self):
-            posix, os = self.posix, self.os
+            os = self.posix
             import errno
             fd = os.open(self.path2 + 'test_os_posix_fallocate', os.O_WRONLY | os.O_CREAT)
             try:
-                ret = posix.posix_fallocate(fd, 0, 10)
+                ret = os.posix_fallocate(fd, 0, 10)
                 if ret == errno.EINVAL and not self.runappdirect:
                     # Does not work untranslated on a 32-bit chroot/docker
                     pass
@@ -975,7 +973,7 @@
 
     if hasattr(rposix, 'getpriority'):
         def test_os_set_get_priority(self):
-            posix, os = self.posix, self.os
+            posix = os = self.posix
             childpid = os.fork()
             if childpid == 0:
                 # in the child (avoids changing the priority of the parent
@@ -1001,7 +999,7 @@
     if hasattr(rposix, 'sched_get_priority_max'):
         def test_os_sched_get_priority_max(self):
             import sys
-            posix, os = self.posix, self.os
+            posix = self.posix
             assert posix.sched_get_priority_max(posix.SCHED_FIFO) != -1
             assert posix.sched_get_priority_max(posix.SCHED_RR) != -1
             assert posix.sched_get_priority_max(posix.SCHED_OTHER) != -1
@@ -1011,7 +1009,7 @@
     if hasattr(rposix, 'sched_get_priority_min'):
         def test_os_sched_get_priority_min(self):
             import sys
-            posix, os = self.posix, self.os
+            posix = self.posix
             assert posix.sched_get_priority_min(posix.SCHED_FIFO) != -1
             assert posix.sched_get_priority_min(posix.SCHED_RR) != -1
             assert posix.sched_get_priority_min(posix.SCHED_OTHER) != -1
@@ -1020,7 +1018,7 @@
 
     if hasattr(rposix, 'sched_get_priority_min'):
         def test_os_sched_priority_max_greater_than_min(self):
-            posix, os = self.posix, self.os
+            posix = self.posix
             policy = posix.SCHED_RR
             low = posix.sched_get_priority_min(policy)
             high = posix.sched_get_priority_max(policy)
@@ -1301,9 +1299,10 @@
         assert hasattr(os, 'kill')
 
     def test_pipe_flush(self):
+        import io
         ffd, gfd = self.posix.pipe()
-        f = self.os.fdopen(ffd, 'r')
-        g = self.os.fdopen(gfd, 'w')
+        f = io.open(ffd, 'r')
+        g = io.open(gfd, 'w')
         g.write('he')
         g.flush()
         x = f.read(1)
@@ -1424,7 +1423,7 @@
             s1.close()
 
         def test_os_lockf(self):
-            posix, os = self.posix, self.os
+            posix = os = self.posix
             fd = os.open(self.path2 + 'test_os_lockf', os.O_WRONLY | os.O_CREAT)
             try:
                 os.write(fd, b'test')
@@ -1502,21 +1501,21 @@
 
     if os.name == 'nt':
         def test__getfileinformation(self):
-            import os
-            path = os.path.join(self.pdir, 'file1')
+            os = self.posix
+            path = '\\'.join([self.pdir, 'file1'])
             with open(path) as fp:
                 info = self.posix._getfileinformation(fp.fileno())
             assert len(info) == 3
             assert all(isinstance(obj, int) for obj in info)
 
         def test__getfinalpathname(self):
-            import os
-            path = os.path.join(self.pdir, 'file1')
+            os = self.posix
+            path = '\\'.join([self.pdir, 'file1'])
             try:
                 result = self.posix._getfinalpathname(path)
             except NotImplementedError:
                 skip("_getfinalpathname not supported on this platform")
-            assert os.path.exists(result)
+            assert os.stat(result) is not None
 
     @py.test.mark.skipif("sys.platform == 'win32'")
     def test_rtld_constants(self):
@@ -1603,16 +1602,16 @@
 
 class AppTestEnvironment(object):
     def setup_class(cls):
+        cls.w_posix = space.appexec([], GET_POSIX)
         cls.w_path = space.wrap(str(path))
 
     def test_environ(self):
-        import sys, os
-        environ = os.environ
+        environ = self.posix.environ
         if not environ:
             skip('environ not filled in for untranslated tests')
         for k, v in environ.items():
-            assert type(k) is str
-            assert type(v) is str
+            assert type(k) is bytes
+            assert type(v) is bytes
         name = next(iter(environ))
         assert environ[name] is not None
         del environ[name]
@@ -1620,7 +1619,8 @@
 
     @py.test.mark.dont_track_allocations('putenv intentionally keeps strings alive')
     def test_environ_nonascii(self):
-        import sys, os
+        import sys
+        os = self.posix
         name, value = 'PYPY_TEST_日本', 'foobar日本'
         if not sys.platform == 'win32':
             fsencoding = sys.getfilesystemencoding()
@@ -1633,10 +1633,8 @@
 
         os.environ[name] = value
         assert os.environ[name] == value
-        assert os.getenv(name) == value
         del os.environ[name]
         assert os.environ.get(name) is None
-        assert os.getenv(name) is None
 
     if hasattr(__import__(os.name), "unsetenv"):
         def test_unsetenv_nonexisting(self):
@@ -1669,17 +1667,19 @@
 
 @py.test.mark.usefixtures('check_fsencoding')
 class AppTestPosixUnicode:
+    def setup_class(cls):
+        cls.w_posix = space.appexec([], GET_POSIX)
+
     def test_stat_unicode(self):
         # test that passing unicode would not raise UnicodeDecodeError
-        import os
         try:
-            os.stat(u"ą")
+            self.posix.stat(u"ą")
         except OSError:
             pass
 
     def test_open_unicode(self):
+        os = self.posix
         # Ensure passing unicode doesn't raise UnicodeEncodeError
-        import os
         try:
             os.open(u"ą", os.O_WRONLY)
         except OSError:
@@ -1687,9 +1687,8 @@
 
     def test_remove_unicode(self):
         # See 2 above ;)
-        import os
         try:
-            os.remove(u"ą")
+            self.posix.remove(u"ą")
         except OSError:
             pass
 
@@ -1717,20 +1716,6 @@
         assert content == b"test"
 
 
-class AppTestFdVariants:
-    # Tests variant functions which also accept file descriptors,
-    # dir_fd and follow_symlinks.
-    def test_have_functions(self):
-        import os
-        assert os.stat in os.supports_fd  # fstat() is supported everywhere
-        if os.name != 'nt':
-            assert os.chdir in os.supports_fd  # fchdir()
-        else:
-            assert os.chdir not in os.supports_fd
-        if os.name == 'posix':
-            assert os.open in os.supports_dir_fd  # openat()
-
-
 class AppTestPep475Retry:
     spaceconfig = {'usemodules': USEMODULES}
 


More information about the pypy-commit mailing list