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

no error when casting to a non-overlapping type #11958

Closed
DetachHead opened this issue Jan 10, 2022 · 11 comments
Closed

no error when casting to a non-overlapping type #11958

DetachHead opened this issue Jan 10, 2022 · 11 comments

Comments

@DetachHead
Copy link
Contributor

from typing import cast

foo: str

a = cast(int, foo)

https://mypy-play.net/?mypy=master&python=3.10&flags=show-error-codes%2Callow-redefinition%2Cstrict%2Ccheck-untyped-defs%2Cdisallow-any-decorated%2Cdisallow-any-expr%2Cdisallow-any-explicit%2Cdisallow-any-generics%2Cdisallow-any-unimported%2Cdisallow-incomplete-defs%2Cdisallow-subclassing-any%2Cdisallow-untyped-calls%2Cdisallow-untyped-decorators%2Cdisallow-untyped-defs%2Cno-implicit-optional%2Cno-implicit-reexport%2Cstrict-equality%2Cwarn-incomplete-stub%2Cwarn-redundant-casts%2Cwarn-return-any%2Cwarn-unreachable%2Cwarn-unused-configs%2Cwarn-unused-ignores&gist=31fcda75d3ac971c1307689beae24537

typescript doesn't allow this, and instead suggests up-casting to unknown first

declare const foo: string

const bar = foo as number

Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

https://www.typescriptlang.org/play?#code/CYUwxgNghgTiAEYD2A7AzgF3gMyUgXPJjAJYoDmAsAFA3LpYBGs8AvDnvFGvCgK4BbRiBg06qTPGYAvNhyRcefFAGsUSAO4pFvQcJhA

mypy should probably suggest the same thing, which would look like

a = cast(int, cast(object, foo))
@DetachHead DetachHead added the bug mypy got something wrong label Jan 10, 2022
@erictraut
Copy link

The cast operator in Python allows any arbitrary cast. It's unsafe by its very nature, so it should be used sparingly. There has been discussion of adding a safe_cast that applies type validation as you're suggesting, but that would require a new call (and probably a new PEP).

@KotlinIsland
Copy link
Contributor

KotlinIsland commented Feb 3, 2022

The cast here will literally never 'succeed' and is only a mistake.

This is especially relevant to final classes:

from typing import final
@final
class A: ...
class B: ...

a: A
cast(a, B)  # literally impossible and only ever incorrect

The cases where it would get a little dicey is when nominal types overlap.

class A:
    a: int
class B:
    a: int

cast(B, A())  # should not have an error because these types are duck compatible

I would very much like this feature to be implemented.

@AlexWaygood AlexWaygood added topic-casts feature priority-2-low and removed bug mypy got something wrong labels Mar 27, 2022
@erictraut
Copy link

As I mentioned above, the behavior of cast is well defined (in PEP 484), and mypy implements it according to the spec.

It sounds like you want a safe form of cast. If so, this is a duplicate of #5756.

I recommend closing this issue.

@DetachHead
Copy link
Contributor Author

that issue is for upcasting, which is different. i still want to be able to cast to a subtype, but the problem is that it allows casting to types that are not a subtype.

basically it should behave the same way as typescript:

declare const foo: string

// doesn't allow casting to a non-overlapping type (because it's completely unsafe because it's always wrong)
foo as number // error

// but still allows casting to a valid subtype (even though it's not fully safe, it's not always wrong)
foo as 'asdf' // no error

// upcasting is always safe
foo as string | number // no error

@erictraut
Copy link

I think what you want is consistent with the #5756.

Regardless, if you want a different (safe) cast to become part of Python typing, that would need to go through a standardization (PEP) process. It would be more appropriate to discuss in the python/typing discussion forum.

@DetachHead
Copy link
Contributor Author

I think what you want is consistent with the #5756.

i don't think so. that issue says one of the semantics of the proposed "safe cast" is that it 'Requires that the expression has a type that is a "proper subtype" (mypy terminology) of the target type'. as in, the type has to be a supertype of the expression being casted to it.

Regardless, if you want a different (safe) cast to become part of Python typing, that would need to go through a standardization (PEP) process. It would be more appropriate to discuss in the python/typing discussion forum.

i don't think the existing PEP explicitly states that invalid casts should be allowed. it says "the programmer may know that an expression is of a more constrained type than a type checker may be able to infer".

because int is not a more constrained type than str, it does not fit the use case outlined in the PEP. it should be an error, just like how cast(foo, int) is an error because the expression is in the type position even though the PEP doesn't say so.

@erictraut
Copy link

The semantics of typing.cast are well established. It is used, among other things, to handle cases where types are annotated incorrectly in third-party libraries or stubs, and a "safe" form will not work in these cases.

If you want a "safe" form of a cast, that would require a new and different mechanism. That would require specification and standardization.

@hauntsaninja
Copy link
Collaborator

Closing as a duplicate.

See my comment here: #14797 (comment)
More discussion here python/typing#565 and #5756

@hauntsaninja hauntsaninja closed this as not planned Won't fix, can't repro, duplicate, stale Aug 13, 2023
@DetachHead
Copy link
Contributor Author

i don't get why this issue was closed when none of the other issues seem like appropriate places to continue this discussion.

@hauntsaninja
Copy link
Collaborator

python/typing#565 isn't locked, can you comment on other issues in that repo?

Anyway, if you want a standard type system feature, that's the repo and issue to comment in (or the typing-sig mailing list).

If you want something non-standard, the opt-in check I mention in #14797 (comment) is something I would review a PR for.

@DetachHead
Copy link
Contributor Author

python/typing#565 isn't locked, can you comment on other issues in that repo?

looks like i can comment on other issues, but not that one:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants