| import codecs |
| import os |
| from gettext import gettext as _ |
| |
| |
| def _verify_python_env() -> None: |
| """Ensures that the environment is good for Unicode.""" |
| try: |
| from locale import getpreferredencoding |
| |
| fs_enc = codecs.lookup(getpreferredencoding()).name |
| except Exception: |
| fs_enc = "ascii" |
| |
| if fs_enc != "ascii": |
| return |
| |
| extra = [ |
| _( |
| "Click will abort further execution because Python was" |
| " configured to use ASCII as encoding for the environment." |
| " Consult https://click.palletsprojects.com/unicode-support/" |
| " for mitigation steps." |
| ) |
| ] |
| |
| if os.name == "posix": |
| import subprocess |
| |
| try: |
| rv = subprocess.Popen( |
| ["locale", "-a"], |
| stdout=subprocess.PIPE, |
| stderr=subprocess.PIPE, |
| encoding="ascii", |
| errors="replace", |
| ).communicate()[0] |
| except OSError: |
| rv = "" |
| |
| good_locales = set() |
| has_c_utf8 = False |
| |
| for line in rv.splitlines(): |
| locale = line.strip() |
| |
| if locale.lower().endswith((".utf-8", ".utf8")): |
| good_locales.add(locale) |
| |
| if locale.lower() in ("c.utf8", "c.utf-8"): |
| has_c_utf8 = True |
| |
| if not good_locales: |
| extra.append( |
| _( |
| "Additional information: on this system no suitable" |
| " UTF-8 locales were discovered. This most likely" |
| " requires resolving by reconfiguring the locale" |
| " system." |
| ) |
| ) |
| elif has_c_utf8: |
| extra.append( |
| _( |
| "This system supports the C.UTF-8 locale which is" |
| " recommended. You might be able to resolve your" |
| " issue by exporting the following environment" |
| " variables:" |
| ) |
| ) |
| extra.append(" export LC_ALL=C.UTF-8\n export LANG=C.UTF-8") |
| else: |
| extra.append( |
| _( |
| "This system lists some UTF-8 supporting locales" |
| " that you can pick from. The following suitable" |
| " locales were discovered: {locales}" |
| ).format(locales=", ".join(sorted(good_locales))) |
| ) |
| |
| bad_locale = None |
| |
| for env_locale in os.environ.get("LC_ALL"), os.environ.get("LANG"): |
| if env_locale and env_locale.lower().endswith((".utf-8", ".utf8")): |
| bad_locale = env_locale |
| |
| if env_locale is not None: |
| break |
| |
| if bad_locale is not None: |
| extra.append( |
| _( |
| "Click discovered that you exported a UTF-8 locale" |
| " but the locale system could not pick up from it" |
| " because it does not exist. The exported locale is" |
| " {locale!r} but it is not supported." |
| ).format(locale=bad_locale) |
| ) |
| |
| raise RuntimeError("\n\n".join(extra)) |