From e42fc6c4dac70a85de3b52d7a61bd9522a094328 Mon Sep 17 00:00:00 2001 From: mrbean-bremen Date: Sat, 8 Jul 2023 12:39:47 +0200 Subject: Adapt to work with pypy 3.10 - adapt to some changed behavior - add another SKIPMODULE for pytest - add tests for more pypy versions - see #859 --- .github/workflows/testsuite.yml | 4 ++++ CHANGES.md | 2 ++ pyfakefs/fake_io.py | 3 ++- pyfakefs/fake_os.py | 5 +++-- pyfakefs/fake_pathlib.py | 9 +++++---- pyfakefs/pytest_plugin.py | 2 ++ pyfakefs/tests/fake_filesystem_shutil_test.py | 3 ++- pyfakefs/tests/fake_open_test.py | 12 +++++++++++- pyfakefs/tests/patched_packages_test.py | 5 ++++- 9 files changed, 35 insertions(+), 10 deletions(-) diff --git a/.github/workflows/testsuite.yml b/.github/workflows/testsuite.yml index 33aee2b..92e7c4d 100644 --- a/.github/workflows/testsuite.yml +++ b/.github/workflows/testsuite.yml @@ -29,6 +29,10 @@ jobs: include: - python-version: "pypy-3.7" os: ubuntu-latest + - python-version: "pypy-3.9" + os: ubuntu-latest + - python-version: "pypy-3.10" + os: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/CHANGES.md b/CHANGES.md index 4953808..15739ac 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ The released versions correspond to PyPI releases. * Adapt to changes in Python 3.12 beta1 (only working partially, see [#830](../../issues/830) and [#831](../../issues/831)). * Adapt to changes in `shutil` in Python 3.12 beta2 (see [#814](../../issues/814)). +* Fix support for newer PyPi versions (see [#859](../../issues/859)). ### Documentation * Added a note regarding the incompatibility of the built-in `sqlite3` module with @@ -18,6 +19,7 @@ The released versions correspond to PyPI releases. ### Infrastructure * Added pytype check for non-test modules in CI (see [#599](../../issues/599)). +* Added tests for different pypy3 versions. ## [Version 5.2.2](https://pypi.python.org/pypi/pyfakefs/5.2.2) (2023-04-13) Fixes a regression in 5.2.0 diff --git a/pyfakefs/fake_io.py b/pyfakefs/fake_io.py index 2f78230..fc719ad 100644 --- a/pyfakefs/fake_io.py +++ b/pyfakefs/fake_io.py @@ -33,6 +33,7 @@ from typing import ( from pyfakefs.fake_file import AnyFileWrapper from pyfakefs.fake_open import FakeFileOpen +from pyfakefs.helpers import IS_PYPY if TYPE_CHECKING: from pyfakefs.fake_filesystem import FakeFilesystem @@ -124,7 +125,7 @@ class FakeIoModule: function may be overridden by an earlier call to the PyFile_SetOpenCodeHook(). This behavior is not reproduced here. """ - if not isinstance(path, str): + if not isinstance(path, str) and not IS_PYPY: raise TypeError("open_code() argument 'path' must be str, not int") patch_mode = self.filesystem.patch_open_code if ( diff --git a/pyfakefs/fake_os.py b/pyfakefs/fake_os.py index 989d5c9..ba19bf8 100644 --- a/pyfakefs/fake_os.py +++ b/pyfakefs/fake_os.py @@ -1348,7 +1348,7 @@ if sys.version_info > (3, 10): @functools.wraps(f) def wrapped(*args, **kwargs): - if not f.__name__.startswith("_") and FakeOsModule.use_original: + if FakeOsModule.use_original: # remove the `self` argument for FakeOsModule methods if args and isinstance(args[0], FakeOsModule): args = args[1:] @@ -1358,7 +1358,8 @@ if sys.version_info > (3, 10): return wrapped for name, fn in inspect.getmembers(FakeOsModule, inspect.isfunction): - setattr(FakeOsModule, name, handle_original_call(fn)) + if not fn.__name__.startswith("_"): + setattr(FakeOsModule, name, handle_original_call(fn)) @contextmanager diff --git a/pyfakefs/fake_pathlib.py b/pyfakefs/fake_pathlib.py index 17c3ebb..6e096d1 100644 --- a/pyfakefs/fake_pathlib.py +++ b/pyfakefs/fake_pathlib.py @@ -47,6 +47,7 @@ from pyfakefs.extra_packages import use_scandir from pyfakefs.fake_filesystem import FakeFilesystem from pyfakefs.fake_open import FakeFileOpen from pyfakefs.fake_os import FakeOsModule, use_original_os +from pyfakefs.helpers import IS_PYPY def init_module(filesystem): @@ -130,9 +131,8 @@ class _FakeAccessor(accessor): # type: ignore[valid-type, misc] "chmod() got an unexpected keyword " "argument 'follow_symlinks'" ) - if ( - not kwargs["follow_symlinks"] - and os.chmod not in os.supports_follow_symlinks + if not kwargs["follow_symlinks"] and ( + os.chmod not in os.supports_follow_symlinks or IS_PYPY ): raise NotImplementedError( "`follow_symlinks` for chmod() is not available " "on this system" @@ -916,7 +916,8 @@ if sys.version_info > (3, 10): return wrapped for name, fn in inspect.getmembers(RealPath, inspect.isfunction): - setattr(RealPath, name, with_original_os(fn)) + if not name.startswith("__"): + setattr(RealPath, name, with_original_os(fn)) class RealPathlibPathModule: diff --git a/pyfakefs/pytest_plugin.py b/pyfakefs/pytest_plugin.py index 0ecdd0e..fed7a55 100644 --- a/pyfakefs/pytest_plugin.py +++ b/pyfakefs/pytest_plugin.py @@ -10,6 +10,7 @@ def my_fakefs_test(fs): """ import py import pytest +from _pytest import capture from pyfakefs.fake_filesystem_unittest import Patcher @@ -20,6 +21,7 @@ except ImportError: Patcher.SKIPMODULES.add(py) Patcher.SKIPMODULES.add(pytest) +Patcher.SKIPMODULES.add(capture) if pathlib is not None: Patcher.SKIPMODULES.add(pathlib) diff --git a/pyfakefs/tests/fake_filesystem_shutil_test.py b/pyfakefs/tests/fake_filesystem_shutil_test.py index a3b4ae3..83d4672 100644 --- a/pyfakefs/tests/fake_filesystem_shutil_test.py +++ b/pyfakefs/tests/fake_filesystem_shutil_test.py @@ -25,7 +25,7 @@ import unittest from pathlib import Path from pyfakefs import fake_filesystem_unittest -from pyfakefs.helpers import get_uid, set_uid, is_root +from pyfakefs.helpers import get_uid, set_uid, is_root, IS_PYPY from pyfakefs.tests.test_utils import RealFsTestMixin is_windows = sys.platform == "win32" @@ -231,6 +231,7 @@ class FakeShutilModuleTest(RealFsTestCase): self.assertAlmostEqual(src_stat.st_atime, dst_stat.st_atime, places=2) self.assertAlmostEqual(src_stat.st_mtime, dst_stat.st_mtime, places=2) + @unittest.skipIf(IS_PYPY, "Functionality not supported in PyPy") def test_copystat_symlinks(self): """Regression test for #799""" self.skip_if_symlink_not_supported() diff --git a/pyfakefs/tests/fake_open_test.py b/pyfakefs/tests/fake_open_test.py index cdb8a7b..21a5043 100644 --- a/pyfakefs/tests/fake_open_test.py +++ b/pyfakefs/tests/fake_open_test.py @@ -25,7 +25,7 @@ import time import unittest from pyfakefs import fake_filesystem, helpers -from pyfakefs.helpers import is_root +from pyfakefs.helpers import is_root, IS_PYPY from pyfakefs.fake_io import FakeIoModule from pyfakefs.fake_filesystem_unittest import PatchMode from pyfakefs.tests.test_utils import RealFsTestCase @@ -1057,10 +1057,19 @@ class FakeFilePatchedOpenCodeTest(FakeFileOpenTestBase): self.filesystem.patch_open_code = False super(FakeFilePatchedOpenCodeTest, self).tearDown() + @unittest.skipIf(IS_PYPY, "Different behavior in PyPy") def test_invalid_path(self): with self.assertRaises(TypeError): self.open_code(4) + @unittest.skipIf(not IS_PYPY, "Different behavior in PyPy") + def test_open_code_fd_pypy(self): + file_path = self.make_path("foo") + self.create_file(file_path, contents="test") + fd = self.os.open(file_path, os.O_RDONLY) + with self.open_code(fd) as f: + assert f.read() == b"test" + def test_byte_contents_open_code(self): byte_fractions = b"\xe2\x85\x93 \xe2\x85\x94 \xe2\x85\x95 \xe2\x85\x96" file_path = self.make_path("foo") @@ -1090,6 +1099,7 @@ class FakeFileUnpatchedOpenCodeTest(FakeFileOpenTestBase): else: self.open_code = self.fake_io_module.open_code + @unittest.skipIf(IS_PYPY, "Different behavior in PyPy") def test_invalid_path(self): with self.assertRaises(TypeError): self.open_code(4) diff --git a/pyfakefs/tests/patched_packages_test.py b/pyfakefs/tests/patched_packages_test.py index f57bb58..1c76091 100644 --- a/pyfakefs/tests/patched_packages_test.py +++ b/pyfakefs/tests/patched_packages_test.py @@ -15,6 +15,7 @@ Provides patches for some commonly used modules that enable them to work with pyfakefs. """ import os +import sys import unittest from pyfakefs import fake_filesystem_unittest @@ -36,7 +37,9 @@ except ImportError: openpyxl = None -@unittest.skipIf(IS_PYPY, "Has a problem with current PyPy") +@unittest.skipIf( + IS_PYPY and sys.version_info < (3, 8), "Has a problem with older PyPy versions" +) class TestPatchedPackages(fake_filesystem_unittest.TestCase): def setUp(self): self.setUpPyfakefs() -- cgit v1.2.3