Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix joining a function against metaclass-using object constructors
This pull request fixes python#9838. It turns out that when an object is using a metaclass, it uses that metaclass as the fallback instead of `builtins.type`. This caused the `if t.fallback.type.fullname != "builtins.type"` check we were performing in `join_similar_callables` and `combine_similar_callables` to pick the wrong fallback in the case where we were attempting to join a function against a constructor for an object that used a metaclass. This ended up causing a crash later for basically the exact same reason python#13576 caused a crash: using `abc.ABCMeta` causes `Callable.is_type_obj()` to return true, which causes us to enter a codepath where we call `Callable.type_object()`. But this function is not prepared to handle the case where the return type of the callable is a Union, causing an assert to fail. I opted to fix this by adjusting the join algorithm so it does `if t.fallback.type.fullname == "builtins.function"`. One question I did punt on -- what should happen in the case where one of the fallbacks is `builtins.type` and the other is a metaclass? I suspect it's impossible for this case to actually occur: I think mypy would opt to use the algorithm for joining two `Type[...]` entities instead of these callable joining algorithms. While I'm not 100% sure of this, the current approach of just arbitrarily picking one of the two fallbacks seemed good enough for now.
- Loading branch information