Author jdemeyer
Recipients Mark.Shannon, inada.naoki, jdemeyer
Date 2019-07-05.12:31:42
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1562329903.16.0.406310679042.issue37207@roundup.psfhosted.org>
In-reply-to
Content
One thing that keeps bothering me when using vectorcall for type.__call__ is that we would have two completely independent code paths for constructing an object: the new one using vectorcall and the old one using tp_call, which in turn calls tp_new and tp_init.

In typical vectorcall usages, there is no need to support the old way any longer: we can set tp_call = PyVectorcall_Call and that's it. But for "type", we still need to support tp_new and tp_init because there may be C code out there that calls tp_new/tp_init directly. To give one concrete example: collections.defaultdict calls PyDict_Type.tp_init

One solution is to keep the old code for tp_new/tp_init. This is what Mark did in PR 13930. But this leads to duplication of functionality and is therefore error-prone (different code paths may have subtly different behaviour).

Since we don't want to break Python code calling dict.__new__ or dict.__init__, not implementing those is not an option. But to be compatible with the vectorcall signature, ideally we want to implement __init__ using METH_FASTCALL, so __init__ would need to be a normal method instead of a slot wrapper of tp_init (similar to Python classes). This would work, but it needs some support in typeobject.c
History
Date User Action Args
2019-07-05 12:31:43jdemeyersetrecipients: + jdemeyer, inada.naoki, Mark.Shannon
2019-07-05 12:31:43jdemeyersetmessageid: <1562329903.16.0.406310679042.issue37207@roundup.psfhosted.org>
2019-07-05 12:31:43jdemeyerlinkissue37207 messages
2019-07-05 12:31:42jdemeyercreate