add 'output.stdout', '.stdin', and '.stderr' options

(#1621, #2152, #2529)

Allow setting custom input/output encodings and options
without having to rely on Python's defaults.
pull/3713/head
Mike Fährmann 2 years ago
parent a70a3e5da6
commit e480a93337
No known key found for this signature in database
GPG Key ID: 5680CA389D365A88

@ -3808,6 +3808,42 @@ Description
* ``{3}`` is percent of bytes downloaded to total bytes
output.stdout & .stdin & .stderr
--------------------------------
Type
* ``string``
* ``object``
Example
.. code:: json
"utf-8"
.. code:: json
{
"encoding": "utf-8",
"errors": "replace",
"line_buffering": true
}
Description
`Reconfigure <https://docs.python.org/3/library/io.html#io.TextIOWrapper.reconfigure>`__
a `standard stream <https://docs.python.org/3/library/sys.html#sys.stdin>`__.
Possible options are
* ``encoding``
* ``errors``
* ``newline``
* ``line_buffering``
* ``write_through``
When this option is specified as a simple ``string``,
it is interpreted as ``{"encoding": "<string-value>", "errors": "replace"}``
Note: ``errors`` always defaults to ``"replace"``
output.shorten
--------------
Type

@ -33,9 +33,6 @@ def progress(urls, pformat):
def main():
try:
if sys.stdout and sys.stdout.encoding.lower() != "utf-8":
output.replace_std_streams()
parser = option.build_parser()
args = parser.parse_args()
log = output.initialize_logging(args.loglevel)
@ -77,6 +74,8 @@ def main():
for opts in args.options:
config.set(*opts)
output.configure_standard_streams()
# signals
signals = config.get((), "signals-ignore")
if signals:

@ -271,16 +271,32 @@ else:
stderr_write = stderr_write_flush
def replace_std_streams(errors="replace"):
"""Replace standard streams and set their error handlers to 'errors'"""
for name in ("stdout", "stdin", "stderr"):
stream = getattr(sys, name)
if stream:
def configure_standard_streams():
for name in ("stdout", "stderr", "stdin"):
options = config.get(("output",), name)
if not options:
continue
stream = getattr(sys, name, None)
if not stream:
continue
if isinstance(options, str):
options = {"encoding": options, "errors": "replace"}
elif not options.get("errors"):
options["errors"] = "replace"
try:
stream.reconfigure(**options)
except AttributeError:
# no 'reconfigure' support
oget = options.get
setattr(sys, name, stream.__class__(
stream.buffer,
errors=errors,
newline=stream.newlines,
line_buffering=stream.line_buffering,
encoding=oget("encoding", stream.encoding),
errors=oget("errors", "replace"),
newline=oget("newline", stream.newlines),
line_buffering=oget("line_buffering", stream.line_buffering),
))

Loading…
Cancel
Save