1
+ import os
2
+ import stat
1
3
import sys
4
+ import time
5
+ import warnings
2
6
3
7
import pytest
4
8
@@ -17,3 +21,128 @@ def only_on_windows(func):
17
21
18
22
def posixify (path ):
19
23
return str (path ).replace ("\\ " , "/" )
24
+
25
+
26
+ # === vendored from test.os_support ===========================================
27
+ # https://github.com/python/cpython/blob/7f97c8e36786/Lib/test/support/os_helper.py#LL327C1-L445C1
28
+ # fmt: off
29
+ if sys .platform .startswith ("win" ):
30
+ def _waitfor (func , pathname , waitall = False ):
31
+ # Perform the operation
32
+ func (pathname )
33
+ # Now setup the wait loop
34
+ if waitall :
35
+ dirname = pathname
36
+ else :
37
+ dirname , name = os .path .split (pathname )
38
+ dirname = dirname or '.'
39
+ # Check for `pathname` to be removed from the filesystem.
40
+ # The exponential backoff of the timeout amounts to a total
41
+ # of ~1 second after which the deletion is probably an error
42
+ # anyway.
43
+ # Testing on an [email protected] shows that usually only 1 iteration is
44
+ # required when contention occurs.
45
+ timeout = 0.001
46
+ while timeout < 1.0 :
47
+ # Note we are only testing for the existence of the file(s) in
48
+ # the contents of the directory regardless of any security or
49
+ # access rights. If we have made it this far, we have sufficient
50
+ # permissions to do that much using Python's equivalent of the
51
+ # Windows API FindFirstFile.
52
+ # Other Windows APIs can fail or give incorrect results when
53
+ # dealing with files that are pending deletion.
54
+ L = os .listdir (dirname )
55
+ if not (L if waitall else name in L ):
56
+ return
57
+ # Increase the timeout and try again
58
+ time .sleep (timeout )
59
+ timeout *= 2
60
+ warnings .warn ('tests may fail, delete still pending for ' + pathname ,
61
+ RuntimeWarning , stacklevel = 4 )
62
+
63
+ def _unlink (filename ):
64
+ _waitfor (os .unlink , filename )
65
+
66
+ def _rmdir (dirname ):
67
+ _waitfor (os .rmdir , dirname )
68
+
69
+ def _rmtree (path ):
70
+ from test .support import _force_run
71
+
72
+ def _rmtree_inner (path ):
73
+ for name in _force_run (path , os .listdir , path ):
74
+ fullname = os .path .join (path , name )
75
+ try :
76
+ mode = os .lstat (fullname ).st_mode
77
+ except OSError as exc :
78
+ print ("support.rmtree(): os.lstat(%r) failed with %s"
79
+ % (fullname , exc ),
80
+ file = sys .__stderr__ )
81
+ mode = 0
82
+ if stat .S_ISDIR (mode ):
83
+ _waitfor (_rmtree_inner , fullname , waitall = True )
84
+ _force_run (fullname , os .rmdir , fullname )
85
+ else :
86
+ _force_run (fullname , os .unlink , fullname )
87
+ _waitfor (_rmtree_inner , path , waitall = True )
88
+ _waitfor (lambda p : _force_run (p , os .rmdir , p ), path )
89
+
90
+ def _longpath (path ):
91
+ try :
92
+ import ctypes
93
+ except ImportError :
94
+ # No ctypes means we can't expands paths.
95
+ pass
96
+ else :
97
+ buffer = ctypes .create_unicode_buffer (len (path ) * 2 )
98
+ length = ctypes .windll .kernel32 .GetLongPathNameW (path , buffer ,
99
+ len (buffer ))
100
+ if length :
101
+ return buffer [:length ]
102
+ return path
103
+ else :
104
+ _unlink = os .unlink
105
+ _rmdir = os .rmdir
106
+
107
+ def _rmtree (path ):
108
+ import shutil
109
+ try :
110
+ shutil .rmtree (path )
111
+ return
112
+ except OSError :
113
+ pass
114
+
115
+ def _rmtree_inner (path ):
116
+ from test .support import _force_run
117
+ for name in _force_run (path , os .listdir , path ):
118
+ fullname = os .path .join (path , name )
119
+ try :
120
+ mode = os .lstat (fullname ).st_mode
121
+ except OSError :
122
+ mode = 0
123
+ if stat .S_ISDIR (mode ):
124
+ _rmtree_inner (fullname )
125
+ _force_run (path , os .rmdir , fullname )
126
+ else :
127
+ _force_run (path , os .unlink , fullname )
128
+ _rmtree_inner (path )
129
+ os .rmdir (path )
130
+
131
+ def _longpath (path ):
132
+ return path
133
+
134
+
135
+ def rmdir (dirname ):
136
+ try :
137
+ _rmdir (dirname )
138
+ except FileNotFoundError :
139
+ pass
140
+
141
+
142
+ def rmtree (path ):
143
+ try :
144
+ _rmtree (path )
145
+ except FileNotFoundError :
146
+ pass
147
+ # fmt: on
148
+ # === /vendored from test.os_support ==========================================
0 commit comments