Skip to content

gh-85308: Add a parameter to argparse.ArgumentParser for file encoding #21444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion Doc/library/argparse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ ArgumentParser objects
formatter_class=argparse.HelpFormatter, \
prefix_chars='-', fromfile_prefix_chars=None, \
argument_default=None, conflict_handler='error', \
add_help=True, allow_abbrev=True, exit_on_error=True)
add_help=True, allow_abbrev=True, \
exit_on_error=True, fromfile_encoding=None)

Create a new :class:`ArgumentParser` object. All parameters should be passed
as keyword arguments. Each parameter has its own more detailed description
Expand Down Expand Up @@ -182,6 +183,9 @@ ArgumentParser objects
* exit_on_error_ - Determines whether or not ArgumentParser exits with
error info when an error occurs. (default: ``True``)

* fromfile_encoding_ - The encoding to use when reading files specified by
fromfile_prefix_chars_. (default: the system's default encoding)

.. versionchanged:: 3.5
*allow_abbrev* parameter was added.

Expand All @@ -192,6 +196,9 @@ ArgumentParser objects
.. versionchanged:: 3.9
*exit_on_error* parameter was added.

.. versionchanged:: 3.10
*fromfile_encoding* parameter was added.

The following sections describe how each of these are used.


Expand Down Expand Up @@ -675,6 +682,16 @@ If the user would like catch errors manually, the feature can be enable by setti
.. versionadded:: 3.9


fromfile_encoding
^^^^^^^^^^^^^^^^^

The ``fromfile_encoding=`` argument specifies the encoding to use when
reading files designated by fromfile_prefix_chars_. By default,
:class:`ArgumentParser` objects use the system's default encoding.

.. versionadded:: 3.10


The add_argument() method
-------------------------

Expand Down
9 changes: 7 additions & 2 deletions Lib/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1681,6 +1681,8 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
- allow_abbrev -- Allow long options to be abbreviated unambiguously
- exit_on_error -- Determines whether or not ArgumentParser exits with
error info when an error occurs
- fromfile_encoding -- The encoding to use when reading files
specified by fromfile_prefix_chars
"""

def __init__(self,
Expand All @@ -1696,7 +1698,8 @@ def __init__(self,
conflict_handler='error',
add_help=True,
allow_abbrev=True,
exit_on_error=True):
exit_on_error=True,
fromfile_encoding=None):

superinit = super(ArgumentParser, self).__init__
superinit(description=description,
Expand All @@ -1716,6 +1719,7 @@ def __init__(self,
self.add_help = add_help
self.allow_abbrev = allow_abbrev
self.exit_on_error = exit_on_error
self.fromfile_encoding = fromfile_encoding

add_group = self.add_argument_group
self._positionals = add_group(_('positional arguments'))
Expand Down Expand Up @@ -2118,7 +2122,8 @@ def _read_args_from_files(self, arg_strings):
# replace arguments referencing files with the file content
else:
try:
with open(arg_string[1:]) as args_file:
with open(arg_string[1:], encoding=self.fromfile_encoding) \
as args_file:
arg_strings = []
for arg_line in args_file.read().splitlines():
for arg in self.convert_arg_line_to_args(arg_line):
Expand Down
15 changes: 15 additions & 0 deletions Lib/test/test_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,21 @@ def setUp(self):
]


class TestArgumentsFromFileEncoding(TempDirMixin, ParserTestCase):
"""Test reading arguments from a file with fromfile_encoding"""

def setUp(self):
super().setUp()
with open('hello', 'w', encoding='utf-8') as f:
f.write('spœm\n')

parser_signature = Sig(fromfile_encoding='utf-8',
fromfile_prefix_chars='@')
argument_signatures = [Sig('y')]
failures = []
successes = [('@hello', NS(y='spœm'))]


class TestArgumentsFromFileConverter(TempDirMixin, ParserTestCase):
"""Test reading arguments from a file"""

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add a ``fromfile_encoding`` parameter to :class:`argparse.ArgumentParser` to
specify the file encoding when using the ``fromfile_prefix_chars`` option.