
Here's an example of the difference:
class C: def f(s): pass f.__repr__ = lambda: "42" print C().f.__repr__()
This prints "42". If you comment out the PyDescr_IsData() call, it will print "<bound method C.f of <__main__.C instance at 0x...>>".
I'm not entirely clear what goes wrong in your case.
Well, in my case, I try to pickle a bound method, so
Um, my brain just did a double-take. Standard Python doesn't let you do that, so you must be changing some internals. Which parts of Python are you trying to change and which parts are you trying to keep unchanged? If you were using a different metaclass you could just create a different implementation of instancemethod that does what you want, so apparently you're not going that route. (With new-style classes, instancemethod isn't that special any more -- it's just a currying construct with some extra baggage.)
I expect that C().f.__reduce__ gives me a reasonable object: A method of an instance of C that is able to do an __reduce__, that is, I need the bound f and try to get its __reduce__ in a bound way.
Try again. I don't think that C().f.__reduce__ should be a method of an instance of C. You want it to be a method of a bound method object, right?
If that's not the way to do it, which is it?
I think what I suggested above -- forget about the existing instancemethod implementation. But I really don't understand the context in which you are doing this well enough to give you advice, and in any context that I understand the whole construct doesn't make sense. :-( --Guido van Rossum (home page: http://www.python.org/~guido/)