Skip to content

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

Closed as not planned

Description

@koogoro

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.

Activity

  1. ilevkivskyi commented on Aug 22, 2023

    @ilevkivskyi
    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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions