# HG changeset patch # User Matt Harbison # Date 1670999523 18000 # Node ID 9cd327509cd44a4aeb2f7b69cd9548cb93d7b898 # Parent c43b283a19c3d3dc610677e0b1eafcae2dca03bc 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. diff -r c43b283a19c3 -r 9cd327509cd4 mercurial/pycompat.py --- a/mercurial/pycompat.py Tue Dec 13 16:48:47 2022 -0500 +++ b/mercurial/pycompat.py Wed Dec 14 01:32:03 2022 -0500 @@ -28,6 +28,10 @@ import tempfile import xmlrpc.client as xmlrpclib +from typing import ( + List, + Optional, +) ispy3 = sys.version_info[0] >= 3 ispypy = '__pypy__' in sys.builtin_module_names @@ -94,21 +98,17 @@ fsencode = os.fsencode fsdecode = os.fsdecode -oscurdir = os.curdir.encode('ascii') -oslinesep = os.linesep.encode('ascii') -osname = os.name.encode('ascii') -ospathsep = os.pathsep.encode('ascii') -ospardir = os.pardir.encode('ascii') -ossep = os.sep.encode('ascii') -osaltsep = os.altsep -if osaltsep: - osaltsep = osaltsep.encode('ascii') -osdevnull = os.devnull.encode('ascii') +oscurdir: bytes = os.curdir.encode('ascii') +oslinesep: bytes = os.linesep.encode('ascii') +osname: bytes = os.name.encode('ascii') +ospathsep: bytes = os.pathsep.encode('ascii') +ospardir: bytes = os.pardir.encode('ascii') +ossep: bytes = os.sep.encode('ascii') +osaltsep: Optional[bytes] = os.altsep.encode('ascii') if os.altsep else None +osdevnull: bytes = os.devnull.encode('ascii') -sysplatform = sys.platform.encode('ascii') -sysexecutable = sys.executable -if sysexecutable: - sysexecutable = os.fsencode(sysexecutable) +sysplatform: bytes = sys.platform.encode('ascii') +sysexecutable: bytes = os.fsencode(sys.executable) if sys.executable else b'' def maplist(*args): @@ -143,6 +143,7 @@ # (this is how Python 2 worked). To get that, we encode with the mbcs # encoding, which will pass CP_ACP to the underlying Windows API to # produce bytes. + sysargv: List[bytes] = [] if os.name == r'nt': sysargv = [a.encode("mbcs", "ignore") for a in sys.argv] else: @@ -377,12 +378,12 @@ json_loads = json.loads -isjython = sysplatform.startswith(b'java') +isjython: bool = sysplatform.startswith(b'java') -isdarwin = sysplatform.startswith(b'darwin') -islinux = sysplatform.startswith(b'linux') -isposix = osname == b'posix' -iswindows = osname == b'nt' +isdarwin: bool = sysplatform.startswith(b'darwin') +islinux: bool = sysplatform.startswith(b'linux') +isposix: bool = osname == b'posix' +iswindows: bool = osname == b'nt' def getoptb(args, shortlist, namelist):