Skip to content

argparse _print_message silently fails with invalid file object #153967

Description

@ptim0626

Bug report

Bug description:

https://gist.github.com/devdanzin/3198710e3c0128fda5e0a7b4e0768e5f#6-_print_message-swallows-write-failures

When an invalid file object is passed to argparse.print_help or argparse.print_usage, the current behaviour does not raise any error, which is confusing as users may expect if no error is thrown, the usage text is successfully redirected. Consider the example below:

import argparse

p = argparse.ArgumentParser()
p.print_help(file="my/help.txt")
p.print_usage(file="my/usage.txt")

Both print_help and print_usage do not throw any error, and the users may think, for instance, passing the file path as a str, the help/usage message is written on that file, which is not the case.

The current behaviour was introduced 42f54d1 in #101802, where it does not error out when stderr is None with no explicit file argument. However if the users explicitly pass something to file, there is an expectation that the message will be redirected to file, and if the redirection fails, an error should be raised.

Expected behaviour

import argparse

p = argparse.ArgumentParser()
p.print_help(file="my/help.txt")

The above should raise an exception.

When stderr is None:

import argparse
import contextlib

p = argparse.ArgumentParser()
with contextlib.redirect_stderr(None):
    p.print_help(file="my/help.txt")

The above should also raise an exception as the user intentionally passes something (which is invalid). However if the user passes nothing:

import argparse
import contextlib

p = argparse.ArgumentParser()
with contextlib.redirect_stderr(None):
    p.print_help()

No exception should be raised and this keeps the behaviour backward compatible.

Proposal

Remove the try...except and check explicitly if file is a valid file object or not. If the file is valid, redirect the message to it; otherwise raise ValueError.

CPython versions tested on:

CPython main branch

Operating systems tested on:

macOS

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions