Skip to content

Commit 02d5f69

Browse files
committed
Overwrite _from_parts / _from_parsed_parts to call _init
- fix link_to for Python 3.10 - revert some of the probably unneeded changes
1 parent d6ae60b commit 02d5f69

File tree

2 files changed

+37
-31
lines changed

2 files changed

+37
-31
lines changed

pyfakefs/fake_pathlib.py

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ def init_module(filesystem):
5454
def _wrap_strfunc(strfunc):
5555
@functools.wraps(strfunc)
5656
def _wrapped(pathobj, *args, **kwargs):
57-
p = pathobj.filesystem if hasattr(pathobj, "filesystem") else pathobj
58-
return strfunc(p, str(pathobj), *args, **kwargs)
57+
return strfunc(pathobj.filesystem, str(pathobj), *args, **kwargs)
5958

6059
return staticmethod(_wrapped)
6160

@@ -125,23 +124,19 @@ def lchmod(self, pathobj, mode):
125124
FakeFilesystem.create_symlink(fs, file_path, link_target,
126125
create_missing_dirs=False))
127126

128-
if sys.version_info >= (3, 8):
127+
if (3, 8) <= sys.version_info < (3, 10):
129128
link_to = _wrap_binary_strfunc(
130129
lambda fs, file_path, link_target:
131130
FakeFilesystem.link(fs, file_path, link_target))
132131

133-
if sys.version_info >= (3, 9):
134-
readlink = _wrap_strfunc(FakeFilesystem.readlink)
135-
else:
136-
# why? and shouldnt this not be *os* -- but something patched (FakeOsModule probably)?
137-
readlink = staticmethod(os.readlink)
138-
pass
132+
if sys.version_info >= (3, 10):
133+
link = _wrap_binary_strfunc(
134+
lambda fs, file_path, link_target:
135+
FakeFilesystem.link(fs, file_path, link_target))
139136

140-
utime = _wrap_strfunc(FakeFilesystem.utime)
137+
readlink = _wrap_strfunc(FakeFilesystem.readlink)
141138

142-
# same comment as above for these two
143-
realpath = staticmethod(os.path.realpath)
144-
getcwd = staticmethod(os.getcwd)
139+
utime = _wrap_strfunc(FakeFilesystem.utime)
145140

146141

147142
_fake_accessor = _FakeAccessor()
@@ -471,15 +466,35 @@ def __new__(cls, *args, **kwargs):
471466
if cls.filesystem.is_windows_fs
472467
else FakePathlibModule.PosixPath)
473468
self = cls._from_parts(args)
469+
return self
470+
471+
@classmethod
472+
def _from_parts(cls, args, init=False): # pylint: disable=unused-argument
473+
# Overwritten to call _init to set the fake accessor,
474+
# which is not done since Python 3.10
475+
self = object.__new__(cls)
474476
self._init()
477+
drv, root, parts = self._parse_args(args)
478+
self._drv = drv
479+
self._root = root
480+
self._parts = parts
481+
return self
482+
483+
@classmethod
484+
def _from_parsed_parts(cls, drv, root, parts):
485+
# Overwritten to call _init to set the fake accessor,
486+
# which is not done since Python 3.10
487+
self = object.__new__(cls)
488+
self._init()
489+
self._drv = drv
490+
self._root = root
491+
self._parts = parts
475492
return self
476493

477494
def _init(self, template=None):
478-
"""Initializer called from base class."""
479-
# template is an unused holdover
480-
_ = template
481-
self._accessor = _fake_accessor
482-
self._closed = False
495+
"""Initializer called from base class."""
496+
self._accessor = _fake_accessor
497+
self._closed = False
483498

484499
def _path(self):
485500
"""Returns the underlying path string as used by the fake filesystem.
@@ -729,20 +744,12 @@ class RealPath(pathlib.Path):
729744
itself is not.
730745
"""
731746

732-
def _init(self, template=None):
733-
"""Initializer called from base class."""
734-
# template is an unused holdover
735-
_ = template
736-
self._accessor = _fake_accessor
737-
self._closed = False
738-
739747
def __new__(cls, *args, **kwargs):
740748
"""Creates the correct subclass based on OS."""
741749
if cls is RealPathlibModule.Path:
742750
cls = (RealPathlibModule.WindowsPath if os.name == 'nt'
743751
else RealPathlibModule.PosixPath)
744752
self = cls._from_parts(args)
745-
self._init()
746753
return self
747754

748755

pyfakefs/tests/fake_pathlib_test.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,20 +378,19 @@ def test_chmod(self):
378378
# we get stat.S_IFLNK | 0o755 under MacOs
379379
self.assertEqual(link_stat.st_mode, stat.S_IFLNK | 0o777)
380380

381-
@unittest.skipIf(sys.platform == 'darwin',
382-
'Different behavior under MacOs')
383381
def test_lchmod(self):
384382
self.skip_if_symlink_not_supported()
385383
file_stat = self.os.stat(self.file_path)
386384
link_stat = self.os.lstat(self.file_link_path)
387-
if not hasattr(os, "lchmod"):
385+
if not hasattr(os, "lchmod") and sys.version_info < (3, 10):
388386
with self.assertRaises(NotImplementedError):
389387
self.path(self.file_link_path).lchmod(0o444)
390388
else:
391389
self.path(self.file_link_path).lchmod(0o444)
392390
self.assertEqual(file_stat.st_mode, stat.S_IFREG | 0o666)
393-
# we get stat.S_IFLNK | 0o755 under MacOs
394-
self.assertEqual(link_stat.st_mode, stat.S_IFLNK | 0o444)
391+
# the exact mode depends on OS and Python version
392+
self.assertEqual(link_stat.st_mode & 0o777700,
393+
stat.S_IFLNK | 0o700)
395394

396395
def test_resolve(self):
397396
self.create_dir(self.make_path('antoine', 'docs'))

0 commit comments

Comments
 (0)