Comment 26 for bug 128496

Revision history for this message
Martin von Gagern (gagern) wrote :

> When wrapping, it shouldn't affect other parts of bzr, since we would change the locale before calling a svn function and then change it back afterwards. We also don't use threads.

While bzr the command line tool might not be using threads, there might well be multithreaded client applications using bzrlib. However, those should call setlocale themselves, if they can cope with it, or bzr shouldn't use locales either. At least in the C world that's the way things would be. Maybe you can achive the setlocale wrapping with a decorator that does nothing if the locale has been set to something different than C, the Posix default value.

> Hmm, I misunderstood the meaning of setlocale(LC_ALL, "") I think. I'll just wait for your patch to be merged upstream.

You don't want to use LC_ALL, because you can't reliably restor that to it's old value. Only use LC_CTYPE. setlocale(LC_CTYPE, "") sets the current encoding according to environment settings. setlocale(LC_CTYPE, None) simply queries the current value. The returned value is always the old value.

Together you could use this to build a decorator like this (untested):

if setlocale(LC_CTYPE, None) != 'C':
    need_setlocale = False
else:
    old_locale = setlocale(LC_CTYPE, '')
    need_setlocale = (setlocale(LC_CTYPE, old_locale) != 'C')

def setlocale_wrapper(unbound):
    if not need_setlocale:
        return unbound
    def wrapped(*args, **kwargs):
        old_locale = setlocale(LC_CTYPE, '')
        try:
            return unbound(*args, **kwargs)
        finally:
            setlocale(LC_CTYPE, old_locale)
    wrapped.__doc__ = unbound.__doc__
    wrapped.__name__ = unbound.__name__
    return wrapped