Guido van Rossum wrote:
Apart from the tests that were testing the behavior of im_class, I found only a single piece of code in the standard library that used im_class of an unbound method object (the clever test in the pyclbr test). Uses of im_self and im_func were more widespread. Given the level of cleverness in the pyclbr test (and the fact that I wrote it myself) I'm not worried about widespread use of im_class on unbound methods.
I guess this depends on how you define widespread use. I'm using this feature a lot via the basemethod() function in mxTools for calling the base method of an overridden method in mixin classes (basemethod() predates super() and unlike the latter works for old-style classes).
I'm not sure I understand how basemethod is supposed to work; I can't find docs for it using Google (only three hits for the query mxTools basemethod). How does it depend on im_class?
It uses im_class to find the class defining the (unbound) method:
""" Return the unbound method that is defined *after* method in the inheritance order of object with the same name as method (usually called base method or overridden method).
object can be an instance, class or bound method. method, if given, may be a bound or unbound method. If it is not given, object must be bound method.
Note: Unbound methods must be called with an instance as first argument.
The function uses a cache to speed up processing. Changes done to the class structure after the first hit will not be noticed by the function.
This is how it is used in mixin classes to call the base method of the overridden method in the inheritance tree (of old-style classes):
def __init__(self,name,viewname,viewdb,context=None,use_clipboard=0, size=None,width=None,monospaced=1,events=None):
# Call base method mx.Tools.basemethod(self, RequestListboxMixin.__init__)\ (self,name,size,width,monospaced,None,events)
Without .im_class for the unbound method, basemethod would seize to work since it uses this attribute to figure out the class object defining the overriding method.
I can send you the code if you don't have egenix-mx-base installed somewhere (its in mx/Tools/Tools.py).
What I don't understand in your reasoning is that you are talking about making an unbound method look more like a function.
That's a strange interpretation. I'm getting rid of the unbound method object altogether.
Well, you do have to assign some other type to the object that is returned by "myClass.myMethod" and as I understood your proposal, the returned object should be of the FunctionType. So from an application point of view, you are changing the type of an object.
Unbound methods and bound methods are objects of the same type - the method object.
Yeah I know that. :-)
And it is one of the problems -- the two uses are quite distinct and yet it's the same object, which is confusing.
Hmm, I have a hard time seeing how you can get rid off unbound methods while keeping bound methods - since both are the same type :-)
By turning an unbound method into a function type, you break code that tests for MethodType in Python or does a PyMethod_Check() at C level.
My expectation is that there is very little code like that. Almost all the code that I found doing that in the core Python code (none in C BTW) was in the test suite.
I'm using PyMethod_Check() in mxProxy to automatically wrap methods of proxied object in order to prevent references to the object class or the object itself to slip by the proxy. Changing the type to function object and placing the class information into a function attribute would break this approach. Apart from that the type change (by itself) would not affect the eGenix code base.
I would expect code in the following areas to make use of the type check: * language interface code (e.g. Java, .NET bridges) * security code that tries to implement object access control * RPC applications that use introspection to generate interface definitions (e.g. WSDL service definitions) * debugging tools (e.g. IDEs)
Perhaps a few others could scan their code base as well ?!
If you want to make methods look more like functions, the method object should become a subclass of the function object (function + added im_* attributes).
Can't do that, since the (un)bound method object supports binding other callables besides functions.
Is this feature used anywhere ?