123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- import codecs
- import os
- import sys
- from ._compat import PY2
- def _find_unicode_literals_frame():
- import __future__
- if not hasattr(sys, "_getframe"): # not all Python implementations have it
- return 0
- frm = sys._getframe(1)
- idx = 1
- while frm is not None:
- if frm.f_globals.get("__name__", "").startswith("click."):
- frm = frm.f_back
- idx += 1
- elif frm.f_code.co_flags & __future__.unicode_literals.compiler_flag:
- return idx
- else:
- break
- return 0
- def _check_for_unicode_literals():
- if not __debug__:
- return
- from . import disable_unicode_literals_warning
- if not PY2 or disable_unicode_literals_warning:
- return
- bad_frame = _find_unicode_literals_frame()
- if bad_frame <= 0:
- return
- from warnings import warn
- warn(
- Warning(
- "Click detected the use of the unicode_literals __future__"
- " import. This is heavily discouraged because it can"
- " introduce subtle bugs in your code. You should instead"
- ' use explicit u"" literals for your unicode strings. For'
- " more information see"
- " https://click.palletsprojects.com/python3/"
- ),
- stacklevel=bad_frame,
- )
- def _verify_python3_env():
- """Ensures that the environment is good for unicode on Python 3."""
- if PY2:
- return
- try:
- import locale
- fs_enc = codecs.lookup(locale.getpreferredencoding()).name
- except Exception:
- fs_enc = "ascii"
- if fs_enc != "ascii":
- return
- extra = ""
- if os.name == "posix":
- import subprocess
- try:
- rv = subprocess.Popen(
- ["locale", "-a"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
- ).communicate()[0]
- except OSError:
- rv = b""
- good_locales = set()
- has_c_utf8 = False
- # Make sure we're operating on text here.
- if isinstance(rv, bytes):
- rv = rv.decode("ascii", "replace")
- 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
- extra += "\n\n"
- if not good_locales:
- extra += (
- "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 += (
- "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:\n\n"
- " export LC_ALL=C.UTF-8\n"
- " export LANG=C.UTF-8"
- )
- else:
- extra += (
- "This system lists a couple of UTF-8 supporting locales"
- " that you can pick from. The following suitable"
- " locales were discovered: {}".format(", ".join(sorted(good_locales)))
- )
- bad_locale = None
- for locale in os.environ.get("LC_ALL"), os.environ.get("LANG"):
- if locale and locale.lower().endswith((".utf-8", ".utf8")):
- bad_locale = locale
- if locale is not None:
- break
- if bad_locale is not None:
- extra += (
- "\n\nClick 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"
- " '{}' but it is not supported".format(bad_locale)
- )
- raise RuntimeError(
- "Click will abort further execution because Python 3 was"
- " configured to use ASCII as encoding for the environment."
- " Consult https://click.palletsprojects.com/python3/ for"
- " mitigation steps.{}".format(extra)
- )
|