Author: Carl Friedrich Bolz-Tereick <cfb...@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} _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit