diff options
author | mrbean-bremen <hansemrbean@googlemail.com> | 2023-04-11 13:01:34 +0200 |
---|---|---|
committer | mrbean-bremen <mrbean-bremen@users.noreply.github.com> | 2023-04-11 15:50:50 +0200 |
commit | 7071d88c94c29fd8b11b4ca7a49192baea9e7cbe (patch) | |
tree | 6d3b305feb2177082d6e0b062dd66df20dd72bc4 | |
parent | 36170ee62592b0f53a64d4f6f37bd8023887bd15 (diff) | |
download | pyfakefs-7071d88c94c29fd8b11b4ca7a49192baea9e7cbe.tar.gz |
Adapt fake pathlib to changes in Python 3.12a7
- stat.st_ctype is deprecated under Windows in 3.12 on,
comment out the tests for the time being
(support for st_birthdate to be added)
-rw-r--r-- | CHANGES.md | 3 | ||||
-rw-r--r-- | pyfakefs/fake_pathlib.py | 89 | ||||
-rw-r--r-- | pyfakefs/tests/fake_os_test.py | 20 |
3 files changed, 62 insertions, 50 deletions
@@ -3,6 +3,9 @@ The released versions correspond to PyPI releases. ## Unreleased +### Changes +* Adapted fake pathlib to changes in Python 3.12a7 (last alpha version) + ### Fixes * Properties defining the capabilities of some `os` functions like `os.supports_follow_symlinks` are now properly faked to contain the fake functions diff --git a/pyfakefs/fake_pathlib.py b/pyfakefs/fake_pathlib.py index 2291ddb..62a3d3c 100644 --- a/pyfakefs/fake_pathlib.py +++ b/pyfakefs/fake_pathlib.py @@ -520,39 +520,41 @@ class FakePath(pathlib.Path): if cls.filesystem.is_windows_fs else FakePathlibModule.PosixPath ) - self = cls._from_parts(args) - return self - - @classmethod - def _from_parts(cls, args, init=False): # pylint: disable=unused-argument - # Overwritten to call _init to set the fake accessor, - # which is not done since Python 3.10 - self = object.__new__(cls) - self._init() - parse_fct = ( - self._parse_parts if sys.version_info >= (3, 12) else self._parse_args - ) - drv, root, parts = parse_fct(args) - self._drv = drv - self._root = root - self._parts = parts - return self - - @classmethod - def _from_parsed_parts(cls, drv, root, parts): - # Overwritten to call _init to set the fake accessor, - # which is not done since Python 3.10 - self = object.__new__(cls) - self._init() - self._drv = drv - self._root = root - self._parts = parts - return self - - def _init(self, template=None): - """Initializer called from base class.""" - self._accessor = _fake_accessor - self._closed = False + if sys.version_info < (3, 12): + return cls._from_parts(args) + else: + return object.__new__(cls) + + if sys.version_info[:2] == (3, 10): + # Overwritten class methods to call _init to set the fake accessor, + # which is not done in Python 3.10, and not needed from Python 3.11 on + @classmethod + def _from_parts(cls, args, init=False): # pylint: disable=unused-argument + self = object.__new__(cls) + self._init() + drv, root, parts = self._parse_args(args) + self._drv = drv + self._root = root + self._parts = parts + return self + + @classmethod + def _from_parsed_parts(cls, drv, root, parts): + self = object.__new__(cls) + self._drv = drv + self._root = root + self._parts = parts + self._init() + return self + + if sys.version_info < (3, 11): + + def _init(self, template=None): + """Initializer called from base class.""" + # only needed until Python 3.10 + self._accessor = _fake_accessor + # only needed until Python 3.8 + self._closed = False def _path(self): """Returns the underlying path string as used by the fake @@ -591,8 +593,7 @@ class FakePath(pathlib.Path): "resolve() got an unexpected keyword argument 'strict'" ) strict = True - if self._closed: - self._raise_closed() + self._raise_on_closed() path = self._flavour.resolve(self, strict=strict) if path is None: self.stat() @@ -607,8 +608,7 @@ class FakePath(pathlib.Path): OSError: if the target object is a directory, the path is invalid or permission is denied. """ - if self._closed: - self._raise_closed() + self._raise_on_closed() return FakeFileOpen(self.filesystem)( self._path(), mode, buffering, encoding, errors, newline ) @@ -720,6 +720,10 @@ class FakePath(pathlib.Path): ) ) + def _raise_on_closed(self): + if sys.version_info < (3, 9) and self._closed: + self._raise_closed() + def touch(self, mode=0o666, exist_ok=True): """Create a fake file for the path with the given access mode, if it doesn't exist. @@ -732,8 +736,7 @@ class FakePath(pathlib.Path): Raises: FileExistsError: if the file exists and exits_ok is False. """ - if self._closed: - self._raise_closed() + self._raise_on_closed() if self.exists(): if exist_ok: self.filesystem.utime(self._path(), times=None) @@ -751,7 +754,7 @@ class FakePath(pathlib.Path): def is_absolute(self): if self.filesystem.is_windows_fs: - return self._drv and self._root + return self.drive and self.root return os.path.isabs(self._path()) def is_reserved(self): @@ -887,8 +890,10 @@ class RealPath(pathlib.Path): if os.name == "nt" else RealPathlibModule.PosixPath ) - self = cls._from_parts(args) - return self + if sys.version_info < (3, 12): + return cls._from_parts(args) + else: + return object.__new__(cls) if sys.version_info > (3, 10): diff --git a/pyfakefs/tests/fake_os_test.py b/pyfakefs/tests/fake_os_test.py index e9294f6..dc83649 100644 --- a/pyfakefs/tests/fake_os_test.py +++ b/pyfakefs/tests/fake_os_test.py @@ -5200,10 +5200,12 @@ class FakeScandirTest(FakeOsModuleTestBase): self, absolute_symlink_expected_size, relative_symlink_expected_size ): self.assertEqual(self.FILE_SIZE, self.dir_entries[1].stat().st_size) - self.assertEqual( - int(self.os.stat(self.dir_path).st_ctime), - int(self.dir_entries[0].stat().st_ctime), - ) + if not self.is_windows_fs or sys.version_info < (3, 12): + # behavior of st_ctime changed in 3.12, to be adapted later + self.assertEqual( + int(self.os.stat(self.dir_path).st_ctime), + int(self.dir_entries[0].stat().st_ctime), + ) if self.supports_symlinks: self.assertEqual(self.LINKED_FILE_SIZE, self.dir_entries[3].stat().st_size) @@ -5234,10 +5236,12 @@ class FakeScandirTest(FakeOsModuleTestBase): self.check_stat(0, 0) def test_index_access_to_stat_times_returns_int(self): - self.assertEqual( - self.os.stat(self.dir_path)[stat.ST_CTIME], - int(self.dir_entries[0].stat().st_ctime), - ) + if not self.is_windows_fs or sys.version_info < (3, 12): + # behavior of st_ctime changed in 3.12, to be adapted later + self.assertEqual( + self.os.stat(self.dir_path)[stat.ST_CTIME], + int(self.dir_entries[0].stat().st_ctime), + ) if self.supports_symlinks: self.assertEqual( self.os.stat(self.linked_dir_path)[stat.ST_MTIME], |