Message 285404 - Python tracker (original) (raw)
- If a type only defines tp_fastcall: tp_fastcall is always use (tp_call uses the wrapper)
Is tp_call set to the wrapper rather then inheriting?
It is set to the wrapper. Defining tp_fastcall should work as defining tp_call: it should override the tp_call and tp_fastcall slots.
What if tp_call is defined in a superclass?
What is a superclass? Do you have an example?
- If a type defines tp_call and tp_fastcall, PyObject_Call() uses tp_call whereas _PyObject_FastCallDict() uses tp_fastcall.
I would consider this as a bug. It would be weird if different ways of calling cause executing different code.
It's a micro-optimization to avoid arguments unpacking/packing, conversions needed when you switch from the regular calling convention to the fast call convention, or the opposite.
I don't think that types defining tp_call and tp_fastcall will be common.
What about dynamically changed Python types?
What do you mean? Do you have an example?
What if you set or delete the call attribute of Python class?
I don't know how these things work :-) Let me try on a patched Python (using tp_fastcall):
$ ./python
class A: ... def call(self): print("A") ... a=A() a() A
A.call=lambda self: print("B!") a() B!
del A.call a() Traceback (most recent call last): File "", line 1, in TypeError: 'A' object is not callable
It seems like "it just works", but I don't know how it works internally :-)
a() uses a dynamic lookup of a.class.call, no?