Skip to content

Commit 64e4a59

Browse files
gh-155044: Support copy.replace() for optparse.Values
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 7d76013 commit 64e4a59

4 files changed

Lines changed: 20 additions & 0 deletions

File tree

Doc/library/optparse.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,12 @@ As you can see, most actions involve storing or updating a value somewhere.
10731073
and can be overridden by a custom subclass passed to the *values* argument of
10741074
:meth:`OptionParser.parse_args` (as described in :ref:`optparse-parsing-arguments`).
10751075

1076+
:class:`!Values` objects support :func:`copy.replace`,
1077+
which returns a copy of the object with the specified attributes replaced.
1078+
1079+
.. versionchanged:: next
1080+
Added support of :func:`copy.replace`.
1081+
10761082
Option
10771083
arguments (and various other values) are stored as attributes of this object,
10781084
according to the :attr:`~Option.dest` (destination) option attribute.

Lib/optparse.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,12 @@ def __eq__(self, other):
830830
else:
831831
return NotImplemented
832832

833+
def __replace__(self, /, **changes):
834+
new = self.__class__()
835+
new.__dict__.update(self.__dict__)
836+
new.__dict__.update(changes)
837+
return new
838+
833839
def _update_careful(self, dict):
834840
"""
835841
Update the option values from an arbitrary dictionary, but only

Lib/test/test_optparse.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,13 @@ def test_basics(self):
434434
self.assertNotEqual(values, "")
435435
self.assertNotEqual(values, [])
436436

437+
def test_replace(self):
438+
values = Values(defaults={"foo": "bar", "baz": 42})
439+
new = copy.replace(values, baz=43, spam="eggs")
440+
self.assertIsInstance(new, Values)
441+
self.assertEqual(vars(new), {"foo": "bar", "baz": 43, "spam": "eggs"})
442+
self.assertEqual(vars(values), {"foo": "bar", "baz": 42})
443+
437444

438445
class TestTypeAliases(BaseTest):
439446
def setUp(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:class:`optparse.Values` objects now support :func:`copy.replace`.

0 commit comments

Comments
 (0)