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.ArgumentParser.add_argument doesn't allow type=os.path.abspath #3107

Closed
andymwood opened this issue Jul 8, 2019 · 6 comments
Closed

Comments

@andymwood
Copy link

Running mypy on this code:

import argparse,  os
reveal_type(os.path.abspath)
p = argparse.ArgumentParser()
p.add_argument("file", type=os.path.abspath)

I get:

mypy args.py 
args.py:2: note: Revealed type is 'Overload(def [AnyStr in (builtins.str, builtins.bytes)] (path: builtins._PathLike[AnyStr`-1]) -> AnyStr`-1, def [AnyStr in (builtins.str, builtins.bytes)] (path: AnyStr`-1) -> AnyStr`-1)'
args.py:4: error: Argument "type" to "add_argument" of "_ActionsContainer" has incompatible type overloaded function; expected "Union[Callable[[str], AnyStr], FileType]"

Should the type signature of add_argument be changed to allow functions that accept a PathLike argument?

@srittau
Copy link
Collaborator

srittau commented Jul 8, 2019

I assume you are using Python 3.6+. If I'm not mistaken, the stubs are correct. Callable[[str], _T] matches the overload def basename(path: AnyStr) -> AnyStr: ... with AnyStr and _T constrained to str. Possibly a not supported edge case in mypy? pytype accepts this.

@andymwood
Copy link
Author

Ok, thanks for that. I've reported the issue at the python/mypy repo instead.

@andymwood
Copy link
Author

I'm re-opening this issue following the advice of this comment.

@andymwood andymwood reopened this Aug 12, 2019
@srittau
Copy link
Collaborator

srittau commented Aug 12, 2019

I still think add_argument is typed correctly. Replacing _T with Any would actually reduce the strictness, since _T is deliberately used for both type and choices. By changing _T to Any, this wouldn't be caught:

from argparse import ArgumentParser

def to_str(x: str) -> str:
    return x

arg = ArgumentParser()
arg.add_argument(type=to_str, choices=[1])

CC @ilevkivskyi

@ilevkivskyi
Copy link
Member

The fact that mypy currently flags above code is a bug in mypy (quite subtle one). It should infer _T = object for the method and accept this call.

For example this code is correctly accepted:

T = TypeVar('T')
def g(x: T, y: T) -> None: ...
g('yes', 42)

@JelleZijlstra
Copy link
Member

Pyright allows the code in the original post and it also looks fine to me with the current stub, so I am going to say this is still a bug in mypy.

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

No branches or pull requests

4 participants