jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/418713 )
Change subject: tests/utils.py: Do not modify system language settings ......................................................................
tests/utils.py: Do not modify system language settings
Do not change system wide settings via `control.exe intl.cpl` call. (T189288)
This reverts changes of 07f3f168263b6ed2591e6db7a3898ddec2de3f21 in utils.py and config2.py. Only keeping the change of 'azb' to 'nn' in i18n_tests.py.
To change config.userinterface_lang in subprocesses use PYWIKIBOT_USERINTERFACE_LANG environment variable.
Bug: T189288 Bug: T189280 Bug: T128991 Change-Id: I8cf2d524963dc570ae03ed0d59af924f8fd86a3e --- M pywikibot/config2.py M tests/i18n_tests.py M tests/utils.py 3 files changed, 9 insertions(+), 183 deletions(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/config2.py b/pywikibot/config2.py index 1b42234..257b3ee 100644 --- a/pywikibot/config2.py +++ b/pywikibot/config2.py @@ -1081,8 +1081,6 @@ _modified = [_key for _key in _gl if _uc[_key] != globals()[_key] or _key in ('usernames', 'sysopnames', 'disambiguation_comment')] -# Retain the list of modified key names -__modified__ = _modified
if ('user_agent_format' in _modified): _right_user_agent_format = re.sub(r'{httplib2(:|})', r'{http_backend\1', @@ -1125,7 +1123,8 @@ 'path delimiter.')
if userinterface_lang is None: - userinterface_lang = getdefaultlocale()[0] + userinterface_lang = os.getenv('PYWIKIBOT_USERINTERFACE_LANG') \ + or getdefaultlocale()[0] if userinterface_lang in [None, 'C']: userinterface_lang = 'en' else: diff --git a/tests/i18n_tests.py b/tests/i18n_tests.py index 8b05058..6454bb8 100644 --- a/tests/i18n_tests.py +++ b/tests/i18n_tests.py @@ -368,10 +368,6 @@ @classmethod def setUpClass(cls): """Verify that a translation does not yet exist.""" - if 'userinterface_lang' in pywikibot.config.__modified__: - raise unittest.SkipTest( - 'user-config has a modified userinterface_lang') - super(InputTestCase, cls).setUpClass()
if cls.code in i18n.twget_keys(cls.message): @@ -380,13 +376,10 @@ % (cls.code, cls.message))
def test_pagegen_i18n_input(self): - """Test i18n.input fallback via pwb and LC_ALL.""" + """Test i18n.input fallback via pwb.""" expect = i18n.twtranslate(self.alt_code, self.message, fallback=False) - result = self._execute(args=['listpages', '-cat'], - data_in='non-existant-category\r\n', - timeout=20) - + data_in='non-existant-category\r\n') self.assertIn(expect, result['stderr'])
diff --git a/tests/utils.py b/tests/utils.py index 8ebce88..129f0eb 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -9,12 +9,10 @@
import inspect import json -import locale import os import re import subprocess import sys -import tempfile import time import traceback import warnings @@ -44,25 +42,11 @@
from tests import _pwb_py from tests import unittest -from tests import unittest_print
OSWIN32 = (sys.platform == 'win32')
PYTHON_26_CRYPTO_WARN = ('Python 2.6 is no longer supported by the Python core ' 'team, please upgrade your Python.') - -WIN32_LOCALE_UPDATE = """ -<gs:GlobalizationServices xmlns:gs="urn:longhornGlobalizationUnattend"> - gs:UserList - <gs:User UserID="Current" CopySettingsToDefaultUserAcct="true" - CopySettingsToSystemAcct="true"/> - </gs:UserList> - - gs:UserLocale - <gs:Locale Name="%s" SetAsCurrent="true" ResetAllSettings="false"/> - </gs:UserLocale> -</gs:GlobalizationServices> -"""
class DrySiteNote(RuntimeWarning): @@ -650,132 +634,6 @@ self._module.http = self._old_http
-def is_simple_locale_with_region(locale): - """Check if a locale is only an ISO and region code.""" - # Some locale are unicode names, which are not valid - try: - lang, sep, qualifier = locale.partition('_') - except UnicodeDecodeError: - return False - if '-' in lang: - return False - # Only allow qualifiers that look like a country code, without any suffix - if qualifier and len(qualifier) == 2: - return True - else: - return False - - -def get_simple_locales(): - """Get list of simple locales.""" - return [locale_code for locale_code in sorted(locale.locale_alias.keys()) - if is_simple_locale_with_region(locale_code)] - - -def generate_locale(lang, region=True, encoding='utf8'): - """ - Generate a locale string. - - @param lang: language code - @type lang: str - @param region: region code; if True, a random one will be used - @type region: str or True - @param encoding: encoding name - @type encoding: str - @rtype: str - """ - locale_prefix = lang + '_' - - if region is True: - locales = get_simple_locales() - - lang_locales = [code for code in locales - if code.startswith(locale_prefix)] - assert(lang_locales) - - # Get a region from the first locale - lang, sep, region = lang_locales[0].partition('_') - assert lang and sep and region - - if region: - locale_code = locale_prefix + region.upper() - else: - locale_code = lang - - if encoding: - locale_code += '.' + encoding - - return locale_code - - -def execute_with_temp_text_file(text, command, **kwargs): - """ - Perform command on a temporary file. - - @param text: contents of temporary file - @type text: str - @param command: command to execute with {0} replaced with the filename - @type command: str - @param kwargs: parameters for tempfile.mkstemp/tempfile.NamedTemporaryFile, - such as prefix, suffix and dir - """ - options = { - 'shell': True, - 'stdout': subprocess.PIPE, - 'stderr': subprocess.STDOUT, - } - - # NamedTemporaryFile does not work correctly with win32_set_global_locale - # subprocess.Popen is a context handler in Python 3.2+ - if OSWIN32 or PY2: - (fd, filename) = tempfile.mkstemp(text=True, **kwargs) - try: - os.close(fd) - with open(filename, 'wt') as f: - f.write(text) - - command = command.format(filename) - - p = subprocess.Popen(command, **options) - out = p.communicate()[0] - - # Python 2 raises an exception when attempting to close the process - # Python 3 does not allow the file to be removed until the process - # has been closed - if not PY2: - p.terminate() - finally: - try: - os.remove(filename) - except OSError: - # As it is a temporary file, the OS should clean it up - unittest_print('Could not delete {0}'.format(filename)) - else: - with tempfile.NamedTemporaryFile(mode='w+t', **kwargs) as f: - f.write(text) - f.flush() - command = command.format(f.name) - with subprocess.Popen(command, **options) as p: - out = p.communicate()[0] - - if out: - unittest_print('command "{0}" output: {1}'.format(command, out)) - - -def win32_set_global_locale(locale_code): - """Set global locale on win32.""" - locale_code = locale_code.split('.')[0] - win_locale_code = locale_code.replace('_', '-') - locale_update_xml = WIN32_LOCALE_UPDATE % win_locale_code - command = 'control.exe intl.cpl,,/f:"{0}"' - execute_with_temp_text_file(locale_update_xml, command, suffix='.xml') - - actual_code = locale.getdefaultlocale()[0] - assert locale_code == actual_code, \ - ('locale code {0} not set; actual code is {1}' - .format(locale_code, actual_code)) - - def execute(command, data_in=None, timeout=0, error=None): """ Execute a command and capture outputs. @@ -812,31 +670,11 @@ env[str('PYTHONPATH')] = pythonpath env[str('PYTHONIOENCODING')] = str(config.console_encoding)
- # LC_ALL is used by i18n.input as an alternative for userinterface_lang - # A complete locale string needs to be created, so the country code - # is guessed, however it is discarded when loading config. - if config.userinterface_lang: - current_locale = locale.getdefaultlocale()[0] - if current_locale in [None, 'C']: - current_locale = 'en' - else: - current_locale = current_locale.split('.')[0] - locale_prefix = str(config.userinterface_lang + '_') - - if not current_locale.startswith(locale_prefix): - locale_code = generate_locale( - config.userinterface_lang, - encoding=config.console_encoding) - - env[str('LC_ALL')] = str(locale_code) - - if OSWIN32: - # This is not multiprocessing safe, as it affects all processes - win32_set_global_locale(locale_code) - else: - current_locale = None - else: - current_locale = None + # PYWIKIBOT_USERINTERFACE_LANG will be assigned to + # config.userinterface_lang + if pywikibot.config.userinterface_lang: + env[str('PYWIKIBOT_USERINTERFACE_LANG')] = \ + str(pywikibot.config.userinterface_lang)
# Set EDITOR to an executable that ignores all arguments and does nothing. env[str('EDITOR')] = str('call' if OSWIN32 else 'true') @@ -894,10 +732,6 @@ stderr_lines += p.stderr.read()
data_out = p.communicate() - - if OSWIN32 and current_locale: - win32_set_global_locale(current_locale) - return {'exit_code': p.returncode, 'stdout': data_out[0].decode(config.console_encoding), 'stderr': (stderr_lines + data_out[1]).decode(config.console_encoding)}
pywikibot-commits@lists.wikimedia.org