- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 33.3k
 
gh-96859: Optimize argparse actions 'append', 'append_const' and 'extend' #124909
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
base: main
Are you sure you want to change the base?
gh-96859: Optimize argparse actions 'append', 'append_const' and 'extend' #124909
Conversation
…nd 'extend' Previously, the target list was copied every time the action was taken. Now only the default value is copied the first time the action is taken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The title of the PR should be changed to gh-96859: Optimize ... to link to a github issue. (gh-124745 is the number of an alternative PR)
| @@ -0,0 +1,4 @@ | |||
| Optimize :mod:`argparse` actions 'append', 'append_const' and 'extend' for | |||
| the case when the option is specified many times. | |||
| The targed list no longer copied every time the action is taken, only | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| The targed list no longer copied every time the action is taken, only | |
| The target list is no longer copied every time the action is taken, only | 
| def __call__(self, parser, namespace, values, option_string=None): | ||
| items = getattr(namespace, self.dest, None) | ||
| items = _copy_items(items) | ||
| if items is self.default: | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell this changes the behavior in some corner cases. For example, when parse_known_args() is called with a not empty namespace. The new code will only clone lists when default is set. The old code would have cloned any existing list. This matters if the caller has another reference to the same list.
Something like this
some_existing_list = []
ns = argparse.Namespace()
ns.setattr("foo", some_existing_list)
parser = argparse.ArgumentParser()
parser.add_argument('--foo', action='append')
...
... = parser.parse_known_args(args=['--foo=xxx'], namespace=ns)
# At this point some_existing_list is ['xxx']There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. There are no tests for this (and some other corner cases).
        
          
                Misc/NEWS.d/next/Library/2024-10-02-21-34-08.gh-issue-96859.efyaxu.rst
              
                Outdated
          
            Show resolved
            Hide resolved
        
      …yaxu.rst Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Previously, the target list was copied every time the action was taken. Now only the default value is copied the first time the action is taken.