-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Disallow unsafe cast() uses. #14797
Comments
Leaving For example, these casts are unsafe:
So, what can we cast then?
This can be an opt-in error code if we define what "unsafe" casts are 👍 |
Isn’t that question somewhat answered when checking whether the LHS and the RHS of an assignment are “compatible”? From my list of unsafe examples or yours: class Foo:
pass
f: Foo = None # error: Incompatible types in assignment (expression has type "None", variable has type "Foo")
f: Foo = cast(Foo, None) # Success: no issues found in 1 source file
i: int = "abc" # error: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]
i: int = cast(int, "abc") # Success: no issues found in 1 source file and so forth — so if I can assign it, then it’s probably a “safe” cast and I should be allowed to cast it. (Which sort-of defeats the purpose of Perhaps the builtin types should be considered more carefully with
This sort-of opens the door to the same issue described above, but is probably strongly tied to how well n: Any = None
f: Foo = n # Success: no issues found in 1 source file But I’d probably agree:
Up-casts, yes, down-casts are problematic (and class Foo:
pass
class Bar(Foo):
def do_bar(self) -> None: ...
b: Bar = cast(Bar, Foo()) # b.do_bar() will fail. If somebody casts to a super-type then the cast is redundant, I think, and maybe
You mean allowing additional types for a list? Wouldn’t that be similar to “widening” (as opposed to narrowing)? But I guess that’s why I want to
That’s with the intention to define the shape of the dictionary, right? It’s also a down-cast but a special one.
You mean treating So the more I think about this, the more I’m tempted to distinguish three use-cases for the
|
I broadly agree. There are two uses of safe casts:
Everything else is unsafe. If you think of types as sets, I can see that it could be useful to disambiguate casts to an overlapping type (where there is a value that can possibly belong to the casted type), such as downcasts, NewType, cast to TypedDict, etc — from your "nonsense" casts where the sets of values are completely disjoint. I would potentially be okay with including a (non-standard) opt-in check to detect nonsense casts in mypy. But I do kind of want to pursue adding differently named functions for these cases, at least for the safe cast vs unsafe cast. In particular, I find users are sometimes completely unaware of how unsafe |
I agree with adding a And we’re circling in on discussion #5756
Hah, yeah. The initial |
The semantics and behavior for the existing Adding a safer form of cast is a reasonable idea, but it would be better to move that discussion to the python/typing discussion forum because such an addition would presumably need to be added to the python type system and would not be specific to mypy. |
Yeah, let's move discussion to python/typing#565 |
Fair enough. Should I open a discussion with the above blurb there again, or what’s the recommended approach?
Thanks for the reference, that issue is interesting and quite related; I might chime in for a moment. So we now have #5756 and python/typing#565 and the python/typing discussion forum to continue this conversation 🤓 An alternative would be a writing a flake8 plugin or a pylint plugin instead… at least for the aforementioned uses of |
Feature
Certain uses of the
cast()
function should be disallowed and rejected by the type checker. In fact, I think that “unsafe” uses ofcast()
should be an explicit opt-in feature.This feature request seems related to #5756
Pitch
Today I came across the following statement (yes, this is production code):
embedded in a function roughly like so:
Allowing to cast
None
to another type is the essence of an “unsafe” cast and should not be allowed. Furthermore, I’d consider the following uses of thecast()
function nonsense as well:which actually gives me
If somebody — for whatever reason — insists on such an unsafe type cast, then they should make their intentions clear, e.g.
Allowing the above casts, to me, defeats the purpose of using a type checker as a code QA tool which is supposed to help prevent bugs.
The text was updated successfully, but these errors were encountered: