4242import warnings
4343from pathlib import PurePath
4444from typing import Callable , List , Optional
45+ from unittest import mock
4546from urllib .parse import quote_from_bytes as urlquote_from_bytes
4647
4748from pyfakefs import fake_scandir
@@ -554,6 +555,7 @@ def gethomedir(self, username):
554555
555556 def compile_pattern (self , pattern ):
556557 return re .compile (fnmatch .translate (pattern )).fullmatch
558+
557559else : # Python >= 3.12
558560
559561 class FakePosixPathModule (FakePathModule ):
@@ -862,24 +864,48 @@ def _warn_is_reserved_deprecated():
862864class FakePathlibModule :
863865 """Uses FakeFilesystem to provide a fake pathlib module replacement.
864866
865- You need a fake_filesystem to use this::
867+ Automatically created if using `fake_filesystem_unittest.TestCase`,
868+ `fs` fixture, or the `patchfs` decorator.
869+
870+ For creating it separately, a `fake_filesystem` instance is needed::
866871
867872 filesystem = fake_filesystem.FakeFilesystem()
868873 fake_pathlib_module = fake_pathlib.FakePathlibModule(filesystem)
869874 """
870875
871- def __init__ (self , filesystem ):
876+ def __init__ (self , filesystem , from_patcher = False ):
872877 """
873878 Initializes the module with the given filesystem.
874879
875880 Args:
876881 filesystem: FakeFilesystem used to provide file system information
882+ from_patcher: If `False` (the default), `pathlib.os` will be manually
883+ patched using `FakeOsModule`. This allows to instantiate the class
884+ manually for a test.
885+ Will be set to `True` if instantiated from `Patcher`.
877886 """
878887 init_module (filesystem )
879888 self ._pathlib_module = pathlib
889+ self ._os = None
890+ self ._os_patcher = None
891+ if not from_patcher :
892+ self .patch_os_module ()
893+
894+ def patch_os_module (self ):
895+ if sys .version_info >= (3 , 11 ) and not isinstance (os , FakeOsModule ):
896+ self ._os = FakeOsModule (FakePath .filesystem )
897+ pathlib_os = (
898+ "pathlib._local.os" if sys .version_info [:2 ] == (3 , 13 ) else "pathlib.os"
899+ )
900+ self ._os_patcher = mock .patch (pathlib_os , self ._os )
901+ self ._os_patcher .start ()
902+
903+ def __del__ (self ):
904+ if self ._os_patcher is not None :
905+ self ._os_patcher .stop ()
880906
881907 class PurePosixPath (PurePath ):
882- """A subclass of PurePath, that represents non-Windows filesystem
908+ """A subclass of PurePath that represents non-Windows filesystem
883909 paths"""
884910
885911 __slots__ = ()
@@ -898,7 +924,7 @@ def joinpath(self, *pathsegments):
898924 return super ().joinpath (* pathsegments )
899925
900926 class PureWindowsPath (PurePath ):
901- """A subclass of PurePath, that represents Windows filesystem paths"""
927+ """A subclass of PurePath that represents Windows filesystem paths"""
902928
903929 __slots__ = ()
904930
@@ -990,9 +1016,9 @@ class FakePathlibPathModule:
9901016
9911017 fake_pathlib = None
9921018
993- def __init__ (self , filesystem = None ):
1019+ def __init__ (self , filesystem = None , from_patcher = False ):
9941020 if self .fake_pathlib is None :
995- self .__class__ .fake_pathlib = FakePathlibModule (filesystem )
1021+ self .__class__ .fake_pathlib = FakePathlibModule (filesystem , from_patcher )
9961022
9971023 @property
9981024 def skip_names (self ):
0 commit comments