# HG changeset patch # User Matt Harbison # Date 1607556076 18000 # Node ID 224af78021ded7bd4f051fed3e3ebb97b076718c # Parent 08fd76a553c966e78b5785b640d405c154081210 windows: continue looking at `%HOME%` for user config files with py3.8+ The `%HOME%` variable is explicitly called out in `hg help config` as a location that is consulted when reading user files, but python stopped looking at it when expanding '~' in py3.8+.[1] Restore that old functionality by copying in the old implementation (and simplifying it to just use bytes). It could be simplfied further, since only '~' is passed, but I'm not sure yet if we need to make this a generic utility function on Windows. There are other uses of `os.path.expanduser()`, but this is the only case I know of that documents `%HOME%` usage. (The reason for removing it was that it typically isn't set, but it actually is set in MSYS and PowerShell, and `%HOME%` and `%USERPROFILE%` are different in MSYS. I could be convinced to just replace all uses with this as a general utility, so we don't have to think too hard about BC.) [1] https://bugs.python.org/issue36264 Differential Revision: https://phab.mercurial-scm.org/D9559 diff -r 08fd76a553c9 -r 224af78021de mercurial/scmwindows.py --- a/mercurial/scmwindows.py Wed Dec 09 15:50:59 2020 -0500 +++ b/mercurial/scmwindows.py Wed Dec 09 18:21:16 2020 -0500 @@ -68,7 +68,7 @@ def userrcpath(): '''return os-specific hgrc search path to the user dir''' - home = os.path.expanduser(b'~') + home = _legacy_expanduser(b'~') path = [os.path.join(home, b'mercurial.ini'), os.path.join(home, b'.hgrc')] userprofile = encoding.environ.get(b'USERPROFILE') if userprofile and userprofile != home: @@ -77,5 +77,37 @@ return path +def _legacy_expanduser(path): + """Expand ~ and ~user constructs in the pre 3.8 style""" + + # Python 3.8+ changed the expansion of '~' from HOME to USERPROFILE. See + # https://bugs.python.org/issue36264. It also seems to capitalize the drive + # letter, as though it was processed through os.path.realpath(). + if not path.startswith(b'~'): + return path + + i, n = 1, len(path) + while i < n and path[i] not in b'\\/': + i += 1 + + if b'HOME' in encoding.environ: + userhome = encoding.environ[b'HOME'] + elif b'USERPROFILE' in encoding.environ: + userhome = encoding.environ[b'USERPROFILE'] + elif b'HOMEPATH' not in encoding.environ: + return path + else: + try: + drive = encoding.environ[b'HOMEDRIVE'] + except KeyError: + drive = b'' + userhome = os.path.join(drive, encoding.environ[b'HOMEPATH']) + + if i != 1: # ~user + userhome = os.path.join(os.path.dirname(userhome), path[1:i]) + + return userhome + path[i:] + + def termsize(ui): return win32.termsize()