@@ -66,25 +66,73 @@ def __repr__(self):
6666 return "<{}.parents>" .format (type (self ._path ).__name__ )
6767
6868
69- class _PathStatus :
70- """Implementation of pathlib.types.Status that provides file status
71- information. Don't try to construct it yourself."""
72- __slots__ = ('_path' , '_repr' , '_mode' )
69+ class _PathStatusBase :
70+ __slots__ = ('_path' , '_repr' )
7371
7472 def __init__ (self , path ):
7573 self ._path = str (path )
7674 self ._repr = f"<{ type (path ).__name__ } .status>"
77- self ._mode = [None , None ]
75+
76+ def __fspath__ (self ):
77+ return self ._path
7878
7979 def __repr__ (self ):
8080 return self ._repr
8181
82+
83+ class _WindowsPathStatus (_PathStatusBase ):
84+ __slots__ = ('_exists' , '_is_dir' , '_is_file' , '_is_symlink' )
85+
86+ def exists (self , * , follow_symlinks = True ):
87+ if not follow_symlinks and self .is_symlink ():
88+ return True
89+ try :
90+ return self ._exists
91+ except AttributeError :
92+ self ._exists = os .path .exists (self )
93+ return self ._exists
94+
95+ def is_dir (self , * , follow_symlinks = True ):
96+ if not follow_symlinks and self .is_symlink ():
97+ return False
98+ try :
99+ return self ._is_dir
100+ except AttributeError :
101+ self ._is_dir = os .path .isdir (self )
102+ return self ._is_dir
103+
104+ def is_file (self , * , follow_symlinks = True ):
105+ if not follow_symlinks and self .is_symlink ():
106+ return False
107+ try :
108+ return self ._is_file
109+ except AttributeError :
110+ self ._is_file = os .path .isfile (self )
111+ return self ._is_file
112+
113+ def is_symlink (self ):
114+ try :
115+ return self ._is_symlink
116+ except AttributeError :
117+ self ._is_symlink = os .path .islink (self )
118+ return self ._is_symlink
119+
120+
121+ class _PosixPathStatus (_PathStatusBase ):
122+ """Implementation of pathlib.types.Status that provides file status
123+ information. Don't try to construct it yourself."""
124+ __slots__ = ('_mode' ,)
125+
126+ def __init__ (self , path ):
127+ super ().__init__ (path )
128+ self ._mode = [None , None ]
129+
82130 def _get_mode (self , * , follow_symlinks = True ):
83131 idx = int (follow_symlinks )
84132 mode = self ._mode [idx ]
85133 if mode is None :
86134 try :
87- st = os .stat (self . _path , follow_symlinks = follow_symlinks )
135+ st = os .stat (self , follow_symlinks = follow_symlinks )
88136 except (OSError , ValueError ):
89137 mode = 0
90138 else :
@@ -121,29 +169,35 @@ def is_symlink(self):
121169 return S_ISLNK (self ._get_mode (follow_symlinks = False ))
122170
123171
124- class _DirEntryStatus :
172+ _PathStatus = _WindowsPathStatus if os .name == 'nt' else _PosixPathStatus
173+
174+
175+ class _DirEntryStatus (_PathStatusBase ):
125176 """Implementation of pathlib.types.Status that provides file status
126177 information by querying a wrapped os.DirEntry object. Don't try to
127178 construct it yourself."""
128- __slots__ = ('_entry' , '_repr ' )
179+ __slots__ = ('_entry' , '_exists ' )
129180
130181 def __init__ (self , path , entry ):
182+ super ().__init__ (path )
131183 self ._entry = entry
132- self ._repr = f"<{ type (path ).__name__ } .status>"
133-
134- def __repr__ (self ):
135- return self ._repr
136184
137185 def exists (self , * , follow_symlinks = True ):
138186 """
139187 Whether this path exists
140188 """
141- if follow_symlinks :
189+ if not follow_symlinks :
190+ return True
191+ try :
192+ return self ._exists
193+ except AttributeError :
142194 try :
143195 self ._entry .stat ()
144196 except OSError :
145- return False
146- return True
197+ self ._exists = False
198+ else :
199+ self ._exists = True
200+ return self ._exists
147201
148202 def is_dir (self , * , follow_symlinks = True ):
149203 """
0 commit comments