Aside from the distinction between unbound methods and functions being eliminated on Python 3, these classes aren't doing very much at the moment.
UnboundMethod overloads getattr and igetattr to return special values for im_func. This is both incorrect, because on Python 3 im_func is replaced by __func__, and incomplete, because there's another special attribute __self__ that's not handled.
Both have special cases in infer_call_result to specifically detect when they're being called on object.__new__and type.__new__. I would argue this should be done by having special nodes for object and type with other special nodes for their methods; then, the code that's currently living in the code for all methods could live in either methods of the new nodes or in functions dispatching on those types. Either way would reduce the overhead for every getattr or igetattr call made on every on method as well as improving the clarity of the code.
There are some miscellaneous methods that are easily replaced by type dispatch or are already completely unnecessary.
After removing this, the only important functionality remaining on either of these classes is the code that handles context binding in BoundMethod.infer_call_result:
if context is None:
context = contextmod.InferenceContext()
context = context.clone()
context.boundnode = self.bound
There might still need to be a Method object, but if so it will have pretty much that one method.
Originally reported by: BitBucket: ceridwenv, GitHub: ceridwenv
Aside from the distinction between unbound methods and functions being eliminated on Python 3, these classes aren't doing very much at the moment.
im_func
. This is both incorrect, because on Python 3im_func
is replaced by__func__
, and incomplete, because there's another special attribute__self__
that's not handled.object.__new__
andtype.__new__
. I would argue this should be done by having special nodes forobject
andtype
with other special nodes for their methods; then, the code that's currently living in the code for all methods could live in either methods of the new nodes or in functions dispatching on those types. Either way would reduce the overhead for every getattr or igetattr call made on every on method as well as improving the clarity of the code.After removing this, the only important functionality remaining on either of these classes is the code that handles context binding in BoundMethod.infer_call_result:
There might still need to be a Method object, but if so it will have pretty much that one method.