diff options
-rw-r--r-- | Doc/library/test.rst | 7 | ||||
-rw-r--r-- | Lib/test/support/__init__.py | 18 | ||||
-rw-r--r-- | Lib/test/test_compile.py | 10 | ||||
-rw-r--r-- | Lib/test/test_genericpath.py | 12 | ||||
-rw-r--r-- | Lib/test/test_io.py | 25 | ||||
-rw-r--r-- | Lib/test/test_ntpath.py | 15 | ||||
-rw-r--r-- | Lib/test/test_os.py | 44 | ||||
-rw-r--r-- | Lib/test/test_pathlib.py | 9 | ||||
-rw-r--r-- | Lib/test/test_posixpath.py | 14 | ||||
-rw-r--r-- | Lib/test/test_shutil.py | 11 | ||||
-rw-r--r-- | Lib/test/test_subprocess.py | 8 |
11 files changed, 70 insertions, 103 deletions
diff --git a/Doc/library/test.rst b/Doc/library/test.rst index a366fe2..6041f52 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -1293,6 +1293,13 @@ The :mod:`test.support` module defines the following classes: Class for logging support. +.. class:: FakePath(path) + + Simple :term:`path-like object`. It implements the :meth:`__fspath__` + method which just returns the *path* argument. If *path* is an exception, + it will be raised in :meth:`!__fspath__`. + + :mod:`test.support.script_helper` --- Utilities for the Python execution tests ============================================================================== diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index b4269f4..2c2f888 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2840,3 +2840,21 @@ class SaveSignals: def with_pymalloc(): import _testcapi return _testcapi.WITH_PYMALLOC + + +class FakePath: + """Simple implementing of the path protocol. + """ + def __init__(self, path): + self.path = path + + def __repr__(self): + return f'<FakePath {self.path!r}>' + + def __fspath__(self): + if (isinstance(self.path, BaseException) or + isinstance(self.path, type) and + issubclass(self.path, BaseException)): + raise self.path + else: + return self.path diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 4617a12..acebdbd 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -6,7 +6,7 @@ import _ast import tempfile import types from test import support -from test.support import script_helper +from test.support import script_helper, FakePath class TestSpecifics(unittest.TestCase): @@ -663,13 +663,7 @@ if 1: def test_path_like_objects(self): # An implicit test for PyUnicode_FSDecoder(). - class PathLike: - def __init__(self, path): - self._path = path - def __fspath__(self): - return self._path - - compile("42", PathLike("test_compile_pathlike"), "single") + compile("42", FakePath("test_compile_pathlike"), "single") def test_stack_overflow(self): # bpo-31113: Stack overflow when compile a long sequence of diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index ad5a59c..9ed5390 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -9,6 +9,7 @@ import unittest import warnings from test import support from test.support.script_helper import assert_python_ok +from test.support import FakePath def create_file(filename, data=b'foo'): @@ -493,18 +494,9 @@ class CommonTest(GenericTest): class PathLikeTests(unittest.TestCase): - class PathLike: - def __init__(self, path=''): - self.path = path - def __fspath__(self): - if isinstance(self.path, BaseException): - raise self.path - else: - return self.path - def setUp(self): self.file_name = support.TESTFN.lower() - self.file_path = self.PathLike(support.TESTFN) + self.file_path = FakePath(support.TESTFN) self.addCleanup(support.unlink, self.file_name) create_file(self.file_name, b"test_genericpath.PathLikeTests") diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 4be5631..343c5a4 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -37,6 +37,7 @@ from collections import deque, UserList from itertools import cycle, count from test import support from test.support.script_helper import assert_python_ok, run_python_until_end +from test.support import FakePath import codecs import io # C implementation of io @@ -891,13 +892,6 @@ class IOTest(unittest.TestCase): self.assertEqual(bytes(buffer), b"12345") def test_fspath_support(self): - class PathLike: - def __init__(self, path): - self.path = path - - def __fspath__(self): - return self.path - def check_path_succeeds(path): with self.open(path, "w") as f: f.write("egg\n") @@ -905,16 +899,25 @@ class IOTest(unittest.TestCase): with self.open(path, "r") as f: self.assertEqual(f.read(), "egg\n") - check_path_succeeds(PathLike(support.TESTFN)) - check_path_succeeds(PathLike(support.TESTFN.encode('utf-8'))) + check_path_succeeds(FakePath(support.TESTFN)) + check_path_succeeds(FakePath(support.TESTFN.encode('utf-8'))) + + with self.open(support.TESTFN, "w") as f: + bad_path = FakePath(f.fileno()) + with self.assertRaises(TypeError): + self.open(bad_path, 'w') - bad_path = PathLike(TypeError) + bad_path = FakePath(None) with self.assertRaises(TypeError): self.open(bad_path, 'w') + bad_path = FakePath(FloatingPointError) + with self.assertRaises(FloatingPointError): + self.open(bad_path, 'w') + # ensure that refcounting is correct with some error conditions with self.assertRaisesRegex(ValueError, 'read/write/append mode'): - self.open(PathLike(support.TESTFN), 'rwxa') + self.open(FakePath(support.TESTFN), 'rwxa') def test_RawIOBase_readall(self): # Exercise the default unlimited RawIOBase.read() and readall() diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 1eec26b..2d48be8 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -3,7 +3,7 @@ import os import sys import unittest import warnings -from test.support import TestFailed +from test.support import TestFailed, FakePath from test import support, test_genericpath from tempfile import TemporaryFile @@ -459,18 +459,9 @@ class PathLikeTests(unittest.TestCase): path = ntpath - class PathLike: - def __init__(self, path=''): - self.path = path - def __fspath__(self): - if isinstance(self.path, BaseException): - raise self.path - else: - return self.path - def setUp(self): self.file_name = support.TESTFN.lower() - self.file_path = self.PathLike(support.TESTFN) + self.file_path = FakePath(support.TESTFN) self.addCleanup(support.unlink, self.file_name) with open(self.file_name, 'xb', 0) as file: file.write(b"test_ntpath.PathLikeTests") @@ -485,7 +476,7 @@ class PathLikeTests(unittest.TestCase): self.assertPathEqual(self.path.isabs) def test_path_join(self): - self.assertEqual(self.path.join('a', self.PathLike('b'), 'c'), + self.assertEqual(self.path.join('a', FakePath('b'), 'c'), self.path.join('a', 'b', 'c')) def test_path_split(self): diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 77e4a00..4f8a2a7 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -61,7 +61,7 @@ except ImportError: INT_MAX = PY_SSIZE_T_MAX = sys.maxsize from test.support.script_helper import assert_python_ok -from test.support import unix_shell +from test.support import unix_shell, FakePath root_in_posix = False @@ -85,21 +85,6 @@ def requires_os_func(name): return unittest.skipUnless(hasattr(os, name), 'requires os.%s' % name) -class _PathLike(os.PathLike): - - def __init__(self, path=""): - self.path = path - - def __str__(self): - return str(self.path) - - def __fspath__(self): - if isinstance(self.path, BaseException): - raise self.path - else: - return self.path - - def create_file(filename, content=b'content'): with open(filename, "xb", 0) as fp: fp.write(content) @@ -942,15 +927,14 @@ class WalkTests(unittest.TestCase): dirs.remove('SUB1') self.assertEqual(len(all), 2) - self.assertEqual(all[0], - (str(walk_path), ["SUB2"], ["tmp1"])) + self.assertEqual(all[0], (self.walk_path, ["SUB2"], ["tmp1"])) all[1][-1].sort() all[1][1].sort() self.assertEqual(all[1], self.sub2_tree) def test_file_like_path(self): - self.test_walk_prune(_PathLike(self.walk_path)) + self.test_walk_prune(FakePath(self.walk_path)) def test_walk_bottom_up(self): # Walk bottom-up. @@ -2288,7 +2272,7 @@ class PidTests(unittest.TestCase): def test_waitpid(self): args = [sys.executable, '-c', 'pass'] # Add an implicit test for PyUnicode_FSConverter(). - pid = os.spawnv(os.P_NOWAIT, _PathLike(args[0]), args) + pid = os.spawnv(os.P_NOWAIT, FakePath(args[0]), args) status = os.waitpid(pid, 0) self.assertEqual(status, (pid, 0)) @@ -3129,13 +3113,13 @@ class PathTConverterTests(unittest.TestCase): bytes_fspath = bytes_filename = None else: bytes_filename = support.TESTFN.encode('ascii') - bytes_fspath = _PathLike(bytes_filename) - fd = os.open(_PathLike(str_filename), os.O_WRONLY|os.O_CREAT) + bytes_fspath = FakePath(bytes_filename) + fd = os.open(FakePath(str_filename), os.O_WRONLY|os.O_CREAT) self.addCleanup(support.unlink, support.TESTFN) self.addCleanup(os.close, fd) - int_fspath = _PathLike(fd) - str_fspath = _PathLike(str_filename) + int_fspath = FakePath(fd) + str_fspath = FakePath(str_filename) for name, allow_fd, extra_args, cleanup_fn in self.functions: with self.subTest(name=name): @@ -3540,16 +3524,16 @@ class TestPEP519(unittest.TestCase): def test_fsencode_fsdecode(self): for p in "path/like/object", b"path/like/object": - pathlike = _PathLike(p) + pathlike = FakePath(p) self.assertEqual(p, self.fspath(pathlike)) self.assertEqual(b"path/like/object", os.fsencode(pathlike)) self.assertEqual("path/like/object", os.fsdecode(pathlike)) def test_pathlike(self): - self.assertEqual('#feelthegil', self.fspath(_PathLike('#feelthegil'))) - self.assertTrue(issubclass(_PathLike, os.PathLike)) - self.assertTrue(isinstance(_PathLike(), os.PathLike)) + self.assertEqual('#feelthegil', self.fspath(FakePath('#feelthegil'))) + self.assertTrue(issubclass(FakePath, os.PathLike)) + self.assertTrue(isinstance(FakePath('x'), os.PathLike)) def test_garbage_in_exception_out(self): vapor = type('blah', (), {}) @@ -3561,14 +3545,14 @@ class TestPEP519(unittest.TestCase): def test_bad_pathlike(self): # __fspath__ returns a value other than str or bytes. - self.assertRaises(TypeError, self.fspath, _PathLike(42)) + self.assertRaises(TypeError, self.fspath, FakePath(42)) # __fspath__ attribute that is not callable. c = type('foo', (), {}) c.__fspath__ = 1 self.assertRaises(TypeError, self.fspath, c()) # __fspath__ raises an exception. self.assertRaises(ZeroDivisionError, self.fspath, - _PathLike(ZeroDivisionError())) + FakePath(ZeroDivisionError())) class TimesTests(unittest.TestCase): diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index e56e0d2..5321555 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -11,7 +11,7 @@ import unittest from unittest import mock from test import support -TESTFN = support.TESTFN +from test.support import TESTFN, FakePath try: import grp, pwd @@ -191,18 +191,15 @@ class _BasePurePathTest(object): P = self.cls p = P('a') self.assertIsInstance(p, P) - class PathLike: - def __fspath__(self): - return "a/b/c" P('a', 'b', 'c') P('/a', 'b', 'c') P('a/b/c') P('/a/b/c') - P(PathLike()) + P(FakePath("a/b/c")) self.assertEqual(P(P('a')), P('a')) self.assertEqual(P(P('a'), 'b'), P('a/b')) self.assertEqual(P(P('a'), P('b')), P('a/b')) - self.assertEqual(P(P('a'), P('b'), P('c')), P(PathLike())) + self.assertEqual(P(P('a'), P('b'), P('c')), P(FakePath("a/b/c"))) def _check_str_subclass(self, *args): # Issue #21127: it should be possible to construct a PurePath object diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index 8a1e33b..96b267c 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -4,6 +4,7 @@ import unittest import warnings from posixpath import realpath, abspath, dirname, basename from test import support, test_genericpath +from test.support import FakePath try: import posix @@ -600,18 +601,9 @@ class PathLikeTests(unittest.TestCase): path = posixpath - class PathLike: - def __init__(self, path=''): - self.path = path - def __fspath__(self): - if isinstance(self.path, BaseException): - raise self.path - else: - return self.path - def setUp(self): self.file_name = support.TESTFN.lower() - self.file_path = self.PathLike(support.TESTFN) + self.file_path = FakePath(support.TESTFN) self.addCleanup(support.unlink, self.file_name) with open(self.file_name, 'xb', 0) as file: file.write(b"test_posixpath.PathLikeTests") @@ -626,7 +618,7 @@ class PathLikeTests(unittest.TestCase): self.assertPathEqual(self.path.isabs) def test_path_join(self): - self.assertEqual(self.path.join('a', self.PathLike('b'), 'c'), + self.assertEqual(self.path.join('a', FakePath('b'), 'c'), self.path.join('a', 'b', 'c')) def test_path_split(self): diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index f3cf43e..2cb2f14 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -22,7 +22,7 @@ import tarfile import zipfile from test import support -from test.support import TESTFN +from test.support import TESTFN, FakePath TESTFN2 = TESTFN + "2" @@ -1232,14 +1232,7 @@ class TestShutil(unittest.TestCase): def check_unpack_archive(self, format): self.check_unpack_archive_with_converter(format, lambda path: path) self.check_unpack_archive_with_converter(format, pathlib.Path) - - class MyPath: - def __init__(self, path): - self.path = path - def __fspath__(self): - return self.path - - self.check_unpack_archive_with_converter(format, MyPath) + self.check_unpack_archive_with_converter(format, FakePath) def check_unpack_archive_with_converter(self, format, converter): root_dir, base_dir = self._create_files() diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 46cb5f1..ddee3b9 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -17,6 +17,7 @@ import shutil import threading import gc import textwrap +from test.support import FakePath try: import ctypes @@ -359,12 +360,7 @@ class ProcessTestCase(BaseTestCase): def test_cwd_with_pathlike(self): temp_dir = tempfile.gettempdir() temp_dir = self._normalize_cwd(temp_dir) - - class _PathLikeObj: - def __fspath__(self): - return temp_dir - - self._assert_cwd(temp_dir, sys.executable, cwd=_PathLikeObj()) + self._assert_cwd(temp_dir, sys.executable, cwd=FakePath(temp_dir)) @unittest.skipIf(mswindows, "pending resolution of issue #15533") def test_cwd_with_relative_arg(self): |