Show More
@@ -549,6 +549,41 class chgcmdserver(commandserver.server) | |||||
549 | except ValueError: |
|
549 | except ValueError: | |
550 | raise ValueError(b'unexpected value in setenv request') |
|
550 | raise ValueError(b'unexpected value in setenv request') | |
551 | self.ui.log(b'chgserver', b'setenv: %r\n', sorted(newenv.keys())) |
|
551 | self.ui.log(b'chgserver', b'setenv: %r\n', sorted(newenv.keys())) | |
|
552 | ||||
|
553 | # Python3 has some logic to "coerce" the C locale to a UTF-8 capable | |||
|
554 | # one, and it sets LC_CTYPE in the environment to C.UTF-8 if none of | |||
|
555 | # 'LC_CTYPE', 'LC_ALL' or 'LANG' are set (to any value). This can be | |||
|
556 | # disabled with PYTHONCOERCECLOCALE=0 in the environment. | |||
|
557 | # | |||
|
558 | # When fromui is called via _inithashstate, python has already set | |||
|
559 | # this, so that's in the environment right when we start up the hg | |||
|
560 | # process. Then chg will call us and tell us to set the environment to | |||
|
561 | # the one it has; this might NOT have LC_CTYPE, so we'll need to | |||
|
562 | # carry-forward the LC_CTYPE that was coerced in these situations. | |||
|
563 | # | |||
|
564 | # If this is not handled, we will fail config+env validation and fail | |||
|
565 | # to start chg. If this is just ignored instead of carried forward, we | |||
|
566 | # may have different behavior between chg and non-chg. | |||
|
567 | if pycompat.ispy3: | |||
|
568 | # Rename for wordwrapping purposes | |||
|
569 | oldenv = encoding.environ | |||
|
570 | if not any( | |||
|
571 | e.get(b'PYTHONCOERCECLOCALE') == b'0' for e in [oldenv, newenv] | |||
|
572 | ): | |||
|
573 | keys = [b'LC_CTYPE', b'LC_ALL', b'LANG'] | |||
|
574 | old_keys = [k for k, v in oldenv.items() if k in keys and v] | |||
|
575 | new_keys = [k for k, v in newenv.items() if k in keys and v] | |||
|
576 | # If the user's environment (from chg) doesn't have ANY of the | |||
|
577 | # keys that python looks for, and the environment (from | |||
|
578 | # initialization) has ONLY LC_CTYPE and it's set to C.UTF-8, | |||
|
579 | # carry it forward. | |||
|
580 | if ( | |||
|
581 | not new_keys | |||
|
582 | and old_keys == [b'LC_CTYPE'] | |||
|
583 | and oldenv[b'LC_CTYPE'] == b'C.UTF-8' | |||
|
584 | ): | |||
|
585 | newenv[b'LC_CTYPE'] = oldenv[b'LC_CTYPE'] | |||
|
586 | ||||
552 | encoding.environ.clear() |
|
587 | encoding.environ.clear() | |
553 | encoding.environ.update(newenv) |
|
588 | encoding.environ.update(newenv) | |
554 |
|
589 |
@@ -331,3 +331,25 check server log: | |||||
331 | YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached2 (in ...s) |
|
331 | YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached2 (in ...s) | |
332 | YYYY/MM/DD HH:MM:SS (PID)> log -R cached |
|
332 | YYYY/MM/DD HH:MM:SS (PID)> log -R cached | |
333 | YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in ...s) |
|
333 | YYYY/MM/DD HH:MM:SS (PID)> loaded repo into cache: $TESTTMP/cached (in ...s) | |
|
334 | ||||
|
335 | Test that chg works even when python "coerces" the locale (py3.7+, which is done | |||
|
336 | by default if none of LC_ALL, LC_CTYPE, or LANG are set in the environment) | |||
|
337 | ||||
|
338 | $ cat > $TESTTMP/debugenv.py <<EOF | |||
|
339 | > from mercurial import encoding | |||
|
340 | > from mercurial import registrar | |||
|
341 | > cmdtable = {} | |||
|
342 | > command = registrar.command(cmdtable) | |||
|
343 | > @command(b'debugenv', [], b'', norepo=True) | |||
|
344 | > def debugenv(ui): | |||
|
345 | > for k in [b'LC_ALL', b'LC_CTYPE', b'LANG']: | |||
|
346 | > v = encoding.environ.get(k) | |||
|
347 | > if v is not None: | |||
|
348 | > ui.write(b'%s=%s\n' % (k, encoding.environ[k])) | |||
|
349 | > EOF | |||
|
350 | $ LANG= LC_ALL= LC_CTYPE= chg \ | |||
|
351 | > --config extensions.debugenv=$TESTTMP/debugenv.py debugenv | |||
|
352 | LC_ALL= | |||
|
353 | LC_CTYPE=C.UTF-8 (py37 !) | |||
|
354 | LC_CTYPE= (no-py37 !) | |||
|
355 | LANG= |
General Comments 0
You need to be logged in to leave comments.
Login now