|
|
- # coding: utf-8
- #
- # Copyright © 2010—2014 Andrey Mikhaylenko and contributors
- #
- # This file is part of Argh.
- #
- # Argh is free software under terms of the GNU Lesser
- # General Public License version 3 (LGPLv3) as published by the Free
- # Software Foundation. See the file README.rst for copying conditions.
- #
- """
- Output Processing
- ~~~~~~~~~~~~~~~~~
- """
- import locale
- import sys
-
- from argh import compat
-
-
- __all__ = ['dump', 'encode_output', 'safe_input']
-
-
- def _input(prompt):
- # this function can be mocked up in tests
- if sys.version_info < (3,0):
- return raw_input(prompt)
- else:
- return input(prompt)
-
-
- def safe_input(prompt):
- """
- Prompts user for input. Correctly handles prompt message encoding.
- """
-
- if sys.version_info < (3,0):
- if isinstance(prompt, compat.text_type):
- # Python 2.x: unicode → bytes
- encoding = locale.getpreferredencoding() or 'utf-8'
- prompt = prompt.encode(encoding)
- else:
- if not isinstance(prompt, compat.text_type):
- # Python 3.x: bytes → unicode
- prompt = prompt.decode()
-
- return _input(prompt)
-
-
- def encode_output(value, output_file):
- """
- Encodes given value so it can be written to given file object.
-
- Value may be Unicode, binary string or any other data type.
-
- The exact behaviour depends on the Python version:
-
- Python 3.x
-
- `sys.stdout` is a `_io.TextIOWrapper` instance that accepts `str`
- (unicode) and breaks on `bytes`.
-
- It is OK to simply assume that everything is Unicode unless special
- handling is introduced in the client code.
-
- Thus, no additional processing is performed.
-
- Python 2.x
-
- `sys.stdout` is a file-like object that accepts `str` (bytes)
- and breaks when `unicode` is passed to `sys.stdout.write()`.
-
- We can expect both Unicode and bytes. They need to be encoded so as
- to match the file object encoding.
-
- The output is binary if the object doesn't explicitly require Unicode.
-
- """
- if sys.version_info > (3,0):
- # Python 3: whatever → unicode
- return compat.text_type(value)
- else:
- # Python 2: handle special cases
- stream_encoding = getattr(output_file, 'encoding', None)
- if stream_encoding:
- if stream_encoding.upper() == 'UTF-8':
- return compat.text_type(value)
- else:
- return value.encode(stream_encoding, 'ignore')
- else:
- # no explicit encoding requirements; force binary
- if isinstance(value, compat.text_type):
- # unicode → binary
- return value.encode('utf-8')
- else:
- return str(value)
-
-
- def dump(raw_data, output_file):
- """
- Writes given line to given output file.
- See :func:`encode_output` for details.
- """
- data = encode_output(raw_data, output_file)
- output_file.write(data)
|