Skip to content

argparse: parse_args with a subparser + namespace tries to setdefault on a mappingproxy object #116850

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
alex-tianhuang opened this issue Mar 15, 2024 · 1 comment
Assignees
Labels
3.12 only security fixes 3.13 bugs and security fixes 3.14 bugs and security fixes type-bug An unexpected behavior, bug, or error

Comments

@alex-tianhuang
Copy link

alex-tianhuang commented Mar 15, 2024

Bug report

Bug description:

I was using the namespace argument in parse_args and found that argparse tries to setdefault on a mapping proxy when parsing unknown extra attributes:

import argparse


parser = argparse.ArgumentParser()
subparser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
subparsers.add_parser(name="sub", add_help=False)


class MyNamespace:
    pass


try:
    parser.parse_args(["sub", "oops"], namespace=MyNamespace)
except SystemExit:
    pass
Traceback (most recent call last):
File "<path_to_script>", line 16, in <module>
parser.parse_args(["sub", "oops"], namespace=MyNamespace)
File "<python_installation>/lib/python3.12/argparse.py", line 1891, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "<python_installation>/lib/python3.12/argparse.py", line 1924, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File "<python_installation>/lib/python3.12/argparse.py", line 2139, in _parse_known_args
stop_index = consume_positionals(start_index)
File "<python_installation>/lib/python3.12/argparse.py", line 2095, in consume_positionals
take_action(action, args)
File "<python_installation>/lib/python3.12/argparse.py", line 2000, in take_action
action(self, namespace, argument_values, option_string)
File "<python_installation>/lib/python3.12/argparse.py", line 1268, in call
vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
AttributeError: 'mappingproxy' object has no attribute 'setdefault'

I suspect this is because we're attempting to do vars(MyNamespace) instead of vars(argparse.Namespace) but I don't know much more than that.

I skimmed the top couple entries on the issue tracker with keywords 'argparse mappingproxy / argparse namespace' and found nothing, so I've decided that maybe nobody has reported this yet.

Using python 3.12.1 / argparse 1.1 / osx-arm64.

CPython versions tested on:

3.12

Operating systems tested on:

macOS

Linked PRs

@alex-tianhuang alex-tianhuang added the type-bug An unexpected behavior, bug, or error label Mar 15, 2024
@mimros
Copy link

mimros commented May 14, 2024

Hi, I had same issue. I think you have to create instance of your namespace class.

class MyNamespace:
    pass


try:
    my_namespace = MyNamespace() <---------------------------------------------
    parser.parse_args(["sub", "oops"], namespace=my_namespace)
except SystemExit:
    pass

https://docs.python.org/3/library/argparse.html#argparse.Namespace

serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this issue Sep 27, 2024
…le dict

It now always uses setattr() instead of setting the dict item to modify
the namespace. This allows to use a class as a namespace.
@serhiy-storchaka serhiy-storchaka self-assigned this Sep 28, 2024
serhiy-storchaka added a commit that referenced this issue Sep 29, 2024
GH-124667)

It now always uses setattr() instead of setting the dict item to modify
the namespace. This allows to use a class as a namespace.
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Sep 29, 2024
…le dict (pythonGH-124667)

It now always uses setattr() instead of setting the dict item to modify
the namespace. This allows to use a class as a namespace.
(cherry picked from commit 95e92ef)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Sep 29, 2024
…le dict (pythonGH-124667)

It now always uses setattr() instead of setting the dict item to modify
the namespace. This allows to use a class as a namespace.
(cherry picked from commit 95e92ef)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
@github-project-automation github-project-automation bot moved this to Doc issues in Argparse issues Sep 29, 2024
@serhiy-storchaka serhiy-storchaka added 3.12 only security fixes 3.13 bugs and security fixes 3.14 bugs and security fixes labels Sep 29, 2024
serhiy-storchaka added a commit that referenced this issue Sep 29, 2024
…ble dict (GH-124667) (GH-124758)

It now always uses setattr() instead of setting the dict item to modify
the namespace. This allows to use a class as a namespace.
(cherry picked from commit 95e92ef)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
serhiy-storchaka added a commit that referenced this issue Oct 7, 2024
…ble dict (GH-124667) (GH-124757)

It now always uses setattr() instead of setting the dict item to modify
the namespace. This allows to use a class as a namespace.
(cherry picked from commit 95e92ef)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.12 only security fixes 3.13 bugs and security fixes 3.14 bugs and security fixes type-bug An unexpected behavior, bug, or error
Projects
Status: Doc issues
Development

No branches or pull requests

3 participants