Uh oh!
There was an error while loading. Please reload this page.
tempfile: Fix TypeVar usage - #7939
Conversation
This comment has been minimized.
This comment has been minimized.
2 similar comments
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
AlexWaygood
commented
May 24, 2022
I have no idea why this change makes mypy think that the result of |
Okay, I've managed to reproduce the fromtypingimportAny, AnyStr, TypeAlias, overloadimportosconsts: Any_DirT: TypeAlias=AnyStr|os.PathLike[AnyStr]
@overloaddefmkdtemp(suffix: None= ..., prefix: None= ..., dir: None= ...) ->str: ...
@overloaddefmkdtemp(suffix: AnyStr, prefix: AnyStr|None= ..., dir: _DirT[AnyStr] |None= ...) ->AnyStr: ...
@overloaddefmkdtemp(*, prefix: AnyStr, dir: _DirT[AnyStr] |None= ...) ->AnyStr: ...
@overloaddefmkdtemp(*, dir: _DirT[AnyStr]) ->AnyStr: ...
reveal_type(mkdtemp(prefix=consts.prefix, suffix=consts.suffix)) # Revealed type is "Any"reveal_type(os.path.abspath(mkdtemp(prefix=consts.prefix, suffix=consts.suffix))) # Revealed type is "Any"x: str|Noneifnotx:
x=os.path.abspath(mkdtemp(prefix=consts.prefix, suffix=consts.suffix)) # Revealed type is "Union[builtins.str, None]"reveal_type(x)https://mypy-play.net/?mypy=latest&python=3.10&gist=67faf105c3c17e72591a947bf45aeb64 Mypy appears to be refusing to do type narrowing for the This is how mypy currently infers the types, by contrast: fromtypingimportAny, AnyStr, TypeAlias, overloadfromtempfileimportmkdtempimportosconsts: Anyreveal_type(mkdtemp(prefix=consts.prefix, suffix=consts.suffix)) # Revealed type is "builtins.str"reveal_type(os.path.abspath(mkdtemp(prefix=consts.prefix, suffix=consts.suffix))) # Revealed type is "builtins.str"x: str|Noneifnotx:
x=os.path.abspath(mkdtemp(prefix=consts.prefix, suffix=consts.suffix))
reveal_type(x) # Revealed type is "builtins.str"https://mypy-play.net/?mypy=latest&python=3.10&gist=2bae188586be16ac81bd72c96244f017 I.e., currently mypy incorrectly infers that the return type of |
Looks like it was one of those cases where it's sensitive to the ordering of the contraints in AnyStr, if we had |
JelleZijlstra
left a comment
There was a problem hiding this comment.
This disallows some valid calls, such as tempfile.mkstemp(None, b"x"). I think we can fix this and work around the mypy bug with three overloads:
- One where all the args are None (you already have it)
- One where all the args are
str | None, returningtuple[int, str] - One where all the args are
bytes | None, returningtuple[int, bytes]
mkdtemp would need similar treatment.
mktemp indeed doesn't accept bytes, so it was correct to remove the AnyStr for it.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
hauntsaninja
left a comment
There was a problem hiding this comment.
nit: I'd remove the "according to mypy" since these overloads genuinely do overlap (just to disambiguate from other comments where we workaround incorrect mypy behaviour).
AlexWaygood
commented
May 25, 2022
I think the only reason pyright never complains about this is we have the check switched off in pyrightconfig.json. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
AlexWaygood
commented
May 25, 2022
Good spot! I'm fine with the new approach :) |
Diff from mypy_primer, showing the effect of this PR on open source code: manticore (https://github.com/trailofbits/manticore)
+ manticore/core/workspace.py:220: error: Argument 1 to "exists" has incompatible type "Optional[str]"; expected "Union[Union[str, bytes, PathLike[str], PathLike[bytes]], int]"+ manticore/core/workspace.py:221: error: Argument 1 to "isdir" has incompatible type "Optional[str]"; expected "Union[Union[str, bytes, PathLike[str], PathLike[bytes]], int]"+ manticore/core/workspace.py:223: error: Argument 1 to "mkdir" has incompatible type "Optional[str]"; expected "Union[str, bytes, PathLike[str], PathLike[bytes]]" |
I think this may remove the false positives from #7939's mypy-primer output.
#7928
I find the name
_DirTreally confusing, considering it's a type alias rather than aTypeVar, but decided against fixing that in this PR in order to keep the diff small.