123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- import os
- import sys
- import codecs
- from ._compat import PY2
- # If someone wants to vendor click, we want to ensure the
- # correct package is discovered. Ideally we could use a
- # relative import here but unfortunately Python does not
- # support that.
- click = sys.modules[__name__.rsplit('.', 1)[0]]
- 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
- if not PY2 or click.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\n'
- 'locales were discovered. This most likely requires resolving\n'
- 'by reconfiguring the locale system.'
- )
- elif has_c_utf8:
- extra += (
- 'This system supports the C.UTF-8 locale which is recommended.\n'
- 'You might be able to resolve your issue by exporting the\n'
- '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\n'
- 'you can pick from. The following suitable locales were\n'
- 'discovered: %s'
- ) % ', '.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\n'
- 'but the locale system could not pick up from it because\n'
- 'it does not exist. The exported locale is "%s" but it\n'
- 'is not supported'
- ) % 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/en/7.x/python3/ for'
- ' mitigation steps.' + extra
- )
|