]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-116850: Fix argparse for namespaces with not directly writable dict (GH...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 7 Oct 2024 21:27:11 +0000 (23:27 +0200)
committerGitHub <noreply@github.com>
Mon, 7 Oct 2024 21:27:11 +0000 (00:27 +0300)
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 95e92ef6c74e973ea13d15180190d0fa2af82fbf)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/argparse.py
Lib/test/test_argparse.py
Misc/NEWS.d/next/Library/2024-09-27-15-16-04.gh-issue-116850.dBkR0-.rst [new file with mode: 0644]

index ac08a809e93f2eb860973905dad6fa2d176a1ddf..5d6a065da9e6c518398e0d4668680b6944278da7 100644 (file)
@@ -1252,7 +1252,8 @@ class _SubParsersAction(Action):
             setattr(namespace, key, value)
 
         if arg_strings:
-            vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
+            if not hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):
+                setattr(namespace, _UNRECOGNIZED_ARGS_ATTR, [])
             getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)
 
 class _ExtendAction(_AppendAction):
index 18640a189430efd6fb59cbe7dfaf0e3ec7b4d73d..7a55dc2f941c6f50948c616817b8d1bddd5fead9 100644 (file)
@@ -2365,6 +2365,18 @@ class TestAddSubparsers(TestCase):
             (NS(foo=False, bar=0.5, w=7, x='b'), ['-W', '-X', 'Y', 'Z']),
         )
 
+    def test_parse_known_args_to_class_namespace(self):
+        class C:
+            pass
+        self.assertEqual(
+            self.parser.parse_known_args('0.5 1 b -w 7 -p'.split(), namespace=C),
+            (C, ['-p']),
+        )
+        self.assertIs(C.foo, False)
+        self.assertEqual(C.bar, 0.5)
+        self.assertEqual(C.w, 7)
+        self.assertEqual(C.x, 'b')
+
     def test_parse_known_args_with_single_dash_option(self):
         parser = ErrorRaisingArgumentParser()
         parser.add_argument('-k', '--known', action='count', default=0)
diff --git a/Misc/NEWS.d/next/Library/2024-09-27-15-16-04.gh-issue-116850.dBkR0-.rst b/Misc/NEWS.d/next/Library/2024-09-27-15-16-04.gh-issue-116850.dBkR0-.rst
new file mode 100644 (file)
index 0000000..62639a1
--- /dev/null
@@ -0,0 +1,2 @@
+Fix :mod:`argparse` for namespaces with not directly writable dict (e.g.
+classes).