From 4822017ddfb81635b2a3c978225a67de910e27e8 Mon Sep 17 00:00:00 2001 From: "d.grigonis" Date: Fri, 17 May 2024 18:45:52 +0300 Subject: [PATCH 1/4] functools.partial.fallforward --- Modules/_functoolsmodule.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 9dee7bf3062710..f02e7d93649578 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -46,9 +46,10 @@ typedef struct { PyObject *fn; PyObject *args; PyObject *kw; - PyObject *dict; /* __dict__ */ - PyObject *weakreflist; /* List of weak references */ + PyObject *dict; /* __dict__ */ + PyObject *weakreflist; /* List of weak references */ vectorcallfunc vectorcall; + Py_ssize_t can_vcall; /* Cache whether function allows vector call */ } partialobject; static void partial_setvectorcall(partialobject *pto); @@ -198,32 +199,22 @@ partial_dealloc(partialobject *pto) } -/* Merging keyword arguments using the vectorcall convention is messy, so - * if we would need to do that, we stop using vectorcall and fall back - * to using partial_call() instead. */ -Py_NO_INLINE static PyObject * -partial_vectorcall_fallback(PyThreadState *tstate, partialobject *pto, - PyObject *const *args, size_t nargsf, - PyObject *kwnames) -{ - pto->vectorcall = NULL; - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); - return _PyObject_MakeTpCall(tstate, (PyObject *)pto, - args, nargs, kwnames); -} - static PyObject * partial_vectorcall(partialobject *pto, PyObject *const *args, size_t nargsf, PyObject *kwnames) { PyThreadState *tstate = _PyThreadState_GET(); - + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); /* pto->kw is mutable, so need to check every time */ if (PyDict_GET_SIZE(pto->kw)) { - return partial_vectorcall_fallback(tstate, pto, args, nargsf, kwnames); + /* Merging keyword arguments using the vectorcall convention is messy, so + * if we would need to do that, we stop using vectorcall and fall back + * to using partial_call() instead. */ + pto->vectorcall = NULL; + return _PyObject_MakeTpCall(tstate, (PyObject *)pto, args, nargs, kwnames); + // return partial_vectorcall_fallback(tstate, pto, args, nargsf, kwnames); } - Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); Py_ssize_t nargs_total = nargs; if (kwnames != NULL) { nargs_total += PyTuple_GET_SIZE(kwnames); @@ -286,12 +277,14 @@ partial_setvectorcall(partialobject *pto) if (PyVectorcall_Function(pto->fn) == NULL) { /* Don't use vectorcall if the underlying function doesn't support it */ pto->vectorcall = NULL; + pto->can_vcall = 0; } /* We could have a special case if there are no arguments, * but that is unlikely (why use partial without arguments?), * so we don't optimize that */ else { pto->vectorcall = (vectorcallfunc)partial_vectorcall; + pto->can_vcall = 1; } } From 13e97978f2d12351d84c857a7c6f4405bcf3c60f Mon Sep 17 00:00:00 2001 From: "d.grigonis" Date: Fri, 17 May 2024 19:51:12 +0300 Subject: [PATCH 2/4] second part of the code.. --- Modules/_functoolsmodule.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index f02e7d93649578..f1f925738fafde 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -212,7 +212,6 @@ partial_vectorcall(partialobject *pto, PyObject *const *args, * to using partial_call() instead. */ pto->vectorcall = NULL; return _PyObject_MakeTpCall(tstate, (PyObject *)pto, args, nargs, kwnames); - // return partial_vectorcall_fallback(tstate, pto, args, nargsf, kwnames); } Py_ssize_t nargs_total = nargs; @@ -297,9 +296,17 @@ partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) assert(PyTuple_Check(pto->args)); assert(PyDict_Check(pto->kw)); + /* pto->kw is mutable, so need to check every time + * if kwds are empty to switch to more efficient vectorcall */ + Py_ssize_t pto_nkwargs = PyDict_GET_SIZE(pto->kw); + if ((pto_nkwargs == 0) & pto->can_vcall){ + pto->vectorcall = (vectorcallfunc)partial_vectorcall; + return PyObject_Call((PyObject *)pto, args, kwargs); + } + /* Merge keywords */ PyObject *kwargs2; - if (PyDict_GET_SIZE(pto->kw) == 0) { + if (pto_nkwargs == 0) { /* kwargs can be NULL */ kwargs2 = Py_XNewRef(kwargs); } From 652f50a6290d0513ef2711878b7ef0b60d90a36a Mon Sep 17 00:00:00 2001 From: "d.grigonis" Date: Sat, 18 May 2024 15:25:15 +0300 Subject: [PATCH 3/4] unnecessary stylistic change --- Modules/_functoolsmodule.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index f1f925738fafde..88d3b6eb963927 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -46,10 +46,10 @@ typedef struct { PyObject *fn; PyObject *args; PyObject *kw; - PyObject *dict; /* __dict__ */ - PyObject *weakreflist; /* List of weak references */ + PyObject *dict; /* __dict__ */ + PyObject *weakreflist; /* List of weak references */ vectorcallfunc vectorcall; - Py_ssize_t can_vcall; /* Cache whether function allows vector call */ + Py_ssize_t can_vcall; /* Cache whether function allows vector call */ } partialobject; static void partial_setvectorcall(partialobject *pto); From 64889f70a214c054832801018f099f996d15b957 Mon Sep 17 00:00:00 2001 From: "d.grigonis" Date: Mon, 20 May 2024 16:23:23 +0300 Subject: [PATCH 4/4] int type for bool --- Modules/_functoolsmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 88d3b6eb963927..a8f3019a812748 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -49,7 +49,7 @@ typedef struct { PyObject *dict; /* __dict__ */ PyObject *weakreflist; /* List of weak references */ vectorcallfunc vectorcall; - Py_ssize_t can_vcall; /* Cache whether function allows vector call */ + int can_vcall; /* Cache whether function allows vector call */ } partialobject; static void partial_setvectorcall(partialobject *pto); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy