Skip to content

Commit

Permalink
add 'output.stdout', '.stdin', and '.stderr' options
Browse files Browse the repository at this point in the history
(#1621, #2152, #2529)

Allow setting custom input/output encodings and options
without having to rely on Python's defaults.
  • Loading branch information
mikf committed Feb 26, 2023
1 parent a70a3e5 commit e480a93
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 11 deletions.
36 changes: 36 additions & 0 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 2 additions & 3 deletions gallery_dl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down
32 changes: 24 additions & 8 deletions gallery_dl/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,16 +271,32 @@ def stderr_write(s):
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),
))


Expand Down

0 comments on commit e480a93

Please sign in to comment.