Currently the function/method signature hooks must return a CallableType. This precludes cases where a union of CallableTypes would be more appropriate.
For example, given
@attrs.define
class C1:
foo: int
@attrs.define
class C2:
bar: int
c: C1 | C2
then the signature of attrs.evolve for c could be returned by a function signature hook to be
(c: C1, foo: int) -> C1 | (c: C2, bar: int) -> C2.
Today #14849 performs an ad-hoc "meet" operation which results in a single callable type, which could instead be left to the existing functionality that "meet"s a union's types.
p.s. that being said, the current behavior for a union of callables is not friendly, e.g.
in this playground, the given union of callables can accept a bytes arg, but if you give them the mutually incompatible int or str, it simply says that it must be the other one, instead of saying "it's compatible with item 1 of the union but incompatible with item 2", etc.
Currently the function/method signature hooks must return a
CallableType. This precludes cases where a union ofCallableTypes would be more appropriate.For example, given
then the signature of
attrs.evolveforccould be returned by a function signature hook to be(c: C1, foo: int) -> C1 | (c: C2, bar: int) -> C2.Today #14849 performs an ad-hoc "meet" operation which results in a single callable type, which could instead be left to the existing functionality that "meet"s a union's types.
p.s. that being said, the current behavior for a union of callables is not friendly, e.g.
in this playground, the given union of callables can accept a
bytesarg, but if you give them the mutually incompatibleintorstr, it simply says that it must be the other one, instead of saying "it's compatible with item 1 of the union but incompatible with item 2", etc.