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

Support some form of limited cast #941

Closed
jhance opened this issue Oct 17, 2015 · 5 comments
Closed

Support some form of limited cast #941

jhance opened this issue Oct 17, 2015 · 5 comments

Comments

@jhance
Copy link
Collaborator

jhance commented Oct 17, 2015

Support a softer, more limited alternative to cast.

This isn't in PEP 484, so it can't be the behavior of cast.

One of the common reasons of cast is that we "believe" for some reason that despite the original type of the variable being class A, it is in fact class B.

Currently, if we have

class A:
    pass

class B:
    pass

the two types would have no intersection, so if A was a correct type, it is never B. On the other hand, if we have

class A:
    pass

class B(A):
    pass

Then B and A have nonzero intersection and thus such a cast is at least plausible. It would be nice to have a softcast that allows the latter case but not the former.

Plausible reason to not support this: if isinstance(...) is arguably a better approach. I'm on the fence about it, but it seems like a nice thing to have.

@JukkaL
Copy link
Collaborator

JukkaL commented Oct 17, 2015

This is actually how casts work in Java, for example (at least with classes). Due to multiple inheritance, two Python classes could theoretically almost always intersect.

This might still be a reasonable thing to have and could catch some additional type errors, but this is not a high-priority feature as long as typing doesn't have a primitive for this. May be worth proposing this at https://github.com/ambv/typehinting as well.

@jhance
Copy link
Collaborator Author

jhance commented Oct 17, 2015

I guess instead of "nonzero intersection" it would be "iff one of the types is a subtype of the other" which rules out the class C(A, B) case and allows more safety for, as an example, softcast(CallExpr, self.visit_call_expr(expr))

I feel like this would cover the majority of cases where casting is actually useful (and in fact I would term the actual PEP484 cast as being a coerce, not a cast).

@mthuurne
Copy link
Contributor

mthuurne commented Dec 1, 2019

I think this is similar to the downcast() idea.

@Dreamsorcerer
Copy link
Contributor

Just to add some thoughts about similar usecases, a case I often find is something like a function that returns None or Any in some circumstances:

m = re.search("foo (.*)", some_string)
result = m.group(0)

This would be better if we could say "this is not X". e.g. Something like exclude(Any, m.group(0)) would ensure that any changes to the types are still reflected in the resulting type, and can also produce an error if the excluded type is no longer in the union type, thus ensuring that the code always stays relevant.

Alternatively, it could work as an include, saying what the type is, but also requiring the original type to be a superset of this. The cast() function could even be reused for this, with something like cast(str, m.group(0), narrow=True).

@AlexWaygood
Copy link
Member

I'm going to close in favour of #5756, which (if I understand correctly) is basically the same proposal, but has had much more discussion in the years since. Feel free to reopen if I misunderstood!

@AlexWaygood AlexWaygood closed this as not planned Won't fix, can't repro, duplicate, stale Mar 30, 2024
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

6 participants