Open KotlinIsland opened 3 years ago
This feature request appears to be based on a misunderstanding of the Python type system. The type annotation float
doesn't simply refer to the class float
. It represents a set of types that includes float
and all subtypes thereof. The type float
and the type float | int
refer to the same set of types, so they are equivalent.
This feature request appears to be based on a misunderstanding of the Python type system.
That's obviously not what I am saying lol. This issue is regarding addressing the problems introduced by the 'ducktyping' functionality defined in pep 484, which states that float
/int
should lie about their base classes (mypy extends this idea to bytes). The solution being that instead of lying about their bases (extremely confusing), these specific types should just expand to a union of the ducklings.
I don't understand what you're asking for here. I'm also not sure that you understood my previous point, so let me try again.
In type theory, if you have a class Parent
and a class Child
that derives from parent, then the types Parent
and Parent | Child
are 100% equivalent. If a type checker ever treats these as different, then it's a bug. If I understand you correctly, you're saying that float
should be "expanded to" float | int
, but those two types are 100% equivalent already because int
is (by definition in PEP 484) a subtype of float
. If mypy ever treats float
differently from float | int
, then it's a bug.
Are you suggesting that mypy add a new mode where it deviates from the behavior specified in PEP 484 and treats int
as though it's not a subtype of float
, etc.? That would be incompatible with all existing type stubs, so I don't think it would be very useful.
Or perhaps what you're asking is for new special forms to be added to the type system that represent "a float that is not an int" (float & ~int
), etc.? That would require a new specification in the form of a PEP, and the mypy issue tracker wouldn't be the right place to request such a change.
Or perhaps what you're saying is that when mypy prints the type builtins.float
in a textual form (e.g. in error messages), you always want it to print builtins.float | builtins.int
. That would be sound from a type perspective, but I think most mypy users would find that representation to be redundant, verbose, and even somewhat confusing.
Or perhaps I haven't yet captured what you're proposing. If that's the case, can you provide more specifics?
Edit: Now I get it. I totally missed the fact the hierarchy is fake for those very specific types. Been living too long on mypy-island.
I think @KotlinIsland wants
1) the fake hierarchy undone, and
2) for float
, emit float | int
behind the scenes, and
3) some time later introduce typing.FloatForReal
that won't have that union-emitting behavior
Probably subject for a typing issue...
@ikonst yeah, exactly. I plan on implementing this in basedmypy, it will be an interesting experiment.
@ikonst, what do you mean by "emit float | int
behind the scenes"? Will that result in any user-visible behavior change in mypy? If so, how? Is the only visible change that the textual output for reveal_type
and error messages becomes more verbose?
@ikonst, what do you mean by "emit
float | int
behind the scenes"? Will that result in any user-visible behavior change in mypy? If so, how? Is the only visible change that the textual output forreveal_type
and error messages becomes more verbose?
No, annotating something with float
will result in the type being float | int
. And the promotion/ducktyping will be removed from int
.
Ah, I see what you mean. Thanks for the explanation. Yeah, that's an interesting experiment. Let us know what you find.
If the duck typed types were actually unions of all the ducklings then it would fix a bunch of edge cases that arise. And would make this feature more easily understood and discovered.
edge cases:
It would also be useful to have type types for
float
andbytes
, when you want exactlyfloat
and don't want any stinkingint
s.Related #11511, #11145