Skip to content

float and complex forcibly change invariant types to covariant #18257

Closed
@jorenham

Description

@jorenham

The following example illustrates the issue, and how fixing it will give rise to an important use-case.

mypy playground

from typing import Protocol


class Just[T](Protocol):
    """
    Taken from `optype.typing.Just`.
    https://github.com/jorenham/optype?tab=readme-ov-file#just-types
    """
    @property  # type: ignore[override]
    def __class__(self, /) -> type[T]: ...
    @__class__.setter
    def __class__(self, t: type[T], /) -> None: ...


def assert_object(x: Just[object], /) -> object:
    # free sentinels anyone?
    assert type(x) is object
    return x

def assert_int(x: Just[int], /) -> int:
    # resolves python/mypy#8363
    assert type(x) is int
    return x

def assert_float(x: Just[float], /) -> float:
    # `int` promotion workaround?
    assert type(x) is float
    return x
    
    
assert_object(object())  # ok: <accepted>
assert_object(0.0)       # ok: incompatible type "float"
assert_object(-1)        # ok: incompatible type "int"
assert_object(not 1)     # ok: incompatible type "bool"

assert_int(object())     # ok: incompatible type "object"
assert_int(22 / 7)       # ok: incompatible type "float"
assert_int(0x1337)       # ok: <accepted>
assert_int(0 > -0)       # ok: incompatible type "bool"  (just let that sink in(t)...)

assert_float(object())   # ok: incompatible type "object"
assert_float(3.14)       # ok: <accepted>
assert_float(-1)         # !?: <accepted>
assert_float(False)      # !?: <accepted>

# ... `float` forcibly changes `~T@Just` to `+T@Just`?

# Some notes:
#
# * same issue with `builtins.complex`
# * user-defined types such as `class A: ...` don't have this problem
# * pyright (1.1.390) doesn't have this issue

huh, what's going on with the syntax highlighting?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions