comparison mercurial/utils/procutil.py @ 43077:687b865b95ad

formatting: byteify all mercurial/ and hgext/ string literals Done with python3.7 contrib/byteify-strings.py -i $(hg files 'set:mercurial/**.py - mercurial/thirdparty/** + hgext/**.py - hgext/fsmonitor/pywatchman/** - mercurial/__init__.py') black -l 80 -t py33 -S $(hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**" - hgext/fsmonitor/pywatchman/**') # skip-blame mass-reformatting only Differential Revision: https://phab.mercurial-scm.org/D6972
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:48:39 -0400
parents 2372284d9457
children eef9a2d67051
comparison
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
89 89
90 def explainexit(code): 90 def explainexit(code):
91 """return a message describing a subprocess status 91 """return a message describing a subprocess status
92 (codes from kill are negative - not os.system/wait encoding)""" 92 (codes from kill are negative - not os.system/wait encoding)"""
93 if code >= 0: 93 if code >= 0:
94 return _("exited with status %d") % code 94 return _(b"exited with status %d") % code
95 return _("killed by signal %d") % -code 95 return _(b"killed by signal %d") % -code
96 96
97 97
98 class _pfile(object): 98 class _pfile(object):
99 """File-like wrapper for a stream opened by subprocess.Popen()""" 99 """File-like wrapper for a stream opened by subprocess.Popen()"""
100 100
118 118
119 def __exit__(self, exc_type, exc_value, exc_tb): 119 def __exit__(self, exc_type, exc_value, exc_tb):
120 self.close() 120 self.close()
121 121
122 122
123 def popen(cmd, mode='rb', bufsize=-1): 123 def popen(cmd, mode=b'rb', bufsize=-1):
124 if mode == 'rb': 124 if mode == b'rb':
125 return _popenreader(cmd, bufsize) 125 return _popenreader(cmd, bufsize)
126 elif mode == 'wb': 126 elif mode == b'wb':
127 return _popenwriter(cmd, bufsize) 127 return _popenwriter(cmd, bufsize)
128 raise error.ProgrammingError('unsupported mode: %r' % mode) 128 raise error.ProgrammingError(b'unsupported mode: %r' % mode)
129 129
130 130
131 def _popenreader(cmd, bufsize): 131 def _popenreader(cmd, bufsize):
132 p = subprocess.Popen( 132 p = subprocess.Popen(
133 tonativestr(quotecommand(cmd)), 133 tonativestr(quotecommand(cmd)),
203 CMD is used as a template to create the real command to be run, 203 CMD is used as a template to create the real command to be run,
204 with the strings INFILE and OUTFILE replaced by the real names of 204 with the strings INFILE and OUTFILE replaced by the real names of
205 the temporary files generated.''' 205 the temporary files generated.'''
206 inname, outname = None, None 206 inname, outname = None, None
207 try: 207 try:
208 infd, inname = pycompat.mkstemp(prefix='hg-filter-in-') 208 infd, inname = pycompat.mkstemp(prefix=b'hg-filter-in-')
209 fp = os.fdopen(infd, r'wb') 209 fp = os.fdopen(infd, r'wb')
210 fp.write(s) 210 fp.write(s)
211 fp.close() 211 fp.close()
212 outfd, outname = pycompat.mkstemp(prefix='hg-filter-out-') 212 outfd, outname = pycompat.mkstemp(prefix=b'hg-filter-out-')
213 os.close(outfd) 213 os.close(outfd)
214 cmd = cmd.replace('INFILE', inname) 214 cmd = cmd.replace(b'INFILE', inname)
215 cmd = cmd.replace('OUTFILE', outname) 215 cmd = cmd.replace(b'OUTFILE', outname)
216 code = system(cmd) 216 code = system(cmd)
217 if pycompat.sysplatform == 'OpenVMS' and code & 1: 217 if pycompat.sysplatform == b'OpenVMS' and code & 1:
218 code = 0 218 code = 0
219 if code: 219 if code:
220 raise error.Abort( 220 raise error.Abort(
221 _("command '%s' failed: %s") % (cmd, explainexit(code)) 221 _(b"command '%s' failed: %s") % (cmd, explainexit(code))
222 ) 222 )
223 with open(outname, 'rb') as fp: 223 with open(outname, b'rb') as fp:
224 return fp.read() 224 return fp.read()
225 finally: 225 finally:
226 try: 226 try:
227 if inname: 227 if inname:
228 os.unlink(inname) 228 os.unlink(inname)
234 except OSError: 234 except OSError:
235 pass 235 pass
236 236
237 237
238 _filtertable = { 238 _filtertable = {
239 'tempfile:': tempfilter, 239 b'tempfile:': tempfilter,
240 'pipe:': pipefilter, 240 b'pipe:': pipefilter,
241 } 241 }
242 242
243 243
244 def filter(s, cmd): 244 def filter(s, cmd):
245 "filter a string through a command that transforms its input to its output" 245 b"filter a string through a command that transforms its input to its output"
246 for name, fn in _filtertable.iteritems(): 246 for name, fn in _filtertable.iteritems():
247 if cmd.startswith(name): 247 if cmd.startswith(name):
248 return fn(s, cmd[len(name) :].lstrip()) 248 return fn(s, cmd[len(name) :].lstrip())
249 return pipefilter(s, cmd) 249 return pipefilter(s, cmd)
250 250
254 254
255 The code supports py2exe (most common, Windows only) and tools/freeze 255 The code supports py2exe (most common, Windows only) and tools/freeze
256 (portable, not much used). 256 (portable, not much used).
257 """ 257 """
258 return ( 258 return (
259 pycompat.safehasattr(sys, "frozen") 259 pycompat.safehasattr(sys, b"frozen")
260 or pycompat.safehasattr(sys, "importers") # new py2exe 260 or pycompat.safehasattr(sys, b"importers") # new py2exe
261 or imp.is_frozen(r"__main__") # old py2exe 261 or imp.is_frozen(r"__main__") # old py2exe
262 ) # tools/freeze 262 ) # tools/freeze
263 263
264 264
265 _hgexecutable = None 265 _hgexecutable = None
269 """return location of the 'hg' executable. 269 """return location of the 'hg' executable.
270 270
271 Defaults to $HG or 'hg' in the search path. 271 Defaults to $HG or 'hg' in the search path.
272 """ 272 """
273 if _hgexecutable is None: 273 if _hgexecutable is None:
274 hg = encoding.environ.get('HG') 274 hg = encoding.environ.get(b'HG')
275 mainmod = sys.modules[r'__main__'] 275 mainmod = sys.modules[r'__main__']
276 if hg: 276 if hg:
277 _sethgexecutable(hg) 277 _sethgexecutable(hg)
278 elif mainfrozen(): 278 elif mainfrozen():
279 if getattr(sys, 'frozen', None) == 'macosx_app': 279 if getattr(sys, 'frozen', None) == b'macosx_app':
280 # Env variable set by py2app 280 # Env variable set by py2app
281 _sethgexecutable(encoding.environ['EXECUTABLEPATH']) 281 _sethgexecutable(encoding.environ[b'EXECUTABLEPATH'])
282 else: 282 else:
283 _sethgexecutable(pycompat.sysexecutable) 283 _sethgexecutable(pycompat.sysexecutable)
284 elif ( 284 elif (
285 not pycompat.iswindows 285 not pycompat.iswindows
286 and os.path.basename( 286 and os.path.basename(
287 pycompat.fsencode(getattr(mainmod, '__file__', '')) 287 pycompat.fsencode(getattr(mainmod, '__file__', b''))
288 ) 288 )
289 == 'hg' 289 == b'hg'
290 ): 290 ):
291 _sethgexecutable(pycompat.fsencode(mainmod.__file__)) 291 _sethgexecutable(pycompat.fsencode(mainmod.__file__))
292 else: 292 else:
293 _sethgexecutable( 293 _sethgexecutable(
294 findexe('hg') or os.path.basename(pycompat.sysargv[0]) 294 findexe(b'hg') or os.path.basename(pycompat.sysargv[0])
295 ) 295 )
296 return _hgexecutable 296 return _hgexecutable
297 297
298 298
299 def _sethgexecutable(path): 299 def _sethgexecutable(path):
354 354
355 def shellenviron(environ=None): 355 def shellenviron(environ=None):
356 """return environ with optional override, useful for shelling out""" 356 """return environ with optional override, useful for shelling out"""
357 357
358 def py2shell(val): 358 def py2shell(val):
359 'convert python object into string that is useful to shell' 359 b'convert python object into string that is useful to shell'
360 if val is None or val is False: 360 if val is None or val is False:
361 return '0' 361 return b'0'
362 if val is True: 362 if val is True:
363 return '1' 363 return b'1'
364 return pycompat.bytestr(val) 364 return pycompat.bytestr(val)
365 365
366 env = dict(encoding.environ) 366 env = dict(encoding.environ)
367 if environ: 367 if environ:
368 env.update((k, py2shell(v)) for k, v in environ.iteritems()) 368 env.update((k, py2shell(v)) for k, v in environ.iteritems())
369 env['HG'] = hgexecutable() 369 env[b'HG'] = hgexecutable()
370 return env 370 return env
371 371
372 372
373 if pycompat.iswindows: 373 if pycompat.iswindows:
374 374
418 env=tonativeenv(env), 418 env=tonativeenv(env),
419 cwd=pycompat.rapply(tonativestr, cwd), 419 cwd=pycompat.rapply(tonativestr, cwd),
420 stdout=subprocess.PIPE, 420 stdout=subprocess.PIPE,
421 stderr=subprocess.STDOUT, 421 stderr=subprocess.STDOUT,
422 ) 422 )
423 for line in iter(proc.stdout.readline, ''): 423 for line in iter(proc.stdout.readline, b''):
424 out.write(line) 424 out.write(line)
425 proc.wait() 425 proc.wait()
426 rc = proc.returncode 426 rc = proc.returncode
427 if pycompat.sysplatform == 'OpenVMS' and rc & 1: 427 if pycompat.sysplatform == b'OpenVMS' and rc & 1:
428 rc = 0 428 rc = 0
429 return rc 429 return rc
430 430
431 431
432 def gui(): 432 def gui():
433 '''Are we running in a GUI?''' 433 '''Are we running in a GUI?'''
434 if pycompat.isdarwin: 434 if pycompat.isdarwin:
435 if 'SSH_CONNECTION' in encoding.environ: 435 if b'SSH_CONNECTION' in encoding.environ:
436 # handle SSH access to a box where the user is logged in 436 # handle SSH access to a box where the user is logged in
437 return False 437 return False
438 elif getattr(osutil, 'isgui', None): 438 elif getattr(osutil, 'isgui', None):
439 # check if a CoreGraphics session is available 439 # check if a CoreGraphics session is available
440 return osutil.isgui() 440 return osutil.isgui()
441 else: 441 else:
442 # pure build; use a safe default 442 # pure build; use a safe default
443 return True 443 return True
444 else: 444 else:
445 return pycompat.iswindows or encoding.environ.get("DISPLAY") 445 return pycompat.iswindows or encoding.environ.get(b"DISPLAY")
446 446
447 447
448 def hgcmd(): 448 def hgcmd():
449 """Return the command used to execute current hg 449 """Return the command used to execute current hg
450 450
451 This is different from hgexecutable() because on Windows we want 451 This is different from hgexecutable() because on Windows we want
452 to avoid things opening new shell windows like batch files, so we 452 to avoid things opening new shell windows like batch files, so we
453 get either the python call or current executable. 453 get either the python call or current executable.
454 """ 454 """
455 if mainfrozen(): 455 if mainfrozen():
456 if getattr(sys, 'frozen', None) == 'macosx_app': 456 if getattr(sys, 'frozen', None) == b'macosx_app':
457 # Env variable set by py2app 457 # Env variable set by py2app
458 return [encoding.environ['EXECUTABLEPATH']] 458 return [encoding.environ[b'EXECUTABLEPATH']]
459 else: 459 else:
460 return [pycompat.sysexecutable] 460 return [pycompat.sysexecutable]
461 return _gethgcmd() 461 return _gethgcmd()
462 462
463 463
587 # doesn't seem worth adding that complexity here, though.) 587 # doesn't seem worth adding that complexity here, though.)
588 if returncode == 255: 588 if returncode == 255:
589 returncode = errno.EINVAL 589 returncode = errno.EINVAL
590 raise OSError( 590 raise OSError(
591 returncode, 591 returncode,
592 'error running %r: %s' % (cmd, os.strerror(returncode)), 592 b'error running %r: %s' % (cmd, os.strerror(returncode)),
593 ) 593 )
594 return 594 return
595 595
596 returncode = 255 596 returncode = 255
597 try: 597 try:
598 # Start a new session 598 # Start a new session
599 os.setsid() 599 os.setsid()
600 600
601 stdin = open(os.devnull, 'r') 601 stdin = open(os.devnull, b'r')
602 if stdout is None: 602 if stdout is None:
603 stdout = open(os.devnull, 'w') 603 stdout = open(os.devnull, b'w')
604 if stderr is None: 604 if stderr is None:
605 stderr = open(os.devnull, 'w') 605 stderr = open(os.devnull, b'w')
606 606
607 # connect stdin to devnull to make sure the subprocess can't 607 # connect stdin to devnull to make sure the subprocess can't
608 # muck up that stream for mercurial. 608 # muck up that stream for mercurial.
609 subprocess.Popen( 609 subprocess.Popen(
610 cmd, 610 cmd,