Hello, I'm reworking argument dispatching code, and I realize that we've always had a funny problem. In CPython, we have the following half-expected behavior: class X: def f(self, **kwds): print kwds x = X() x.f(v=5) -> {'v': 5} x.f(self=5) -> TypeError: multiple values for argument 'self' But of course, nothing wrong with: def f(**kwds): print kwds f(self=5) -> {'self': 5} However, this fails in PyPy with the same TypeError as above! The reason is that the call is done via the __call__ descriptor, which is a perfectly normal method: f.__call__ -> <method object at 0xe75fcac> (In CPython you get a <method-wrapper object>.) Now if it is a method we can investiate a bit:
f.__call__.im_self is f True f.__call__.im_func <function object at 0xe73440c> f.__call__.im_func.func_code <internal-code object at 0xe5fc98c> f.__call__.im_func.func_code.co_varnames AttributeError: co_varnames
but actually, even without (yet) exposing it at app-level, the code object has got a signature which says the function's argument list is (self, *args, **keywords). The name 'self' conflicts here with a 'self' keyword. Ack. It's nice and all to be able to inspect built-in functions' signature (which you cannot do yet, but it's just a matter of adding computed co_xxx attributes on this <internal-code object>)... but this is a problem. Moreover, we have a different compatibility problem too: in CPython, built-in functions don't have a __get__, so you can put them in classes and read them out without having the first argument bound to the instance. For example, if you put 'operator.add' in the class TrivialObjSpace, then 'space.add' is exactly 'operator.add' and not a bound version of it. What should we do about it? Maybe asking python-dev for guidance? Have 'unboundable function objects' -- like staticmethod, but the latter is not callable -- and make some carefully selected functions unboundable for compatibility? For the 1st problem we could force a general solution by saying that the argument that a method binds is hidden to keywords. It would also make the very first example of this e-mail work, although it doesn't work in CPython. A bientot, Armin.