Merge lp:~jelmer/brz/3.3-walkdirs into lp:brz/3.3
- 3.3-walkdirs
- Merge into 3.3
Proposed by
Jelmer Vernooij
Status: | Merged |
---|---|
Approved by: | Jelmer Vernooij |
Approved revision: | 7830 |
Merged at revision: | 7830 |
Proposed branch: | lp:~jelmer/brz/3.3-walkdirs |
Merge into: | lp:brz/3.3 |
Diff against target: |
642 lines (+3/-533) 7 files modified
.bzrignore (+0/-1) breezy/_walkdirs_win32.pyx (+0/-303) breezy/osutils.py (+1/-13) breezy/tests/__init__.py (+0/-1) breezy/tests/test__walkdirs_win32.py (+0/-111) breezy/tests/test_osutils.py (+2/-103) setup.py (+0/-1) |
To merge this branch: | bzr merge lp:~jelmer/brz/3.3-walkdirs |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jelmer Vernooij | Approve | ||
Review via email: mp+463544@code.launchpad.net |
Commit message
Drop the win32 specific walkdirs implementation
Description of the change
Drop the win32 specific walkdirs implementation
To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2024-04-01 16:01:47 +0000 |
3 | +++ .bzrignore 2024-04-02 23:21:37 +0000 |
4 | @@ -65,7 +65,6 @@ |
5 | breezy/bzr/_simple_set_pyx.c |
6 | breezy/bzr/_simple_set_pyx.h |
7 | breezy/bzr/_simple_set_pyx_api.h |
8 | -breezy/_walkdirs_win32.c |
9 | # built extension modules |
10 | breezy/_*.dll |
11 | breezy/_*.so |
12 | |
13 | === removed file 'breezy/_walkdirs_win32.pyx' |
14 | --- breezy/_walkdirs_win32.pyx 2023-01-31 01:05:40 +0000 |
15 | +++ breezy/_walkdirs_win32.pyx 1970-01-01 00:00:00 +0000 |
16 | @@ -1,303 +0,0 @@ |
17 | -# Copyright (C) 2008-2012 Canonical Ltd |
18 | -# |
19 | -# This program is free software; you can redistribute it and/or modify |
20 | -# it under the terms of the GNU General Public License as published by |
21 | -# the Free Software Foundation; either version 2 of the License, or |
22 | -# (at your option) any later version. |
23 | -# |
24 | -# This program is distributed in the hope that it will be useful, |
25 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
26 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
27 | -# GNU General Public License for more details. |
28 | -# |
29 | -# You should have received a copy of the GNU General Public License |
30 | -# along with this program; if not, write to the Free Software |
31 | -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
32 | -# |
33 | -# cython: language_level=3 |
34 | - |
35 | -"""Helper functions for Walkdirs on win32.""" |
36 | - |
37 | - |
38 | -cdef extern from "python-compat.h": |
39 | - struct _HANDLE: |
40 | - pass |
41 | - ctypedef _HANDLE *HANDLE |
42 | - ctypedef unsigned long DWORD |
43 | - ctypedef long long __int64 |
44 | - ctypedef unsigned short WCHAR |
45 | - struct _FILETIME: |
46 | - DWORD dwHighDateTime |
47 | - DWORD dwLowDateTime |
48 | - ctypedef _FILETIME FILETIME |
49 | - |
50 | - struct _WIN32_FIND_DATAW: |
51 | - DWORD dwFileAttributes |
52 | - FILETIME ftCreationTime |
53 | - FILETIME ftLastAccessTime |
54 | - FILETIME ftLastWriteTime |
55 | - DWORD nFileSizeHigh |
56 | - DWORD nFileSizeLow |
57 | - # Some reserved stuff here |
58 | - WCHAR cFileName[260] # MAX_PATH |
59 | - WCHAR cAlternateFilename[14] |
60 | - |
61 | - # We have to use the typedef trick, otherwise pyrex uses: |
62 | - # struct WIN32_FIND_DATAW |
63 | - # which fails due to 'incomplete type' |
64 | - ctypedef _WIN32_FIND_DATAW WIN32_FIND_DATAW |
65 | - |
66 | - HANDLE INVALID_HANDLE_VALUE |
67 | - HANDLE FindFirstFileW(WCHAR *path, WIN32_FIND_DATAW *data) |
68 | - int FindNextFileW(HANDLE search, WIN32_FIND_DATAW *data) |
69 | - int FindClose(HANDLE search) |
70 | - |
71 | - DWORD FILE_ATTRIBUTE_READONLY |
72 | - DWORD FILE_ATTRIBUTE_DIRECTORY |
73 | - int ERROR_NO_MORE_FILES |
74 | - |
75 | - int GetLastError() |
76 | - |
77 | - # Wide character functions |
78 | - DWORD wcslen(WCHAR *) |
79 | - |
80 | - |
81 | -cdef extern from "Python.h": |
82 | - WCHAR *PyUnicode_AS_UNICODE(object) |
83 | - Py_ssize_t PyUnicode_GET_SIZE(object) |
84 | - object PyUnicode_FromUnicode(WCHAR *, Py_ssize_t) |
85 | - int PyList_Append(object, object) except -1 |
86 | - object PyUnicode_AsUTF8String(object) |
87 | - |
88 | - |
89 | -import operator |
90 | -import os |
91 | -import stat |
92 | - |
93 | -from . import _readdir_py |
94 | - |
95 | - |
96 | -cdef object osutils |
97 | -osutils = None |
98 | - |
99 | - |
100 | -cdef class _Win32Stat: |
101 | - """Represent a 'stat' result generated from WIN32_FIND_DATA""" |
102 | - |
103 | - cdef readonly int st_mode |
104 | - cdef readonly double st_ctime |
105 | - cdef readonly double st_mtime |
106 | - cdef readonly double st_atime |
107 | - # We can't just declare this as 'readonly' because python2.4 doesn't define |
108 | - # T_LONGLONG as a structure member. So instead we just use a property that |
109 | - # will convert it correctly anyway. |
110 | - cdef __int64 _st_size |
111 | - |
112 | - property st_size: |
113 | - def __get__(self): |
114 | - return self._st_size |
115 | - |
116 | - # os.stat always returns 0, so we hard code it here |
117 | - property st_dev: |
118 | - def __get__(self): |
119 | - return 0 |
120 | - property st_ino: |
121 | - def __get__(self): |
122 | - return 0 |
123 | - # st_uid and st_gid required for some external tools like bzr-git & dulwich |
124 | - property st_uid: |
125 | - def __get__(self): |
126 | - return 0 |
127 | - property st_gid: |
128 | - def __get__(self): |
129 | - return 0 |
130 | - |
131 | - def __repr__(self): |
132 | - """Repr is the same as a Stat object. |
133 | - |
134 | - (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) |
135 | - """ |
136 | - return repr((self.st_mode, 0, 0, 0, 0, 0, self.st_size, self.st_atime, |
137 | - self.st_mtime, self.st_ctime)) |
138 | - |
139 | - |
140 | -cdef object _get_name(WIN32_FIND_DATAW *data): |
141 | - """Extract the Unicode name for this file/dir.""" |
142 | - return PyUnicode_FromUnicode(data.cFileName, |
143 | - wcslen(data.cFileName)) |
144 | - |
145 | - |
146 | -cdef int _get_mode_bits(WIN32_FIND_DATAW *data): # cannot_raise |
147 | - cdef int mode_bits |
148 | - |
149 | - mode_bits = 0100666 # writeable file, the most common |
150 | - if data.dwFileAttributes & FILE_ATTRIBUTE_READONLY == FILE_ATTRIBUTE_READONLY: |
151 | - mode_bits = mode_bits ^ 0222 # remove the write bits |
152 | - if data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY == FILE_ATTRIBUTE_DIRECTORY: |
153 | - # Remove the FILE bit, set the DIR bit, and set the EXEC bits |
154 | - mode_bits = mode_bits ^ 0140111 |
155 | - return mode_bits |
156 | - |
157 | - |
158 | -cdef __int64 _get_size(WIN32_FIND_DATAW *data): # cannot_raise |
159 | - # Pyrex casts a DWORD into a PyLong anyway, so it is safe to do << 32 |
160 | - # on a DWORD |
161 | - return ((<__int64>data.nFileSizeHigh) << 32) + data.nFileSizeLow |
162 | - |
163 | - |
164 | -cdef double _ftime_to_timestamp(FILETIME *ft): # cannot_raise |
165 | - """Convert from a FILETIME struct into a floating point timestamp. |
166 | - |
167 | - The fields of a FILETIME structure are the hi and lo part |
168 | - of a 64-bit value expressed in 100 nanosecond units. |
169 | - 1e7 is one second in such units; 1e-7 the inverse. |
170 | - 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7. |
171 | - It also uses the epoch 1601-01-01 rather than 1970-01-01 |
172 | - (taken from posixmodule.c) |
173 | - """ |
174 | - cdef __int64 val |
175 | - # NB: This gives slightly different results versus casting to a 64-bit |
176 | - # integer and doing integer math before casting into a floating |
177 | - # point number. But the difference is in the sub millisecond range, |
178 | - # which doesn't seem critical here. |
179 | - # secs between epochs: 11,644,473,600 |
180 | - val = ((<__int64>ft.dwHighDateTime) << 32) + ft.dwLowDateTime |
181 | - return (val * 1.0e-7) - 11644473600.0 |
182 | - |
183 | - |
184 | -cdef int _should_skip(WIN32_FIND_DATAW *data): # cannot_raise |
185 | - """Is this '.' or '..' so we should skip it?""" |
186 | - if (data.cFileName[0] != c'.'): |
187 | - return 0 |
188 | - if data.cFileName[1] == c'\0': |
189 | - return 1 |
190 | - if data.cFileName[1] == c'.' and data.cFileName[2] == c'\0': |
191 | - return 1 |
192 | - return 0 |
193 | - |
194 | - |
195 | -cdef class Win32ReadDir: |
196 | - """Read directories on win32.""" |
197 | - |
198 | - cdef object _directory_kind |
199 | - cdef object _file_kind |
200 | - |
201 | - def __init__(self): |
202 | - self._directory_kind = _readdir_py._directory |
203 | - self._file_kind = _readdir_py._file |
204 | - |
205 | - def top_prefix_to_starting_dir(self, top, prefix=""): |
206 | - """See DirReader.top_prefix_to_starting_dir.""" |
207 | - global osutils |
208 | - if osutils is None: |
209 | - from . import osutils |
210 | - return (osutils.safe_utf8(prefix), None, None, None, |
211 | - osutils.safe_unicode(top)) |
212 | - |
213 | - cdef object _get_kind(self, WIN32_FIND_DATAW *data): |
214 | - if data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY: |
215 | - return self._directory_kind |
216 | - return self._file_kind |
217 | - |
218 | - cdef _Win32Stat _get_stat_value(self, WIN32_FIND_DATAW *data): |
219 | - """Get the filename and the stat information.""" |
220 | - cdef _Win32Stat statvalue |
221 | - |
222 | - statvalue = _Win32Stat() |
223 | - statvalue.st_mode = _get_mode_bits(data) |
224 | - statvalue.st_ctime = _ftime_to_timestamp(&data.ftCreationTime) |
225 | - statvalue.st_mtime = _ftime_to_timestamp(&data.ftLastWriteTime) |
226 | - statvalue.st_atime = _ftime_to_timestamp(&data.ftLastAccessTime) |
227 | - statvalue._st_size = _get_size(data) |
228 | - return statvalue |
229 | - |
230 | - def read_dir(self, prefix, top): |
231 | - """Win32 implementation of DirReader.read_dir. |
232 | - |
233 | - :seealso: DirReader.read_dir |
234 | - """ |
235 | - cdef WIN32_FIND_DATAW search_data |
236 | - cdef HANDLE hFindFile |
237 | - cdef int last_err |
238 | - cdef WCHAR *query |
239 | - cdef int result |
240 | - |
241 | - if prefix: |
242 | - relprefix = prefix + '/' |
243 | - else: |
244 | - relprefix = '' |
245 | - top_slash = top + '/' |
246 | - |
247 | - top_star = top_slash + '*' |
248 | - |
249 | - dirblock = [] |
250 | - |
251 | - query = PyUnicode_AS_UNICODE(top_star) |
252 | - hFindFile = FindFirstFileW(query, &search_data) |
253 | - if hFindFile == INVALID_HANDLE_VALUE: |
254 | - # Raise an exception? This path doesn't seem to exist |
255 | - raise WindowsError(GetLastError(), top_star) |
256 | - |
257 | - try: |
258 | - result = 1 |
259 | - while result: |
260 | - # Skip '.' and '..' |
261 | - if _should_skip(&search_data): |
262 | - result = FindNextFileW(hFindFile, &search_data) |
263 | - continue |
264 | - name_unicode = _get_name(&search_data) |
265 | - name_utf8 = PyUnicode_AsUTF8String(name_unicode) |
266 | - PyList_Append(dirblock, |
267 | - (relprefix + name_utf8, name_utf8, |
268 | - self._get_kind(&search_data), |
269 | - self._get_stat_value(&search_data), |
270 | - top_slash + name_unicode)) |
271 | - |
272 | - result = FindNextFileW(hFindFile, &search_data) |
273 | - # FindNextFileW sets GetLastError() == ERROR_NO_MORE_FILES when it |
274 | - # actually finishes. If we have anything else, then we have a |
275 | - # genuine problem |
276 | - last_err = GetLastError() |
277 | - if last_err != ERROR_NO_MORE_FILES: |
278 | - raise WindowsError(last_err) |
279 | - finally: |
280 | - result = FindClose(hFindFile) |
281 | - if result == 0: |
282 | - last_err = GetLastError() |
283 | - # TODO: We should probably raise an exception if FindClose |
284 | - # returns an error, however, I don't want to supress an |
285 | - # earlier Exception, so for now, I'm ignoring this |
286 | - dirblock.sort(key=operator.itemgetter(1)) |
287 | - return dirblock |
288 | - |
289 | - |
290 | -def lstat(path): |
291 | - """Equivalent to os.lstat, except match Win32ReadDir._get_stat_value. |
292 | - """ |
293 | - return wrap_stat(os.lstat(path)) |
294 | - |
295 | - |
296 | -def fstat(fd): |
297 | - """Like os.fstat, except match Win32ReadDir._get_stat_value |
298 | - |
299 | - :seealso: wrap_stat |
300 | - """ |
301 | - return wrap_stat(os.fstat(fd)) |
302 | - |
303 | - |
304 | -def wrap_stat(st): |
305 | - """Return a _Win32Stat object, based on the given stat result. |
306 | - |
307 | - On Windows, os.fstat(open(fname).fileno()) != os.lstat(fname). This is |
308 | - generally because os.lstat and os.fstat differ in what they put into st_ino |
309 | - and st_dev. What gets set where seems to also be dependent on the python |
310 | - version. So we always set it to 0 to avoid worrying about it. |
311 | - """ |
312 | - cdef _Win32Stat statvalue |
313 | - statvalue = _Win32Stat() |
314 | - statvalue.st_mode = st.st_mode |
315 | - statvalue.st_ctime = st.st_ctime |
316 | - statvalue.st_mtime = st.st_mtime |
317 | - statvalue.st_atime = st.st_atime |
318 | - statvalue._st_size = st.st_size |
319 | - return statvalue |
320 | |
321 | === modified file 'breezy/osutils.py' |
322 | --- breezy/osutils.py 2024-04-01 18:20:12 +0000 |
323 | +++ breezy/osutils.py 2024-04-02 23:21:37 +0000 |
324 | @@ -408,14 +408,6 @@ |
325 | normpath = _win32_normpath |
326 | getcwd = _win32_getcwd |
327 | rename = _rename_wrap_exception(_win32_rename) |
328 | - try: |
329 | - from . import _walkdirs_win32 |
330 | - except ImportError: |
331 | - pass |
332 | - else: |
333 | - lstat = _walkdirs_win32.lstat |
334 | - fstat = _walkdirs_win32.fstat |
335 | - wrap_stat = _walkdirs_win32.wrap_stat |
336 | |
337 | MIN_ABS_PATHLENGTH = 3 |
338 | |
339 | @@ -1728,11 +1720,7 @@ |
340 | if fs_enc is None: |
341 | fs_enc = sys.getfilesystemencoding() |
342 | if sys.platform == "win32": |
343 | - try: |
344 | - from ._walkdirs_win32 import Win32ReadDir |
345 | - _selected_dir_reader = Win32ReadDir() |
346 | - except ImportError: |
347 | - pass |
348 | + pass |
349 | elif fs_enc in ('utf-8', 'ascii'): |
350 | try: |
351 | from ._readdir_pyx import UTF8DirReader |
352 | |
353 | === modified file 'breezy/tests/__init__.py' |
354 | --- breezy/tests/__init__.py 2023-03-31 16:38:48 +0000 |
355 | +++ breezy/tests/__init__.py 2024-04-02 23:21:37 +0000 |
356 | @@ -3972,7 +3972,6 @@ |
357 | 'breezy.tests.per_workingtree', |
358 | 'breezy.tests.test__annotator', |
359 | 'breezy.tests.test__known_graph', |
360 | - 'breezy.tests.test__walkdirs_win32', |
361 | 'breezy.tests.test_ancestry', |
362 | 'breezy.tests.test_annotate', |
363 | 'breezy.tests.test_atomicfile', |
364 | |
365 | === removed file 'breezy/tests/test__walkdirs_win32.py' |
366 | --- breezy/tests/test__walkdirs_win32.py 2023-01-31 01:05:40 +0000 |
367 | +++ breezy/tests/test__walkdirs_win32.py 1970-01-01 00:00:00 +0000 |
368 | @@ -1,111 +0,0 @@ |
369 | -# Copyright (C) 2008, 2009, 2010 Canonical Ltd |
370 | -# |
371 | -# This program is free software; you can redistribute it and/or modify |
372 | -# it under the terms of the GNU General Public License as published by |
373 | -# the Free Software Foundation; either version 2 of the License, or |
374 | -# (at your option) any later version. |
375 | -# |
376 | -# This program is distributed in the hope that it will be useful, |
377 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
378 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
379 | -# GNU General Public License for more details. |
380 | -# |
381 | -# You should have received a copy of the GNU General Public License |
382 | -# along with this program; if not, write to the Free Software |
383 | -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
384 | - |
385 | -"""Tests for the win32 walkdir extension.""" |
386 | - |
387 | -import errno |
388 | - |
389 | -from .. import osutils, tests |
390 | -from . import features |
391 | - |
392 | -win32_readdir_feature = features.ModuleAvailableFeature( |
393 | - 'breezy._walkdirs_win32') |
394 | - |
395 | - |
396 | -class TestWin32Finder(tests.TestCaseInTempDir): |
397 | - |
398 | - _test_needs_features = [win32_readdir_feature] |
399 | - |
400 | - def setUp(self): |
401 | - super().setUp() |
402 | - from ._walkdirs_win32 import Win32ReadDir |
403 | - self.reader = Win32ReadDir() |
404 | - |
405 | - def _remove_stat_from_dirblock(self, dirblock): |
406 | - return [info[:3] + info[4:] for info in dirblock] |
407 | - |
408 | - def assertWalkdirs(self, expected, top, prefix=''): |
409 | - old_selected_dir_reader = osutils._selected_dir_reader |
410 | - try: |
411 | - osutils._selected_dir_reader = self.reader |
412 | - finder = osutils._walkdirs_utf8(top, prefix=prefix) |
413 | - result = [] |
414 | - for dirname, dirblock in finder: |
415 | - dirblock = self._remove_stat_from_dirblock(dirblock) |
416 | - result.append((dirname, dirblock)) |
417 | - self.assertEqual(expected, result) |
418 | - finally: |
419 | - osutils._selected_dir_reader = old_selected_dir_reader |
420 | - |
421 | - def assertReadDir(self, expected, prefix, top_unicode): |
422 | - result = self._remove_stat_from_dirblock( |
423 | - self.reader.read_dir(prefix, top_unicode)) |
424 | - self.assertEqual(expected, result) |
425 | - |
426 | - def test_top_prefix_to_starting_dir(self): |
427 | - # preparing an iteration should create a unicode native path. |
428 | - self.assertEqual( |
429 | - ('prefix', None, None, None, '\x12'), |
430 | - self.reader.top_prefix_to_starting_dir( |
431 | - '\x12'.encode(), 'prefix')) |
432 | - |
433 | - def test_empty_directory(self): |
434 | - self.assertReadDir([], 'prefix', '.') |
435 | - self.assertWalkdirs([(('', '.'), [])], '.') |
436 | - |
437 | - def test_file(self): |
438 | - self.build_tree(['foo']) |
439 | - self.assertReadDir([('foo', 'foo', 'file', './foo')], |
440 | - '', '.') |
441 | - |
442 | - def test_directory(self): |
443 | - self.build_tree(['bar/']) |
444 | - self.assertReadDir([('bar', 'bar', 'directory', './bar')], |
445 | - '', '.') |
446 | - |
447 | - def test_prefix(self): |
448 | - self.build_tree(['bar/', 'baf']) |
449 | - self.assertReadDir([ |
450 | - ('xxx/baf', 'baf', 'file', './baf'), |
451 | - ('xxx/bar', 'bar', 'directory', './bar'), |
452 | - ], |
453 | - 'xxx', '.') |
454 | - |
455 | - def test_missing_dir(self): |
456 | - e = self.assertRaises(WindowsError, |
457 | - self.reader.read_dir, 'prefix', 'no_such_dir') |
458 | - self.assertEqual(errno.ENOENT, e.errno) |
459 | - self.assertEqual(3, e.winerror) |
460 | - self.assertEqual((3, 'no_such_dir/*'), e.args) |
461 | - |
462 | - |
463 | -class Test_Win32Stat(tests.TestCaseInTempDir): |
464 | - |
465 | - _test_needs_features = [win32_readdir_feature] |
466 | - |
467 | - def setUp(self): |
468 | - super().setUp() |
469 | - from ._walkdirs_win32 import lstat |
470 | - self.win32_lstat = lstat |
471 | - |
472 | - def test_zero_members_present(self): |
473 | - self.build_tree(['foo']) |
474 | - st = self.win32_lstat('foo') |
475 | - # we only want to ensure that some members are present |
476 | - self.assertEqual(0, st.st_dev) |
477 | - self.assertEqual(0, st.st_ino) |
478 | - self.assertEqual(0, st.st_uid) |
479 | - self.assertEqual(0, st.st_gid) |
480 | |
481 | === modified file 'breezy/tests/test_osutils.py' |
482 | --- breezy/tests/test_osutils.py 2023-01-31 01:05:40 +0000 |
483 | +++ breezy/tests/test_osutils.py 2024-04-02 23:21:37 +0000 |
484 | @@ -26,7 +26,7 @@ |
485 | from io import BytesIO |
486 | |
487 | from .. import errors, osutils, tests, trace, win32utils |
488 | -from . import features, file_utils, test__walkdirs_win32 |
489 | +from . import features, file_utils |
490 | from .scenarios import load_tests_apply_scenarios |
491 | |
492 | |
493 | @@ -73,15 +73,6 @@ |
494 | dict(_dir_reader_class=_readdir_pyx.UTF8DirReader, |
495 | _native_to_unicode=_utf8_to_unicode))) |
496 | |
497 | - if test__walkdirs_win32.win32_readdir_feature.available(): |
498 | - try: |
499 | - from .. import _walkdirs_win32 |
500 | - scenarios.append( |
501 | - ('win32', |
502 | - dict(_dir_reader_class=_walkdirs_win32.Win32ReadDir, |
503 | - _native_to_unicode=_already_unicode))) |
504 | - except ModuleNotFoundError: |
505 | - pass |
506 | return scenarios |
507 | |
508 | |
509 | @@ -235,10 +226,7 @@ |
510 | # 'st_ino' and 'st_dev' fields. So we force them to be '0' in our |
511 | # custom implementation. |
512 | if sys.platform == 'win32': |
513 | - # We only have special lstat/fstat if we have the extension. |
514 | - # Without it, we may end up re-reading content when we don't have |
515 | - # to, but otherwise it doesn't effect correctness. |
516 | - self.requireFeature(test__walkdirs_win32.win32_readdir_feature) |
517 | + self.skipTest('lstat and fstat do not match on Windows') |
518 | with open('test-file.txt', 'wb') as f: |
519 | f.write(b'some content\n') |
520 | f.flush() |
521 | @@ -1242,13 +1230,6 @@ |
522 | self._save_platform_info() |
523 | self.assertDirReaderIs(osutils.UnicodeDirReader, ".", fs_enc='iso-8859-1') |
524 | |
525 | - def test_force_walkdirs_utf8_nt(self): |
526 | - # Disabled because the thunk of the whole walkdirs api is disabled. |
527 | - self.requireFeature(test__walkdirs_win32.win32_readdir_feature) |
528 | - self._save_platform_info() |
529 | - from .._walkdirs_win32 import Win32ReadDir |
530 | - self.assertDirReaderIs(Win32ReadDir, ".") |
531 | - |
532 | def test_unicode_walkdirs(self): |
533 | """Walkdirs should always return unicode paths.""" |
534 | self.requireFeature(features.UnicodeFilenameFeature) |
535 | @@ -1400,52 +1381,6 @@ |
536 | self._filter_out_stat(result) |
537 | self.assertEqual(expected_dirblocks, result) |
538 | |
539 | - def test__walkdirs_utf8_win32readdir(self): |
540 | - self.requireFeature(test__walkdirs_win32.win32_readdir_feature) |
541 | - self.requireFeature(features.UnicodeFilenameFeature) |
542 | - from .._walkdirs_win32 import Win32ReadDir |
543 | - self._save_platform_info() |
544 | - osutils._selected_dir_reader = Win32ReadDir() |
545 | - name0u = '0file-\xb6' |
546 | - name1u = '1dir-\u062c\u0648' |
547 | - name2u = '2file-\u0633' |
548 | - tree = [ |
549 | - name0u, |
550 | - name1u + '/', |
551 | - name1u + '/' + name0u, |
552 | - name1u + '/' + name1u + '/', |
553 | - name2u, |
554 | - ] |
555 | - self.build_tree(tree) |
556 | - name0 = name0u.encode('utf8') |
557 | - name1 = name1u.encode('utf8') |
558 | - name2 = name2u.encode('utf8') |
559 | - |
560 | - # All of the abspaths should be in unicode, all of the relative paths |
561 | - # should be in utf8 |
562 | - expected_dirblocks = [ |
563 | - (('', '.'), |
564 | - [(name0, name0, 'file', './' + name0u), |
565 | - (name1, name1, 'directory', './' + name1u), |
566 | - (name2, name2, 'file', './' + name2u), |
567 | - ] |
568 | - ), |
569 | - ((name1, './' + name1u), |
570 | - [(name1 + '/' + name0, name0, 'file', './' + name1u |
571 | - + '/' + name0u), |
572 | - (name1 + '/' + name1, name1, 'directory', './' + name1u |
573 | - + '/' + name1u), |
574 | - ] |
575 | - ), |
576 | - ((name1 + '/' + name1, './' + name1u + '/' + name1u), |
577 | - [ |
578 | - ] |
579 | - ), |
580 | - ] |
581 | - result = list(osutils._walkdirs_utf8('.')) |
582 | - self._filter_out_stat(result) |
583 | - self.assertEqual(expected_dirblocks, result) |
584 | - |
585 | def assertStatIsCorrect(self, path, win32stat): |
586 | os_stat = os.stat(path) |
587 | self.assertEqual(os_stat.st_size, win32stat.st_size) |
588 | @@ -1456,42 +1391,6 @@ |
589 | self.assertEqual(os_stat.st_ino, win32stat.st_ino) |
590 | self.assertEqual(os_stat.st_mode, win32stat.st_mode) |
591 | |
592 | - def test__walkdirs_utf_win32_find_file_stat_file(self): |
593 | - """make sure our Stat values are valid""" |
594 | - self.requireFeature(test__walkdirs_win32.win32_readdir_feature) |
595 | - self.requireFeature(features.UnicodeFilenameFeature) |
596 | - from .._walkdirs_win32 import Win32ReadDir |
597 | - name0u = '0file-\xb6' |
598 | - name0 = name0u.encode('utf8') |
599 | - self.build_tree([name0u]) |
600 | - # I hate to sleep() here, but I'm trying to make the ctime different |
601 | - # from the mtime |
602 | - time.sleep(2) |
603 | - with open(name0u, 'ab') as f: |
604 | - f.write(b'just a small update') |
605 | - |
606 | - result = Win32ReadDir().read_dir('', '.') |
607 | - entry = result[0] |
608 | - self.assertEqual((name0, name0, 'file'), entry[:3]) |
609 | - self.assertEqual('./' + name0u, entry[4]) |
610 | - self.assertStatIsCorrect(entry[4], entry[3]) |
611 | - self.assertNotEqual(entry[3].st_mtime, entry[3].st_ctime) |
612 | - |
613 | - def test__walkdirs_utf_win32_find_file_stat_directory(self): |
614 | - """make sure our Stat values are valid""" |
615 | - self.requireFeature(test__walkdirs_win32.win32_readdir_feature) |
616 | - self.requireFeature(features.UnicodeFilenameFeature) |
617 | - from .._walkdirs_win32 import Win32ReadDir |
618 | - name0u = '0dir-\u062c\u0648' |
619 | - name0 = name0u.encode('utf8') |
620 | - self.build_tree([name0u + '/']) |
621 | - |
622 | - result = Win32ReadDir().read_dir('', '.') |
623 | - entry = result[0] |
624 | - self.assertEqual((name0, name0, 'directory'), entry[:3]) |
625 | - self.assertEqual('./' + name0u, entry[4]) |
626 | - self.assertStatIsCorrect(entry[4], entry[3]) |
627 | - |
628 | def assertPathCompare(self, path_less, path_greater): |
629 | """check that path_less and path_greater compare correctly.""" |
630 | self.assertEqual(0, osutils.compare_paths_prefix_order( |
631 | |
632 | === modified file 'setup.py' |
633 | --- setup.py 2023-09-04 11:06:40 +0000 |
634 | +++ setup.py 2024-04-02 23:21:37 +0000 |
635 | @@ -172,7 +172,6 @@ |
636 | if sys.platform == 'win32': |
637 | add_cython_extension('breezy.bzr._dirstate_helpers_pyx', |
638 | libraries=['Ws2_32']) |
639 | - add_cython_extension('breezy._walkdirs_win32') |
640 | else: |
641 | add_cython_extension('breezy.bzr._dirstate_helpers_pyx') |
642 | add_cython_extension('breezy._readdir_pyx') |