-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
The lookup logic for __new__ added in #16512 is faulty. It adds "member lookup policies" to skip object.__new__ and type.__new__, and then we effectively special-case handling of an implied object.__new__ if no __new__ is found in the lookup. But this logic doesn't work if there is a custom metaclass: we'll still find __new__ on the custom metaclass (after not finding it on the class itself, since we skip object.__new__) and then we'll wrongly try to use the metaclass __new__:
import abc
class Foo(metaclass=abc.ABCMeta): ...
# error: No arguments provided for required parameters `bases`, `namespace` of bound method `__new__` (lint:missing-argument) [Ln 5, Col 1]
# error: Argument to this function is incorrect: Expected `str`, found `Literal[Foo]` (lint:invalid-argument-type) [Ln 5, Col 1]
Foo()We need to better represent the actual runtime lookup logic here, which is that object.__new__ does exist, therefore __new__ will never be looked up on the metaclass at all. One approach would be to have something like a known synthetic function type for object.__new__, and return that instead of not-found, and then we can recognize that known method type and special-case its usage appropriately when we get it back from the lookup. That will prevent us wrongly going to try to find __new__ on the metaclass (and should remove the need for the skip-type lookup policy.)
Or an alternative approach might be to replace the skip-type lookup policy with an even more general never-look-up-on-the-meta-type policy.