I can see three potential use-cases for always-raising methods:
-
raise NotImplementedError. I’ve used this several times myself, when implementing or designing classes with multiple methods, and I think the developer should be able to tell the type checker “I know what I’m doing, don’t distract me” until the code is production-ready. -
Always-raising method in a base class that’s annotated to produce a value, because subclasses are allowed to implement it in order to provide custom behaviour (for example supporting additional, external types).
Silly example (obviously not the best interface but I think this idea is common in the wild, especially since you cannot implement methods on external types without 'black magic')
class Serializer: @final def serialize(self, x: object, /) -> str: ... # logic that handles builtins, collections etc. by calling `self._serialize_scalar` def _serialize_scalar(self, x: object, /) -> str: raise TypeError(f"I don't know how to serialize object of type {type(x)}") class DecimalSerializer(Serializer): @override def _serialize_scalar(self, x: object) -> str: if isinstance(x, decimal.Decimal): return str(x) return super().serialize_scalar(x) -
Some exception types (for example,
StopIteration, but a library might define their own) are intended to be handled in a specific way, maybe because they carry control-flow information. It makes sense for__next__inIterator(or a concrete iterator base class) to be defined as returning, while an empty iterator can implement it with justraise StopIteration(). This is actually very similar to point 2. now that I think more about it…
Anyway, all the cases I’ve described only arise, in my mind, in a sort-of explicit manner, and I’m not sure whether they can be mapped to the implicit case (A & B having the same method with incompatible return types, and as a result of that incompatibility the return type magically becoming Never). In my mind, a silenceable warning would be the best option.
By the way, thanks (to you, but also everyone else involved) for the hard work on intersections: it will clearly be a very impactful change to the expressiveness of the type system, and as a typing user I’m really excited about it!
Edit: For some reason I hadn’t seen it but you had already answered this: perfect! Then I don’t have any objection and every option above is good; sorry for the extra post.