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

ParamSpec erases Optional when no-strict-optional is enabled #15932

Closed
koogoro opened this issue Aug 22, 2023 · 1 comment
Closed

ParamSpec erases Optional when no-strict-optional is enabled #15932

koogoro opened this issue Aug 22, 2023 · 1 comment
Labels
bug mypy got something wrong topic-paramspec PEP 612, ParamSpec, Concatenate topic-strict-optional

Comments

@koogoro
Copy link
Collaborator

koogoro commented Aug 22, 2023

Bug Report

The latest master will cause ParamSpec to replace parameters with type Optional[T] with type T when in a file with no-strict-optional. This is different from the behavior on 1.5.1. While this is equivalent within the same file, if a function affected by this issue is imported to a file without no-strict-optional, mypy will no longer let you pass None into that parameter. This behavior affects decorators such as contextlib.contextmanager.

To Reproduce

https://gist.github.com/mypy-play/dc17766e33ca6f4a1ec440257b0462ac

Expected Behavior

main.py:10: note: Revealed type is "def (arg: Union[builtins.int, None])"
Success: no issues found in 1 source file

Actual Behavior

main.py:10: note: Revealed type is "def (arg: builtins.int)"
Success: no issues found in 1 source file

Your Environment

I bisected the commits and found that this issue first occurs on 14418bc.

@koogoro koogoro added bug mypy got something wrong topic-strict-optional topic-paramspec PEP 612, ParamSpec, Concatenate labels Aug 22, 2023
@ilevkivskyi
Copy link
Member

This is consistent with behavior for regular TypeVars (since at least 1.0.0, but likely it is much older):

from typing import Optional, TypeVar
from typing import Callable

def a(arg: Optional[int]) -> None: ...

T = TypeVar('T')
def b(f: Callable[[T], None]) -> Callable[[T], None]: ...

reveal_type(b(a))  # Revealed type is "def (builtins.int)"

Unions were simplified during expansion for ages, and inconsistent behavior for ParamSpec was a bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-paramspec PEP 612, ParamSpec, Concatenate topic-strict-optional
Projects
None yet
Development

No branches or pull requests

2 participants