mirror of https://github.com/ansible/ansible.git
ansible-test - Update locale logic to match core. (#78389)
Now that core requires UTF-8 filesystem encoding, ansible-test does as well. Additionally, the `en_US.UTF-8` or `C.UTF-8` encoding must be available. Previously the `en_US.UTF-8` encoding was requested, but its availability was never verified. The fallback to `C.UTF-8` maintains UTF-8 encoding while allowing more flexibility in the running environment.pull/78429/head
parent
27ce607a14
commit
d8fefba20e
@ -0,0 +1,16 @@
|
||||
major_changes:
|
||||
- ansible-test - At startup the filesystem encoding is checked to verify it is UTF-8.
|
||||
If not, the process exits with an error reporting the errant encoding.
|
||||
- ansible-test - At startup the locale is configured as ``en_US.UTF-8``, with a fallback to ``C.UTF-8``.
|
||||
If neither encoding is available the process exits with an error.
|
||||
If the fallback is used, a warning is displayed.
|
||||
In previous versions the ``en_US.UTF-8`` locale was always requested.
|
||||
However, no startup checking was performed to verify the locale was successfully configured.
|
||||
breaking_changes:
|
||||
- ansible-test - At startup the filesystem encoding is checked to verify it is UTF-8.
|
||||
If not, the process exits with an error reporting the errant encoding.
|
||||
- ansible-test - At startup the locale is configured as ``en_US.UTF-8``, with a fallback to ``C.UTF-8``.
|
||||
If neither encoding is available the process exits with an error.
|
||||
If the fallback is used, a warning is displayed.
|
||||
In previous versions the ``en_US.UTF-8`` locale was always requested.
|
||||
However, no startup checking was performed to verify the locale was successfully configured.
|
@ -0,0 +1,61 @@
|
||||
"""Initialize locale settings. This must be imported very early in ansible-test startup."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import locale
|
||||
import sys
|
||||
import typing as t
|
||||
|
||||
STANDARD_LOCALE = 'en_US.UTF-8'
|
||||
"""
|
||||
The standard locale used by ansible-test and its subprocesses and delegated instances.
|
||||
"""
|
||||
|
||||
FALLBACK_LOCALE = 'C.UTF-8'
|
||||
"""
|
||||
The fallback locale to use when the standard locale is not available.
|
||||
This was added in ansible-core 2.14 to allow testing in environments without the standard locale.
|
||||
It was not needed in previous ansible-core releases since they do not verify the locale during startup.
|
||||
"""
|
||||
|
||||
|
||||
class LocaleError(SystemExit):
|
||||
"""Exception to raise when locale related errors occur."""
|
||||
def __init__(self, message: str) -> None:
|
||||
super().__init__(f'ERROR: {message}')
|
||||
|
||||
|
||||
def configure_locale() -> t.Tuple[str, t.Optional[str]]:
|
||||
"""Configure the locale, returning the selected locale and an optional warning."""
|
||||
|
||||
if (fs_encoding := sys.getfilesystemencoding()).lower() != 'utf-8':
|
||||
raise LocaleError(f'ansible-test requires the filesystem encoding to be UTF-8, but "{fs_encoding}" was detected.')
|
||||
|
||||
candidate_locales = STANDARD_LOCALE, FALLBACK_LOCALE
|
||||
|
||||
errors: dict[str, str] = {}
|
||||
warning: t.Optional[str] = None
|
||||
configured_locale: t.Optional[str] = None
|
||||
|
||||
for candidate_locale in candidate_locales:
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, candidate_locale)
|
||||
locale.getlocale()
|
||||
except (locale.Error, ValueError) as ex:
|
||||
errors[candidate_locale] = str(ex)
|
||||
else:
|
||||
configured_locale = candidate_locale
|
||||
break
|
||||
|
||||
if not configured_locale:
|
||||
raise LocaleError('ansible-test could not initialize a supported locale:\n' +
|
||||
'\n'.join(f'{key}: {value}' for key, value in errors.items()))
|
||||
|
||||
if configured_locale != STANDARD_LOCALE:
|
||||
warning = (f'Using locale "{configured_locale}" instead of "{STANDARD_LOCALE}". '
|
||||
'Tests which depend on the locale may behave unexpectedly.')
|
||||
|
||||
return configured_locale, warning
|
||||
|
||||
|
||||
CONFIGURED_LOCALE, LOCALE_WARNING = configure_locale()
|
Loading…
Reference in New Issue