##// END OF EJS Templates
py3: use pycompat.getcwd instead of os.getcwd
Pulkit Goyal -
r30667:5861bdbe default
parent child Browse files
Show More
@@ -1,505 +1,508
1 1 # win32.py - utility functions that use win32 API
2 2 #
3 3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import ctypes
11 11 import errno
12 12 import msvcrt
13 13 import os
14 14 import random
15 15 import subprocess
16 16
17 from . import encoding
17 from . import (
18 encoding,
19 pycompat,
20 )
18 21
19 22 _kernel32 = ctypes.windll.kernel32
20 23 _advapi32 = ctypes.windll.advapi32
21 24 _user32 = ctypes.windll.user32
22 25
23 26 _BOOL = ctypes.c_long
24 27 _WORD = ctypes.c_ushort
25 28 _DWORD = ctypes.c_ulong
26 29 _UINT = ctypes.c_uint
27 30 _LONG = ctypes.c_long
28 31 _LPCSTR = _LPSTR = ctypes.c_char_p
29 32 _HANDLE = ctypes.c_void_p
30 33 _HWND = _HANDLE
31 34
32 35 _INVALID_HANDLE_VALUE = _HANDLE(-1).value
33 36
34 37 # GetLastError
35 38 _ERROR_SUCCESS = 0
36 39 _ERROR_NO_MORE_FILES = 18
37 40 _ERROR_INVALID_PARAMETER = 87
38 41 _ERROR_BROKEN_PIPE = 109
39 42 _ERROR_INSUFFICIENT_BUFFER = 122
40 43
41 44 # WPARAM is defined as UINT_PTR (unsigned type)
42 45 # LPARAM is defined as LONG_PTR (signed type)
43 46 if ctypes.sizeof(ctypes.c_long) == ctypes.sizeof(ctypes.c_void_p):
44 47 _WPARAM = ctypes.c_ulong
45 48 _LPARAM = ctypes.c_long
46 49 elif ctypes.sizeof(ctypes.c_longlong) == ctypes.sizeof(ctypes.c_void_p):
47 50 _WPARAM = ctypes.c_ulonglong
48 51 _LPARAM = ctypes.c_longlong
49 52
50 53 class _FILETIME(ctypes.Structure):
51 54 _fields_ = [('dwLowDateTime', _DWORD),
52 55 ('dwHighDateTime', _DWORD)]
53 56
54 57 class _BY_HANDLE_FILE_INFORMATION(ctypes.Structure):
55 58 _fields_ = [('dwFileAttributes', _DWORD),
56 59 ('ftCreationTime', _FILETIME),
57 60 ('ftLastAccessTime', _FILETIME),
58 61 ('ftLastWriteTime', _FILETIME),
59 62 ('dwVolumeSerialNumber', _DWORD),
60 63 ('nFileSizeHigh', _DWORD),
61 64 ('nFileSizeLow', _DWORD),
62 65 ('nNumberOfLinks', _DWORD),
63 66 ('nFileIndexHigh', _DWORD),
64 67 ('nFileIndexLow', _DWORD)]
65 68
66 69 # CreateFile
67 70 _FILE_SHARE_READ = 0x00000001
68 71 _FILE_SHARE_WRITE = 0x00000002
69 72 _FILE_SHARE_DELETE = 0x00000004
70 73
71 74 _OPEN_EXISTING = 3
72 75
73 76 _FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
74 77
75 78 # SetFileAttributes
76 79 _FILE_ATTRIBUTE_NORMAL = 0x80
77 80 _FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000
78 81
79 82 # Process Security and Access Rights
80 83 _PROCESS_QUERY_INFORMATION = 0x0400
81 84
82 85 # GetExitCodeProcess
83 86 _STILL_ACTIVE = 259
84 87
85 88 class _STARTUPINFO(ctypes.Structure):
86 89 _fields_ = [('cb', _DWORD),
87 90 ('lpReserved', _LPSTR),
88 91 ('lpDesktop', _LPSTR),
89 92 ('lpTitle', _LPSTR),
90 93 ('dwX', _DWORD),
91 94 ('dwY', _DWORD),
92 95 ('dwXSize', _DWORD),
93 96 ('dwYSize', _DWORD),
94 97 ('dwXCountChars', _DWORD),
95 98 ('dwYCountChars', _DWORD),
96 99 ('dwFillAttribute', _DWORD),
97 100 ('dwFlags', _DWORD),
98 101 ('wShowWindow', _WORD),
99 102 ('cbReserved2', _WORD),
100 103 ('lpReserved2', ctypes.c_char_p),
101 104 ('hStdInput', _HANDLE),
102 105 ('hStdOutput', _HANDLE),
103 106 ('hStdError', _HANDLE)]
104 107
105 108 class _PROCESS_INFORMATION(ctypes.Structure):
106 109 _fields_ = [('hProcess', _HANDLE),
107 110 ('hThread', _HANDLE),
108 111 ('dwProcessId', _DWORD),
109 112 ('dwThreadId', _DWORD)]
110 113
111 114 _CREATE_NO_WINDOW = 0x08000000
112 115 _SW_HIDE = 0
113 116
114 117 class _COORD(ctypes.Structure):
115 118 _fields_ = [('X', ctypes.c_short),
116 119 ('Y', ctypes.c_short)]
117 120
118 121 class _SMALL_RECT(ctypes.Structure):
119 122 _fields_ = [('Left', ctypes.c_short),
120 123 ('Top', ctypes.c_short),
121 124 ('Right', ctypes.c_short),
122 125 ('Bottom', ctypes.c_short)]
123 126
124 127 class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
125 128 _fields_ = [('dwSize', _COORD),
126 129 ('dwCursorPosition', _COORD),
127 130 ('wAttributes', _WORD),
128 131 ('srWindow', _SMALL_RECT),
129 132 ('dwMaximumWindowSize', _COORD)]
130 133
131 134 _STD_ERROR_HANDLE = _DWORD(-12).value
132 135
133 136 # CreateToolhelp32Snapshot, Process32First, Process32Next
134 137 _TH32CS_SNAPPROCESS = 0x00000002
135 138 _MAX_PATH = 260
136 139
137 140 class _tagPROCESSENTRY32(ctypes.Structure):
138 141 _fields_ = [('dwsize', _DWORD),
139 142 ('cntUsage', _DWORD),
140 143 ('th32ProcessID', _DWORD),
141 144 ('th32DefaultHeapID', ctypes.c_void_p),
142 145 ('th32ModuleID', _DWORD),
143 146 ('cntThreads', _DWORD),
144 147 ('th32ParentProcessID', _DWORD),
145 148 ('pcPriClassBase', _LONG),
146 149 ('dwFlags', _DWORD),
147 150 ('szExeFile', ctypes.c_char * _MAX_PATH)]
148 151
149 152 def __init__(self):
150 153 super(_tagPROCESSENTRY32, self).__init__()
151 154 self.dwsize = ctypes.sizeof(self)
152 155
153 156
154 157 # types of parameters of C functions used (required by pypy)
155 158
156 159 _kernel32.CreateFileA.argtypes = [_LPCSTR, _DWORD, _DWORD, ctypes.c_void_p,
157 160 _DWORD, _DWORD, _HANDLE]
158 161 _kernel32.CreateFileA.restype = _HANDLE
159 162
160 163 _kernel32.GetFileInformationByHandle.argtypes = [_HANDLE, ctypes.c_void_p]
161 164 _kernel32.GetFileInformationByHandle.restype = _BOOL
162 165
163 166 _kernel32.CloseHandle.argtypes = [_HANDLE]
164 167 _kernel32.CloseHandle.restype = _BOOL
165 168
166 169 try:
167 170 _kernel32.CreateHardLinkA.argtypes = [_LPCSTR, _LPCSTR, ctypes.c_void_p]
168 171 _kernel32.CreateHardLinkA.restype = _BOOL
169 172 except AttributeError:
170 173 pass
171 174
172 175 _kernel32.SetFileAttributesA.argtypes = [_LPCSTR, _DWORD]
173 176 _kernel32.SetFileAttributesA.restype = _BOOL
174 177
175 178 _kernel32.OpenProcess.argtypes = [_DWORD, _BOOL, _DWORD]
176 179 _kernel32.OpenProcess.restype = _HANDLE
177 180
178 181 _kernel32.GetExitCodeProcess.argtypes = [_HANDLE, ctypes.c_void_p]
179 182 _kernel32.GetExitCodeProcess.restype = _BOOL
180 183
181 184 _kernel32.GetLastError.argtypes = []
182 185 _kernel32.GetLastError.restype = _DWORD
183 186
184 187 _kernel32.GetModuleFileNameA.argtypes = [_HANDLE, ctypes.c_void_p, _DWORD]
185 188 _kernel32.GetModuleFileNameA.restype = _DWORD
186 189
187 190 _kernel32.CreateProcessA.argtypes = [_LPCSTR, _LPCSTR, ctypes.c_void_p,
188 191 ctypes.c_void_p, _BOOL, _DWORD, ctypes.c_void_p, _LPCSTR, ctypes.c_void_p,
189 192 ctypes.c_void_p]
190 193 _kernel32.CreateProcessA.restype = _BOOL
191 194
192 195 _kernel32.ExitProcess.argtypes = [_UINT]
193 196 _kernel32.ExitProcess.restype = None
194 197
195 198 _kernel32.GetCurrentProcessId.argtypes = []
196 199 _kernel32.GetCurrentProcessId.restype = _DWORD
197 200
198 201 _SIGNAL_HANDLER = ctypes.WINFUNCTYPE(_BOOL, _DWORD)
199 202 _kernel32.SetConsoleCtrlHandler.argtypes = [_SIGNAL_HANDLER, _BOOL]
200 203 _kernel32.SetConsoleCtrlHandler.restype = _BOOL
201 204
202 205 _kernel32.GetStdHandle.argtypes = [_DWORD]
203 206 _kernel32.GetStdHandle.restype = _HANDLE
204 207
205 208 _kernel32.GetConsoleScreenBufferInfo.argtypes = [_HANDLE, ctypes.c_void_p]
206 209 _kernel32.GetConsoleScreenBufferInfo.restype = _BOOL
207 210
208 211 _advapi32.GetUserNameA.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
209 212 _advapi32.GetUserNameA.restype = _BOOL
210 213
211 214 _user32.GetWindowThreadProcessId.argtypes = [_HANDLE, ctypes.c_void_p]
212 215 _user32.GetWindowThreadProcessId.restype = _DWORD
213 216
214 217 _user32.ShowWindow.argtypes = [_HANDLE, ctypes.c_int]
215 218 _user32.ShowWindow.restype = _BOOL
216 219
217 220 _WNDENUMPROC = ctypes.WINFUNCTYPE(_BOOL, _HWND, _LPARAM)
218 221 _user32.EnumWindows.argtypes = [_WNDENUMPROC, _LPARAM]
219 222 _user32.EnumWindows.restype = _BOOL
220 223
221 224 _kernel32.CreateToolhelp32Snapshot.argtypes = [_DWORD, _DWORD]
222 225 _kernel32.CreateToolhelp32Snapshot.restype = _BOOL
223 226
224 227 _kernel32.PeekNamedPipe.argtypes = [_HANDLE, ctypes.c_void_p, _DWORD,
225 228 ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
226 229 _kernel32.PeekNamedPipe.restype = _BOOL
227 230
228 231 _kernel32.Process32First.argtypes = [_HANDLE, ctypes.c_void_p]
229 232 _kernel32.Process32First.restype = _BOOL
230 233
231 234 _kernel32.Process32Next.argtypes = [_HANDLE, ctypes.c_void_p]
232 235 _kernel32.Process32Next.restype = _BOOL
233 236
234 237 def _raiseoserror(name):
235 238 err = ctypes.WinError()
236 239 raise OSError(err.errno, '%s: %s' % (name, err.strerror))
237 240
238 241 def _getfileinfo(name):
239 242 fh = _kernel32.CreateFileA(name, 0,
240 243 _FILE_SHARE_READ | _FILE_SHARE_WRITE | _FILE_SHARE_DELETE,
241 244 None, _OPEN_EXISTING, _FILE_FLAG_BACKUP_SEMANTICS, None)
242 245 if fh == _INVALID_HANDLE_VALUE:
243 246 _raiseoserror(name)
244 247 try:
245 248 fi = _BY_HANDLE_FILE_INFORMATION()
246 249 if not _kernel32.GetFileInformationByHandle(fh, ctypes.byref(fi)):
247 250 _raiseoserror(name)
248 251 return fi
249 252 finally:
250 253 _kernel32.CloseHandle(fh)
251 254
252 255 def oslink(src, dst):
253 256 try:
254 257 if not _kernel32.CreateHardLinkA(dst, src, None):
255 258 _raiseoserror(src)
256 259 except AttributeError: # Wine doesn't support this function
257 260 _raiseoserror(src)
258 261
259 262 def nlinks(name):
260 263 '''return number of hardlinks for the given file'''
261 264 return _getfileinfo(name).nNumberOfLinks
262 265
263 266 def samefile(path1, path2):
264 267 '''Returns whether path1 and path2 refer to the same file or directory.'''
265 268 res1 = _getfileinfo(path1)
266 269 res2 = _getfileinfo(path2)
267 270 return (res1.dwVolumeSerialNumber == res2.dwVolumeSerialNumber
268 271 and res1.nFileIndexHigh == res2.nFileIndexHigh
269 272 and res1.nFileIndexLow == res2.nFileIndexLow)
270 273
271 274 def samedevice(path1, path2):
272 275 '''Returns whether path1 and path2 are on the same device.'''
273 276 res1 = _getfileinfo(path1)
274 277 res2 = _getfileinfo(path2)
275 278 return res1.dwVolumeSerialNumber == res2.dwVolumeSerialNumber
276 279
277 280 def peekpipe(pipe):
278 281 handle = msvcrt.get_osfhandle(pipe.fileno())
279 282 avail = _DWORD()
280 283
281 284 if not _kernel32.PeekNamedPipe(handle, None, 0, None, ctypes.byref(avail),
282 285 None):
283 286 err = _kernel32.GetLastError()
284 287 if err == _ERROR_BROKEN_PIPE:
285 288 return 0
286 289 raise ctypes.WinError(err)
287 290
288 291 return avail.value
289 292
290 293 def testpid(pid):
291 294 '''return True if pid is still running or unable to
292 295 determine, False otherwise'''
293 296 h = _kernel32.OpenProcess(_PROCESS_QUERY_INFORMATION, False, pid)
294 297 if h:
295 298 try:
296 299 status = _DWORD()
297 300 if _kernel32.GetExitCodeProcess(h, ctypes.byref(status)):
298 301 return status.value == _STILL_ACTIVE
299 302 finally:
300 303 _kernel32.CloseHandle(h)
301 304 return _kernel32.GetLastError() != _ERROR_INVALID_PARAMETER
302 305
303 306 def executablepath():
304 307 '''return full path of hg.exe'''
305 308 size = 600
306 309 buf = ctypes.create_string_buffer(size + 1)
307 310 len = _kernel32.GetModuleFileNameA(None, ctypes.byref(buf), size)
308 311 if len == 0:
309 312 raise ctypes.WinError() # Note: WinError is a function
310 313 elif len == size:
311 314 raise ctypes.WinError(_ERROR_INSUFFICIENT_BUFFER)
312 315 return buf.value
313 316
314 317 def getuser():
315 318 '''return name of current user'''
316 319 size = _DWORD(300)
317 320 buf = ctypes.create_string_buffer(size.value + 1)
318 321 if not _advapi32.GetUserNameA(ctypes.byref(buf), ctypes.byref(size)):
319 322 raise ctypes.WinError()
320 323 return buf.value
321 324
322 325 _signalhandler = []
323 326
324 327 def setsignalhandler():
325 328 '''Register a termination handler for console events including
326 329 CTRL+C. python signal handlers do not work well with socket
327 330 operations.
328 331 '''
329 332 def handler(event):
330 333 _kernel32.ExitProcess(1)
331 334
332 335 if _signalhandler:
333 336 return # already registered
334 337 h = _SIGNAL_HANDLER(handler)
335 338 _signalhandler.append(h) # needed to prevent garbage collection
336 339 if not _kernel32.SetConsoleCtrlHandler(h, True):
337 340 raise ctypes.WinError()
338 341
339 342 def hidewindow():
340 343
341 344 def callback(hwnd, pid):
342 345 wpid = _DWORD()
343 346 _user32.GetWindowThreadProcessId(hwnd, ctypes.byref(wpid))
344 347 if pid == wpid.value:
345 348 _user32.ShowWindow(hwnd, _SW_HIDE)
346 349 return False # stop enumerating windows
347 350 return True
348 351
349 352 pid = _kernel32.GetCurrentProcessId()
350 353 _user32.EnumWindows(_WNDENUMPROC(callback), pid)
351 354
352 355 def termsize():
353 356 # cmd.exe does not handle CR like a unix console, the CR is
354 357 # counted in the line length. On 80 columns consoles, if 80
355 358 # characters are written, the following CR won't apply on the
356 359 # current line but on the new one. Keep room for it.
357 360 width = 80 - 1
358 361 height = 25
359 362 # Query stderr to avoid problems with redirections
360 363 screenbuf = _kernel32.GetStdHandle(
361 364 _STD_ERROR_HANDLE) # don't close the handle returned
362 365 if screenbuf is None or screenbuf == _INVALID_HANDLE_VALUE:
363 366 return width, height
364 367 csbi = _CONSOLE_SCREEN_BUFFER_INFO()
365 368 if not _kernel32.GetConsoleScreenBufferInfo(
366 369 screenbuf, ctypes.byref(csbi)):
367 370 return width, height
368 371 width = csbi.srWindow.Right - csbi.srWindow.Left # don't '+ 1'
369 372 height = csbi.srWindow.Bottom - csbi.srWindow.Top + 1
370 373 return width, height
371 374
372 375 def _1stchild(pid):
373 376 '''return the 1st found child of the given pid
374 377
375 378 None is returned when no child is found'''
376 379 pe = _tagPROCESSENTRY32()
377 380
378 381 # create handle to list all processes
379 382 ph = _kernel32.CreateToolhelp32Snapshot(_TH32CS_SNAPPROCESS, 0)
380 383 if ph == _INVALID_HANDLE_VALUE:
381 384 raise ctypes.WinError()
382 385 try:
383 386 r = _kernel32.Process32First(ph, ctypes.byref(pe))
384 387 # loop over all processes
385 388 while r:
386 389 if pe.th32ParentProcessID == pid:
387 390 # return first child found
388 391 return pe.th32ProcessID
389 392 r = _kernel32.Process32Next(ph, ctypes.byref(pe))
390 393 finally:
391 394 _kernel32.CloseHandle(ph)
392 395 if _kernel32.GetLastError() != _ERROR_NO_MORE_FILES:
393 396 raise ctypes.WinError()
394 397 return None # no child found
395 398
396 399 class _tochildpid(int): # pid is _DWORD, which always matches in an int
397 400 '''helper for spawndetached, returns the child pid on conversion to string
398 401
399 402 Does not resolve the child pid immediately because the child may not yet be
400 403 started.
401 404 '''
402 405 def childpid(self):
403 406 '''returns the child pid of the first found child of the process
404 407 with this pid'''
405 408 return _1stchild(self)
406 409 def __str__(self):
407 410 # run when the pid is written to the file
408 411 ppid = self.childpid()
409 412 if ppid is None:
410 413 # race, child has exited since check
411 414 # fall back to this pid. Its process will also have disappeared,
412 415 # raising the same error type later as when the child pid would
413 416 # be returned.
414 417 return " %d" % self
415 418 return str(ppid)
416 419
417 420 def spawndetached(args):
418 421 # No standard library function really spawns a fully detached
419 422 # process under win32 because they allocate pipes or other objects
420 423 # to handle standard streams communications. Passing these objects
421 424 # to the child process requires handle inheritance to be enabled
422 425 # which makes really detached processes impossible.
423 426 si = _STARTUPINFO()
424 427 si.cb = ctypes.sizeof(_STARTUPINFO)
425 428
426 429 pi = _PROCESS_INFORMATION()
427 430
428 431 env = ''
429 432 for k in encoding.environ:
430 433 env += "%s=%s\0" % (k, encoding.environ[k])
431 434 if not env:
432 435 env = '\0'
433 436 env += '\0'
434 437
435 438 args = subprocess.list2cmdline(args)
436 439 # Not running the command in shell mode makes Python 2.6 hang when
437 440 # writing to hgweb output socket.
438 441 comspec = encoding.environ.get("COMSPEC", "cmd.exe")
439 442 args = comspec + " /c " + args
440 443
441 444 res = _kernel32.CreateProcessA(
442 445 None, args, None, None, False, _CREATE_NO_WINDOW,
443 env, os.getcwd(), ctypes.byref(si), ctypes.byref(pi))
446 env, pycompat.getcwd(), ctypes.byref(si), ctypes.byref(pi))
444 447 if not res:
445 448 raise ctypes.WinError()
446 449
447 450 # _tochildpid because the process is the child of COMSPEC
448 451 return _tochildpid(pi.dwProcessId)
449 452
450 453 def unlink(f):
451 454 '''try to implement POSIX' unlink semantics on Windows'''
452 455
453 456 if os.path.isdir(f):
454 457 # use EPERM because it is POSIX prescribed value, even though
455 458 # unlink(2) on directories returns EISDIR on Linux
456 459 raise IOError(errno.EPERM,
457 460 "Unlinking directory not permitted: '%s'" % f)
458 461
459 462 # POSIX allows to unlink and rename open files. Windows has serious
460 463 # problems with doing that:
461 464 # - Calling os.unlink (or os.rename) on a file f fails if f or any
462 465 # hardlinked copy of f has been opened with Python's open(). There is no
463 466 # way such a file can be deleted or renamed on Windows (other than
464 467 # scheduling the delete or rename for the next reboot).
465 468 # - Calling os.unlink on a file that has been opened with Mercurial's
466 469 # posixfile (or comparable methods) will delay the actual deletion of
467 470 # the file for as long as the file is held open. The filename is blocked
468 471 # during that time and cannot be used for recreating a new file under
469 472 # that same name ("zombie file"). Directories containing such zombie files
470 473 # cannot be removed or moved.
471 474 # A file that has been opened with posixfile can be renamed, so we rename
472 475 # f to a random temporary name before calling os.unlink on it. This allows
473 476 # callers to recreate f immediately while having other readers do their
474 477 # implicit zombie filename blocking on a temporary name.
475 478
476 479 for tries in xrange(10):
477 480 temp = '%s-%08x' % (f, random.randint(0, 0xffffffff))
478 481 try:
479 482 os.rename(f, temp) # raises OSError EEXIST if temp exists
480 483 break
481 484 except OSError as e:
482 485 if e.errno != errno.EEXIST:
483 486 raise
484 487 else:
485 488 raise IOError(errno.EEXIST, "No usable temporary filename found")
486 489
487 490 try:
488 491 os.unlink(temp)
489 492 except OSError:
490 493 # The unlink might have failed because the READONLY attribute may heave
491 494 # been set on the original file. Rename works fine with READONLY set,
492 495 # but not os.unlink. Reset all attributes and try again.
493 496 _kernel32.SetFileAttributesA(temp, _FILE_ATTRIBUTE_NORMAL)
494 497 try:
495 498 os.unlink(temp)
496 499 except OSError:
497 500 # The unlink might have failed due to some very rude AV-Scanners.
498 501 # Leaking a tempfile is the lesser evil than aborting here and
499 502 # leaving some potentially serious inconsistencies.
500 503 pass
501 504
502 505 def makedir(path, notindexed):
503 506 os.mkdir(path)
504 507 if notindexed:
505 508 _kernel32.SetFileAttributesA(path, _FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)
@@ -1,53 +1,50
1 1 #require test-repo
2 2
3 3 $ . "$TESTDIR/helpers-testrepo.sh"
4 4 $ check_code="$TESTDIR"/../contrib/check-code.py
5 5 $ cd "$TESTDIR"/..
6 6
7 7 New errors are not allowed. Warnings are strongly discouraged.
8 8 (The writing "no-che?k-code" is for not skipping this file when checking.)
9 9
10 10 $ hg locate -X contrib/python-zstandard -X hgext/fsmonitor/pywatchman |
11 11 > sed 's-\\-/-g' | xargs "$check_code" --warnings --per-file=0 || false
12 12 Skipping i18n/polib.py it has no-che?k-code (glob)
13 13 mercurial/demandimport.py:309:
14 14 > if os.environ.get('HGDEMANDIMPORT') != 'disable':
15 15 use encoding.environ instead (py3)
16 16 mercurial/encoding.py:54:
17 17 > environ = os.environ
18 18 use encoding.environ instead (py3)
19 19 mercurial/encoding.py:56:
20 20 > environ = os.environb
21 21 use encoding.environ instead (py3)
22 22 mercurial/encoding.py:61:
23 23 > for k, v in os.environ.items())
24 24 use encoding.environ instead (py3)
25 25 mercurial/encoding.py:203:
26 26 > for k, v in os.environ.items())
27 27 use encoding.environ instead (py3)
28 28 Skipping mercurial/httpclient/__init__.py it has no-che?k-code (glob)
29 29 Skipping mercurial/httpclient/_readers.py it has no-che?k-code (glob)
30 30 mercurial/policy.py:45:
31 31 > policy = os.environ.get('HGMODULEPOLICY', policy)
32 32 use encoding.environ instead (py3)
33 33 Skipping mercurial/statprof.py it has no-che?k-code (glob)
34 mercurial/win32.py:443:
35 > env, os.getcwd(), ctypes.byref(si), ctypes.byref(pi))
36 use pycompat.getcwd instead (py3)
37 34 [1]
38 35
39 36 @commands in debugcommands.py should be in alphabetical order.
40 37
41 38 >>> import re
42 39 >>> commands = []
43 40 >>> with open('mercurial/debugcommands.py', 'rb') as fh:
44 41 ... for line in fh:
45 42 ... m = re.match("^@command\('([a-z]+)", line)
46 43 ... if m:
47 44 ... commands.append(m.group(1))
48 45 >>> scommands = list(sorted(commands))
49 46 >>> for i, command in enumerate(scommands):
50 47 ... if command != commands[i]:
51 48 ... print('commands in debugcommands.py not sorted; first differing '
52 49 ... 'command is %s; expected %s' % (commands[i], command))
53 50 ... break
General Comments 0
You need to be logged in to leave comments. Login now