Skip to content

gh-149614 - Restore deepcopiability of argparse.ArgumentParser instances#149617

Open
DavidCEllis wants to merge 10 commits intopython:mainfrom
DavidCEllis:unbreak-argparse-copy
Open

gh-149614 - Restore deepcopiability of argparse.ArgumentParser instances#149617
DavidCEllis wants to merge 10 commits intopython:mainfrom
DavidCEllis:unbreak-argparse-copy

Conversation

@DavidCEllis
Copy link
Copy Markdown
Contributor

@DavidCEllis DavidCEllis commented May 9, 2026

With the creation of the _ColorlessTheme to avoid importing _colorize early the new class unfortunately was returning empty strings for __deepcopy__ along with other dunder methods which broke deepcopy.

I've added tests for copy and deepcopy based on the test for pickle.

Being more cautious, I've narrowed the class to only returning empty strings on attributes matching those taken from _colorize.

This does mean making sure the set remains in sync which could be more annoying to maintain, it would also be possible to just exclude anything starting with _. I've updated the test that checks this theme to directly check they are in sync.

Comment thread Lib/argparse.py Outdated
Comment thread Lib/test/test_argparse.py
Comment thread Lib/test/test_argparse.py
parser.add_argument('bar', nargs='?', default='baz')
return parser

def test_copiable(self):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want @force_not_colorized on these tests right?

Separately, we may also be able to fold copiable and deepcopiable into one test, since these are pretty much the same.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left these as two tests for now as there's testing for the different copy/deepcopy behaviour

Comment thread Lib/test/test_argparse.py
import copy
parser = self._get_parser()
parser2 = copy.deepcopy(parser)
ns = parser2.parse_args(['--foo', '123', 'quux'])
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be more robust to mutate parser2 (e.g. add_argument) and assert parser doesn't see it. As written, the test would still pass if deepcopy silently returned a shallow copy or even the same object.

Comment thread Lib/argparse.py Outdated
Copy link
Copy Markdown
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting merge needs backport to 3.15 pre-release feature fixes, bugs and security fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants