Show More
@@ -187,6 +187,7 b' def debugsvnlog(ui, **opts):' | |||||
187 | """Fetch SVN log in a subprocess and channel them back to parent to |
|
187 | """Fetch SVN log in a subprocess and channel them back to parent to | |
188 | avoid memory collection issues. |
|
188 | avoid memory collection issues. | |
189 | """ |
|
189 | """ | |
|
190 | with util.with_lc_ctype(): | |||
190 | if svn is None: |
|
191 | if svn is None: | |
191 | raise error.Abort( |
|
192 | raise error.Abort( | |
192 | _(b'debugsvnlog could not load Subversion python bindings') |
|
193 | _(b'debugsvnlog could not load Subversion python bindings') | |
@@ -420,6 +421,7 b' class svn_source(converter_source):' | |||||
420 | self.url = geturl(url) |
|
421 | self.url = geturl(url) | |
421 | self.encoding = b'UTF-8' # Subversion is always nominal UTF-8 |
|
422 | self.encoding = b'UTF-8' # Subversion is always nominal UTF-8 | |
422 | try: |
|
423 | try: | |
|
424 | with util.with_lc_ctype(): | |||
423 | self.transport = transport.SvnRaTransport(url=self.url) |
|
425 | self.transport = transport.SvnRaTransport(url=self.url) | |
424 | self.ra = self.transport.ra |
|
426 | self.ra = self.transport.ra | |
425 | self.ctx = self.transport.client |
|
427 | self.ctx = self.transport.client | |
@@ -477,6 +479,7 b' class svn_source(converter_source):' | |||||
477 | ) |
|
479 | ) | |
478 |
|
480 | |||
479 | try: |
|
481 | try: | |
|
482 | with util.with_lc_ctype(): | |||
480 | self.head = self.latest(self.module, latest) |
|
483 | self.head = self.latest(self.module, latest) | |
481 | except SvnPathNotFound: |
|
484 | except SvnPathNotFound: | |
482 | self.head = None |
|
485 | self.head = None | |
@@ -494,6 +497,13 b' class svn_source(converter_source):' | |||||
494 | self.wc = None |
|
497 | self.wc = None | |
495 | self.convertfp = None |
|
498 | self.convertfp = None | |
496 |
|
499 | |||
|
500 | def before(self): | |||
|
501 | self.with_lc_ctype = util.with_lc_ctype() | |||
|
502 | self.with_lc_ctype.__enter__() | |||
|
503 | ||||
|
504 | def after(self): | |||
|
505 | self.with_lc_ctype.__exit__(None, None, None) | |||
|
506 | ||||
497 | def setrevmap(self, revmap): |
|
507 | def setrevmap(self, revmap): | |
498 | lastrevs = {} |
|
508 | lastrevs = {} | |
499 | for revid in revmap: |
|
509 | for revid in revmap: |
@@ -201,7 +201,6 b' except ImportError:' | |||||
201 | termios = None |
|
201 | termios = None | |
202 |
|
202 | |||
203 | import functools |
|
203 | import functools | |
204 | import locale |
|
|||
205 | import os |
|
204 | import os | |
206 | import struct |
|
205 | import struct | |
207 |
|
206 | |||
@@ -1711,10 +1710,7 b' def _chistedit(ui, repo, freeargs, opts)' | |||||
1711 | ctxs = [] |
|
1710 | ctxs = [] | |
1712 | for i, r in enumerate(revs): |
|
1711 | for i, r in enumerate(revs): | |
1713 | ctxs.append(histeditrule(ui, repo[r], i)) |
|
1712 | ctxs.append(histeditrule(ui, repo[r], i)) | |
1714 | # Curses requires setting the locale or it will default to the C |
|
1713 | with util.with_lc_ctype(): | |
1715 | # locale. This sets the locale to the user's default system |
|
|||
1716 | # locale. |
|
|||
1717 | locale.setlocale(locale.LC_ALL, '') |
|
|||
1718 | rc = curses.wrapper(functools.partial(_chisteditmain, repo, ctxs)) |
|
1714 | rc = curses.wrapper(functools.partial(_chisteditmain, repo, ctxs)) | |
1719 | curses.echo() |
|
1715 | curses.echo() | |
1720 | curses.endwin() |
|
1716 | curses.endwin() |
@@ -10,7 +10,6 b'' | |||||
10 |
|
10 | |||
11 | from __future__ import absolute_import |
|
11 | from __future__ import absolute_import | |
12 |
|
12 | |||
13 | import locale |
|
|||
14 | import os |
|
13 | import os | |
15 | import re |
|
14 | import re | |
16 | import signal |
|
15 | import signal | |
@@ -566,13 +565,11 b' def chunkselector(ui, headerlist, operat' | |||||
566 | """ |
|
565 | """ | |
567 | ui.write(_(b'starting interactive selection\n')) |
|
566 | ui.write(_(b'starting interactive selection\n')) | |
568 | chunkselector = curseschunkselector(headerlist, ui, operation) |
|
567 | chunkselector = curseschunkselector(headerlist, ui, operation) | |
569 | # This is required for ncurses to display non-ASCII characters in |
|
|||
570 | # default user locale encoding correctly. --immerrr |
|
|||
571 | locale.setlocale(locale.LC_ALL, '') |
|
|||
572 | origsigtstp = sentinel = object() |
|
568 | origsigtstp = sentinel = object() | |
573 | if util.safehasattr(signal, b'SIGTSTP'): |
|
569 | if util.safehasattr(signal, b'SIGTSTP'): | |
574 | origsigtstp = signal.getsignal(signal.SIGTSTP) |
|
570 | origsigtstp = signal.getsignal(signal.SIGTSTP) | |
575 | try: |
|
571 | try: | |
|
572 | with util.with_lc_ctype(): | |||
576 | curses.wrapper(chunkselector.main) |
|
573 | curses.wrapper(chunkselector.main) | |
577 | if chunkselector.initexc is not None: |
|
574 | if chunkselector.initexc is not None: | |
578 | raise chunkselector.initexc |
|
575 | raise chunkselector.initexc |
@@ -22,6 +22,7 b' import errno' | |||||
22 | import gc |
|
22 | import gc | |
23 | import hashlib |
|
23 | import hashlib | |
24 | import itertools |
|
24 | import itertools | |
|
25 | import locale | |||
25 | import mmap |
|
26 | import mmap | |
26 | import os |
|
27 | import os | |
27 | import platform as pyplatform |
|
28 | import platform as pyplatform | |
@@ -3596,3 +3597,32 b' def uvarintdecodestream(fh):' | |||||
3596 | if not (byte & 0x80): |
|
3597 | if not (byte & 0x80): | |
3597 | return result |
|
3598 | return result | |
3598 | shift += 7 |
|
3599 | shift += 7 | |
|
3600 | ||||
|
3601 | ||||
|
3602 | # Passing the '' locale means that the locale should be set according to the | |||
|
3603 | # user settings (environment variables). | |||
|
3604 | # Python sometimes avoids setting the global locale settings. When interfacing | |||
|
3605 | # with C code (e.g. the curses module or the Subversion bindings), the global | |||
|
3606 | # locale settings must be initialized correctly. Python 2 does not initialize | |||
|
3607 | # the global locale settings on interpreter startup. Python 3 sometimes | |||
|
3608 | # initializes LC_CTYPE, but not consistently at least on Windows. Therefore we | |||
|
3609 | # explicitly initialize it to get consistent behavior if it's not already | |||
|
3610 | # initialized. Since CPython commit 177d921c8c03d30daa32994362023f777624b10d, | |||
|
3611 | # LC_CTYPE is always initialized. If we require Python 3.8+, we should re-check | |||
|
3612 | # if we can remove this code. | |||
|
3613 | @contextlib.contextmanager | |||
|
3614 | def with_lc_ctype(): | |||
|
3615 | oldloc = locale.setlocale(locale.LC_CTYPE, None) | |||
|
3616 | if oldloc == 'C': | |||
|
3617 | try: | |||
|
3618 | try: | |||
|
3619 | locale.setlocale(locale.LC_CTYPE, '') | |||
|
3620 | except locale.Error: | |||
|
3621 | # The likely case is that the locale from the environment | |||
|
3622 | # variables is unknown. | |||
|
3623 | pass | |||
|
3624 | yield | |||
|
3625 | finally: | |||
|
3626 | locale.setlocale(locale.LC_CTYPE, oldloc) | |||
|
3627 | else: | |||
|
3628 | yield |
@@ -2069,7 +2069,7 b' class TTest(Test):' | |||||
2069 | if el.endswith(b" (esc)\n"): |
|
2069 | if el.endswith(b" (esc)\n"): | |
2070 | if PYTHON3: |
|
2070 | if PYTHON3: | |
2071 | el = el[:-7].decode('unicode_escape') + '\n' |
|
2071 | el = el[:-7].decode('unicode_escape') + '\n' | |
2072 |
el = el.encode(' |
|
2072 | el = el.encode('latin-1') | |
2073 | else: |
|
2073 | else: | |
2074 | el = el[:-7].decode('string-escape') + '\n' |
|
2074 | el = el[:-7].decode('string-escape') + '\n' | |
2075 | if el == l or os.name == 'nt' and el[:-1] + b'\r\n' == l: |
|
2075 | if el == l or os.name == 'nt' and el[:-1] + b'\r\n' == l: |
@@ -75,6 +75,16 b' Windows: \\r\\n is handled like \\n and can' | |||||
75 | crlf\r (esc) |
|
75 | crlf\r (esc) | |
76 | #endif |
|
76 | #endif | |
77 |
|
77 | |||
|
78 | Escapes: | |||
|
79 | ||||
|
80 | $ $PYTHON -c 'from mercurial.utils.procutil import stdout; stdout.write(b"\xff")' | |||
|
81 | \xff (no-eol) (esc) | |||
|
82 | ||||
|
83 | Escapes with conditions: | |||
|
84 | ||||
|
85 | $ $PYTHON -c 'from mercurial.utils.procutil import stdout; stdout.write(b"\xff")' | |||
|
86 | \xff (no-eol) (esc) (true !) | |||
|
87 | ||||
78 | Combining esc with other markups - and handling lines ending with \r instead of \n: |
|
88 | Combining esc with other markups - and handling lines ending with \r instead of \n: | |
79 |
|
89 | |||
80 | $ printf 'foo/bar\r' |
|
90 | $ printf 'foo/bar\r' |
General Comments 0
You need to be logged in to leave comments.
Login now