Skip to content

gh-97848: argparse: Disallow misbehaving actions for positional arguments #98367

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
wants to merge 9 commits into from

Conversation

kkarbowiak
Copy link
Contributor

@kkarbowiak kkarbowiak commented Oct 17, 2022

Issue #97848

The disallowed actions are: 'store_true', 'store_false' and 'store_const', which cause a counterintuitive behaviour.

Tests for new behaviour are included.

@bedevere-bot
Copy link

Most changes to Python require a NEWS entry.

Please add it using the blurb_it web app or the blurb command-line tool.

@ghost
Copy link

ghost commented Oct 17, 2022

All commit authors signed the Contributor License Agreement.
CLA signed

Copy link
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.

Thanks you for your proposal!

Technically this is a breaking change. But, in practice I highly doubt that anyone is using it.

@sobolevn
Copy link
Member

Retriggering CI to fix CLA status.

@sobolevn sobolevn closed this Oct 18, 2022
@sobolevn sobolevn reopened this Oct 18, 2022
@kkarbowiak
Copy link
Contributor Author

Hi, is there anything else I need to complete to get this merged?

Copy link
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.

Python is run by volunteers, so reviews by core-devs can take some time :)

But, it is fine to ping folks once in a while if there's no activity.

@kkarbowiak
Copy link
Contributor Author

Python is run by volunteers, so reviews by core-devs can take some time :)

But, it is fine to ping folks once in a while if there's no activity.

I get it and did not mean to be rude or impatient, I'm just keen to add a tiny contribution :-)

Thank you for the reviews!

@kkarbowiak
Copy link
Contributor Author

@sobolevn Since you have been kind enough to review this and provide valuable cues, could you please have a look once more?

Copy link
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.

I think this makes sense for 3.12

I will ping @JelleZijlstra as well :)

@AlexWaygood AlexWaygood changed the title gh-97848: Disallow misbehaving actions for positional arguments gh-97848: argparse: Disallow misbehaving actions for positional arguments Nov 13, 2022
@JelleZijlstra JelleZijlstra self-requested a review November 13, 2022 22:12
Copy link
Member

@JelleZijlstra JelleZijlstra left a comment

Choose a reason for hiding this comment

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

I think I'll leave this for another core dev.

@@ -1540,6 +1540,13 @@ def _get_positional_kwargs(self, dest, **kwargs):
msg = _("'required' is an invalid argument for positionals")
raise TypeError(msg)

# make sure 'store_true', 'store_false', or 'store_const' action
Copy link
Member

Choose a reason for hiding this comment

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

This feels inelegant because we're hardcoding the names of individual actions. I'm not familiar enough with argparse to propose an alternative implementation though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@JelleZijlstra thank you for the review.

You say the change feels inelegant, because the names of individual actions are hardcoded. Do I understand correctly that you would prefer some named values or enumeration? Or did you mean something else?

I also am not a huge fan of using these strings directly, but this is the interface exposed by the ArgumentParser class and as such I think the names are committed to and won't change.

Anyway, I am open to all suggestions on how to improve this PR.

Copy link
Member

Choose a reason for hiding this comment

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

I think that more elegant and general solution would be

  • either add an optional boolean parameter for registry()
  • or add an optional class attribute in _StoreTrueAction etc.

It can be tested in add_argument(), after testing that the action is a callable.

Copy link
Member

Choose a reason for hiding this comment

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

Actually, such flag already exists. You can check if nargs is 0 to detect actions that do not consume arguments.

@kkarbowiak
Copy link
Contributor Author

@rhettinger Could you please have a look and review this PR? @JelleZijlstra did have a look and decided to pass it some other core dev, but has not assigned anyone else.

Thanks.

@@ -1540,6 +1540,13 @@ def _get_positional_kwargs(self, dest, **kwargs):
msg = _("'required' is an invalid argument for positionals")
raise TypeError(msg)

# make sure 'store_true', 'store_false', or 'store_const' action
Copy link
Member

Choose a reason for hiding this comment

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

I think that more elegant and general solution would be

  • either add an optional boolean parameter for registry()
  • or add an optional class attribute in _StoreTrueAction etc.

It can be tested in add_argument(), after testing that the action is a callable.

# is not specified
action = kwargs.get('action')
if action in ('store_true', 'store_false', 'store_const'):
msg = _("{action} is an invalid action for positionals", {'action': action})
Copy link
Member

Choose a reason for hiding this comment

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

The argument of _() should be a string, not a tuple. I afraid that your tests are passed because a wrong TypeError is raised. You should test also the error message to be sure that this is the correct error.

Copy link
Member

Choose a reason for hiding this comment

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

And these error messages should not be internationalized, as they are programming errors, not user input errors.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for the review and comments. I will get back to this PR later this week.

Copy link
Member

Choose a reason for hiding this comment

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

Actually, I already created a PR with more general solution: #124839.

@bedevere-app
Copy link

bedevere-app bot commented Sep 22, 2024

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

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

Successfully merging this pull request may close these issues.

5 participants