Skip to content
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

argparse: Use Literal for action & nargs add_argument parameter types #7329

Merged
merged 2 commits into from
Feb 21, 2022

Conversation

not-my-profile
Copy link
Contributor

@not-my-profile not-my-profile commented Feb 20, 2022

As has previously been discussed in #6826 (comment) the argparse module sometimes compares argparse.SUPPRESS with is meaning Literal["==SUPPRESS=="] is not suited. This PR solves this using NewType.

As reported by mypy_primer the following fails with mypy:

import argparse
x = argparse.SUPPRESS
x = "test"

because of:

foo.py:4: error: Incompatible types in assignment (expression has type "str", variable has type "_SUPPRESS_T")

This however seems to be due to a limitation in mypy not understanding that a newtype is backwards compatible with the original type as can be observed in the following example:

import typing

X = typing.NewType('X', int)

def foo(a: X) -> int:
    return a

Mypy complains whereas Pyright says it's ok. With that in mind I think that the advantages of this PR (type safety against typos) outweigh the caused inconvenience (when reassigning SUPPRESS with mypy).

@github-actions

This comment has been minimized.

@not-my-profile not-my-profile force-pushed the argparse-literals branch 3 times, most recently from 86741ac to 1b736f8 Compare February 20, 2022 19:07
@github-actions

This comment has been minimized.

2 similar comments
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

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.

Looks good. The cwltool code found by mypy-primer can just add explicit annotations.

@Akuli
Copy link
Collaborator

Akuli commented Feb 20, 2022

We could try SUPPRESS: _SUPPRESS_T | str to avoid the primer error. It's not really correct because SUPPRESS isn't just a string in the usual sense, but after foo = argparse.SUPPRESS you would at least be able to reassign a string.

@github-actions

This comment has been minimized.

1 similar comment
@github-actions
Copy link
Contributor

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

@JelleZijlstra JelleZijlstra merged commit a090181 into python:master Feb 21, 2022
JukkaL added a commit to JukkaL/typeshed that referenced this pull request Apr 12, 2022
These were introduced in python#7329 and they cause false positives
in code that used to be accepted before. There was a false
positive in https://github.com/pycqa/pylint (encountered in
python/mypy#12321) and I also saw
false positives in an internal codebase.

I suggest not using literal types here, since they can be kind of
awkward to annotate in callers that don't pass a literal string.
Rrequiring callers to write annotations like
`Literal["?", "*", "+", "...", "A...", "==SUPPRESS=="]` is not
very user friendly.
srittau pushed a commit that referenced this pull request Apr 13, 2022
These were introduced in #7329 and they cause false positives
in code that used to be accepted before.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants