aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrbean-bremen <hansemrbean@googlemail.com>2023-04-11 13:01:34 +0200
committermrbean-bremen <mrbean-bremen@users.noreply.github.com>2023-04-11 15:50:50 +0200
commit7071d88c94c29fd8b11b4ca7a49192baea9e7cbe (patch)
tree6d3b305feb2177082d6e0b062dd66df20dd72bc4
parent36170ee62592b0f53a64d4f6f37bd8023887bd15 (diff)
downloadpyfakefs-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.md3
-rw-r--r--pyfakefs/fake_pathlib.py89
-rw-r--r--pyfakefs/tests/fake_os_test.py20
3 files changed, 62 insertions, 50 deletions
diff --git a/CHANGES.md b/CHANGES.md
index fe11296..d62ad48 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -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],