convert: set LC_CTYPE around calls to Subversion bindings
The Subversion bindings require that LC_CTYPE is set. However, we don’t want to
set it all the time, as it changes the behavior of str methods on Python 2. The
taken approach is hopefully fine-grained enough to not trigger any
locale-specfic behavior of the str methods and coarse-grained enough to not
clutter the code.
Emulating the with-statement behavior in before() and after() should be safe, as
after() is always called when before() is called. hgext.convert.hg takes a
similar approach.
--- a/hgext/convert/subversion.py Sun Jun 28 18:02:45 2020 +0200
+++ b/hgext/convert/subversion.py Sun Jun 28 18:02:45 2020 +0200
@@ -187,13 +187,14 @@
"""Fetch SVN log in a subprocess and channel them back to parent to
avoid memory collection issues.
"""
- if svn is None:
- raise error.Abort(
- _(b'debugsvnlog could not load Subversion python bindings')
- )
+ with util.with_lc_ctype():
+ if svn is None:
+ raise error.Abort(
+ _(b'debugsvnlog could not load Subversion python bindings')
+ )
- args = decodeargs(ui.fin.read())
- get_log_child(ui.fout, *args)
+ args = decodeargs(ui.fin.read())
+ get_log_child(ui.fout, *args)
class logstream(object):
@@ -420,18 +421,19 @@
self.url = geturl(url)
self.encoding = b'UTF-8' # Subversion is always nominal UTF-8
try:
- self.transport = transport.SvnRaTransport(url=self.url)
- self.ra = self.transport.ra
- self.ctx = self.transport.client
- self.baseurl = svn.ra.get_repos_root(self.ra)
- # Module is either empty or a repository path starting with
- # a slash and not ending with a slash.
- self.module = urlreq.unquote(self.url[len(self.baseurl) :])
- self.prevmodule = None
- self.rootmodule = self.module
- self.commits = {}
- self.paths = {}
- self.uuid = svn.ra.get_uuid(self.ra)
+ with util.with_lc_ctype():
+ self.transport = transport.SvnRaTransport(url=self.url)
+ self.ra = self.transport.ra
+ self.ctx = self.transport.client
+ self.baseurl = svn.ra.get_repos_root(self.ra)
+ # Module is either empty or a repository path starting with
+ # a slash and not ending with a slash.
+ self.module = urlreq.unquote(self.url[len(self.baseurl) :])
+ self.prevmodule = None
+ self.rootmodule = self.module
+ self.commits = {}
+ self.paths = {}
+ self.uuid = svn.ra.get_uuid(self.ra)
except svn.core.SubversionException:
ui.traceback()
svnversion = b'%d.%d.%d' % (
@@ -477,7 +479,8 @@
)
try:
- self.head = self.latest(self.module, latest)
+ with util.with_lc_ctype():
+ self.head = self.latest(self.module, latest)
except SvnPathNotFound:
self.head = None
if not self.head:
@@ -494,6 +497,13 @@
self.wc = None
self.convertfp = None
+ def before(self):
+ self.with_lc_ctype = util.with_lc_ctype()
+ self.with_lc_ctype.__enter__()
+
+ def after(self):
+ self.with_lc_ctype.__exit__(None, None, None)
+
def setrevmap(self, revmap):
lastrevs = {}
for revid in revmap: