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

float ignores (in)variance when used as type argument #840

Closed
jorenham opened this issue Dec 6, 2024 · 4 comments
Closed

float ignores (in)variance when used as type argument #840

jorenham opened this issue Dec 6, 2024 · 4 comments
Labels
bug Something isn't working p-2 normal upstream

Comments

@jorenham
Copy link
Collaborator

jorenham commented Dec 6, 2024

Describe the problem

repost from python/mypy#18257

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?

Gist to reproduce

No response

Severity

blocker (literally unusable)

Your Environment

rainy and windy

@jorenham jorenham added bug Something isn't working upstream labels Dec 6, 2024
@KotlinIsland KotlinIsland added the p-2 normal label Dec 7, 2024
@KotlinIsland
Copy link
Owner

KotlinIsland commented Dec 7, 2024

here is the relevant code

basedmypy/mypy/subtypes.py

Lines 521 to 527 in d3e5574

if not self.subtype_context.ignore_promotions:
for base in left.type.mro:
if base._promote and any(
self._is_subtype(p, self.right) for p in base._promote
):
type_state.record_subtype_cache_entry(self._subtype_kind, left, right)
return True

the way promotions are handled is that here it performs the subtype check with all of the promotion types

i could look into this further next week, but i'm not going to treat any promotion issues as high priority as i am planning on deprecating this entirely

@jorenham
Copy link
Collaborator Author

i could look into this further next week, but i'm not going to treat any promotion issues as high priority as i am planning on deprecating this entirely

but that's going to be configurable, right?

@KotlinIsland
Copy link
Owner

resolved upstream

@jorenham
Copy link
Collaborator Author

jorenham commented Jan 2, 2025

python/mypy#18360

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working p-2 normal upstream
Projects
None yet
Development

No branches or pull requests

2 participants