On Wed, Dec 23, 2020 at 5:48 PM Eric Traut <eric@traut.com> wrote:
Just catching up on the thread.

Guido said:
>Sebastian Kreft seems to have executed a search that came to the same conclusion as Anders (typeguards are one-argument functions), but he is pushing for a way to define a typeguard as a method that guards self, e.g. if query.empty(): .... I'm not sure how to address this without adopting David's idea except to propose that if self is the only argument the typeguard applies to self.

Applying a user-defined type guard to `self` strikes me as a very unusual use case — one that probably involves anti-patterns such as a base class having knowledge of its derived classes. I don't think we should accommodate this with any special handling. The proposed mechanism already handles this if you pass self as an explicit argument, as in:

The real world example I provided does not require knowledge of any subclasses, it just asserts the object conforms to a specialized protocol which better describes the types for the current state of the class. Note that the example is based on some real Typescript code.

For the provided example one could instead model the query result as instances of one of the two classes `ExistingResult` or `MissingResult`. However, that violates another principle of not returning Unions.

If you could provide an alternative to better model the example code that would be great.

I think this whole point could be postponed if we remove the ability to specify typeguards with multiple arguments.

class Foo:
    def is_bar(self, x: "Foo") -> TypeGuard[Bar]:
        return isinstance(x, Bar)

    def func(self):
        if self.is_bar(self):
            reveal_type(self)  # Bar

I agree strongly with Guido that `cast` should not be overloaded for all the reasons provided. From my perspective, `cast` should be used only rarely and as a last resort. It's effectively saying "disable all type checking safety here because I know better". It's dangerous and leads to fragile code. I wouldn't want to further legitimize its use. Also, I agree that it would be inappropriate to implicitly redefine the type of the expression passed as the first argument to `cast`. That would be inconsistent, unintuitive, and result in backward compatibility problems for existing code.

David said:
>it's possible to trivially implement safe_cast()...

Yes, but I'll point out that you would need to reverse the parameters because the expression that is being narrowed (in your example, the `value` parameter) must be the first param of the type guard function.

Guido said:
>Conclusion: There are some loose ends, but I will sponsor this PEP and likely approve it after only minor updates. Eric, please use PEP number 647.

OK, thanks. I'll work on incorporating the feedback and post a new draft soon.
Typing-sig mailing list -- typing-sig@python.org
To unsubscribe send an email to typing-sig-leave@python.org
Member address: skreft@gmail.com

Sebastian Kreft