comparison mercurial/pycompat.py @ 49801:9cd327509cd4

typing: add type hints to global variables in mercurial/pycompat.py The way `osaltsep` and `sysexecutable` were defined, pytype determined them to be `Union[bytes, str]`. This was a problem because that cascaded to all of the callers, and also because it couldn't be annotated as bytes on the initial assignment. Therefore, we use a ternary operator. The documentation says that `sys.executable` can either be None or an empty string if the value couldn't be determined. We opt for an empty string here because there are places that blindly pass it to `os.path.xxx()` functions, which crash if given None. Other places test `if pycompat.sysexecutable`, so empty string works for both.
author Matt Harbison <matt_harbison@yahoo.com>
date Wed, 14 Dec 2022 01:32:03 -0500
parents e45c39273395
children f3f33980f19b
comparison
equal deleted inserted replaced
49800:c43b283a19c3 49801:9cd327509cd4
26 import struct 26 import struct
27 import sys 27 import sys
28 import tempfile 28 import tempfile
29 import xmlrpc.client as xmlrpclib 29 import xmlrpc.client as xmlrpclib
30 30
31 from typing import (
32 List,
33 Optional,
34 )
31 35
32 ispy3 = sys.version_info[0] >= 3 36 ispy3 = sys.version_info[0] >= 3
33 ispypy = '__pypy__' in sys.builtin_module_names 37 ispypy = '__pypy__' in sys.builtin_module_names
34 TYPE_CHECKING = False 38 TYPE_CHECKING = False
35 39
92 # This must be set once prior to any fsencode/fsdecode calls. 96 # This must be set once prior to any fsencode/fsdecode calls.
93 sys._enablelegacywindowsfsencoding() # pytype: disable=module-attr 97 sys._enablelegacywindowsfsencoding() # pytype: disable=module-attr
94 98
95 fsencode = os.fsencode 99 fsencode = os.fsencode
96 fsdecode = os.fsdecode 100 fsdecode = os.fsdecode
97 oscurdir = os.curdir.encode('ascii') 101 oscurdir: bytes = os.curdir.encode('ascii')
98 oslinesep = os.linesep.encode('ascii') 102 oslinesep: bytes = os.linesep.encode('ascii')
99 osname = os.name.encode('ascii') 103 osname: bytes = os.name.encode('ascii')
100 ospathsep = os.pathsep.encode('ascii') 104 ospathsep: bytes = os.pathsep.encode('ascii')
101 ospardir = os.pardir.encode('ascii') 105 ospardir: bytes = os.pardir.encode('ascii')
102 ossep = os.sep.encode('ascii') 106 ossep: bytes = os.sep.encode('ascii')
103 osaltsep = os.altsep 107 osaltsep: Optional[bytes] = os.altsep.encode('ascii') if os.altsep else None
104 if osaltsep: 108 osdevnull: bytes = os.devnull.encode('ascii')
105 osaltsep = osaltsep.encode('ascii') 109
106 osdevnull = os.devnull.encode('ascii') 110 sysplatform: bytes = sys.platform.encode('ascii')
107 111 sysexecutable: bytes = os.fsencode(sys.executable) if sys.executable else b''
108 sysplatform = sys.platform.encode('ascii')
109 sysexecutable = sys.executable
110 if sysexecutable:
111 sysexecutable = os.fsencode(sysexecutable)
112 112
113 113
114 def maplist(*args): 114 def maplist(*args):
115 return list(map(*args)) 115 return list(map(*args))
116 116
141 # ANSI codepage representation of the arguments, as this is what 141 # ANSI codepage representation of the arguments, as this is what
142 # `int main()` would receive if Python 3 didn't define `int wmain()` 142 # `int main()` would receive if Python 3 didn't define `int wmain()`
143 # (this is how Python 2 worked). To get that, we encode with the mbcs 143 # (this is how Python 2 worked). To get that, we encode with the mbcs
144 # encoding, which will pass CP_ACP to the underlying Windows API to 144 # encoding, which will pass CP_ACP to the underlying Windows API to
145 # produce bytes. 145 # produce bytes.
146 sysargv: List[bytes] = []
146 if os.name == r'nt': 147 if os.name == r'nt':
147 sysargv = [a.encode("mbcs", "ignore") for a in sys.argv] 148 sysargv = [a.encode("mbcs", "ignore") for a in sys.argv]
148 else: 149 else:
149 sysargv = [fsencode(a) for a in sys.argv] 150 sysargv = [fsencode(a) for a in sys.argv]
150 151
375 iteritems = lambda x: x.items() 376 iteritems = lambda x: x.items()
376 itervalues = lambda x: x.values() 377 itervalues = lambda x: x.values()
377 378
378 json_loads = json.loads 379 json_loads = json.loads
379 380
380 isjython = sysplatform.startswith(b'java') 381 isjython: bool = sysplatform.startswith(b'java')
381 382
382 isdarwin = sysplatform.startswith(b'darwin') 383 isdarwin: bool = sysplatform.startswith(b'darwin')
383 islinux = sysplatform.startswith(b'linux') 384 islinux: bool = sysplatform.startswith(b'linux')
384 isposix = osname == b'posix' 385 isposix: bool = osname == b'posix'
385 iswindows = osname == b'nt' 386 iswindows: bool = osname == b'nt'
386 387
387 388
388 def getoptb(args, shortlist, namelist): 389 def getoptb(args, shortlist, namelist):
389 return _getoptbwrapper(getopt.getopt, args, shortlist, namelist) 390 return _getoptbwrapper(getopt.getopt, args, shortlist, namelist)
390 391