summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2022-08-11 21:25:49 (GMT)
committerGitHub <noreply@github.com>2022-08-11 21:25:49 (GMT)
commit6f6a4e6cc5cd76af4a53ffbb62b686142646ac9a (patch)
treeaeb6de5e55af7bb77acaeccf6d672f725c81aeed /Python
parentbdb2cf8e913c041f26e8976abe58414819b3e8ff (diff)
downloadcpython-6f6a4e6cc5cd76af4a53ffbb62b686142646ac9a.zip
cpython-6f6a4e6cc5cd76af4a53ffbb62b686142646ac9a.tar.gz
cpython-6f6a4e6cc5cd76af4a53ffbb62b686142646ac9a.tar.bz2
gh-90928: Statically Initialize the Keywords Tuple in Clinic-Generated Code (gh-95860)
We only statically initialize for core code and builtin modules. Extension modules still create the tuple at runtime. We'll solve that part of interpreter isolation separately. This change includes generated code. The non-generated changes are in: * Tools/clinic/clinic.py * Python/getargs.c * Include/cpython/modsupport.h * Makefile.pre.in (re-generate global strings after running clinic) * very minor tweaks to Modules/_codecsmodule.c and Python/Python-tokenize.c All other changes are generated code (clinic, global strings).
Diffstat (limited to 'Python')
-rw-r--r--Python/Python-tokenize.c1
-rw-r--r--Python/clinic/Python-tokenize.c.h43
-rw-r--r--Python/clinic/_warnings.c.h78
-rw-r--r--Python/clinic/bltinmodule.c.h253
-rw-r--r--Python/clinic/context.c.h8
-rw-r--r--Python/clinic/import.c.h78
-rw-r--r--Python/clinic/marshal.c.h8
-rw-r--r--Python/clinic/sysmodule.c.h78
-rw-r--r--Python/clinic/traceback.c.h43
-rw-r--r--Python/getargs.c230
10 files changed, 716 insertions, 104 deletions
diff --git a/Python/Python-tokenize.c b/Python/Python-tokenize.c
index 6acfc2a..c5124a6 100644
--- a/Python/Python-tokenize.c
+++ b/Python/Python-tokenize.c
@@ -15,6 +15,7 @@ get_tokenize_state(PyObject *module) {
#define _tokenize_get_state_by_type(type) \
get_tokenize_state(PyType_GetModuleByDef(type, &_tokenizemodule))
+#include "pycore_runtime.h"
#include "clinic/Python-tokenize.c.h"
/*[clinic input]
diff --git a/Python/clinic/Python-tokenize.c.h b/Python/clinic/Python-tokenize.c.h
index 050b4d4..61bf291 100644
--- a/Python/clinic/Python-tokenize.c.h
+++ b/Python/clinic/Python-tokenize.c.h
@@ -2,6 +2,12 @@
preserve
[clinic start generated code]*/
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+# include "pycore_gc.h" // PyGC_Head
+# include "pycore_runtime.h" // _Py_ID()
+#endif
+
+
static PyObject *
tokenizeriter_new_impl(PyTypeObject *type, const char *source);
@@ -9,8 +15,41 @@ static PyObject *
tokenizeriter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 1
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(source), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"source", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "tokenizeriter", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "tokenizeriter",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[1];
PyObject * const *fastargs;
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
@@ -38,4 +77,4 @@ tokenizeriter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=dfcd64774e01bfe6 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=5664c98597aec79e input=a9049054013a1b77]*/
diff --git a/Python/clinic/_warnings.c.h b/Python/clinic/_warnings.c.h
index 926fb32..7944412 100644
--- a/Python/clinic/_warnings.c.h
+++ b/Python/clinic/_warnings.c.h
@@ -2,6 +2,12 @@
preserve
[clinic start generated code]*/
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+# include "pycore_gc.h" // PyGC_Head
+# include "pycore_runtime.h" // _Py_ID()
+#endif
+
+
PyDoc_STRVAR(warnings_warn__doc__,
"warn($module, /, message, category=None, stacklevel=1, source=None)\n"
"--\n"
@@ -19,8 +25,41 @@ static PyObject *
warnings_warn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 4
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(message), &_Py_ID(category), &_Py_ID(stacklevel), &_Py_ID(source), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"message", "category", "stacklevel", "source", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "warn", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "warn",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[4];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
PyObject *message;
@@ -88,8 +127,41 @@ static PyObject *
warnings_warn_explicit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 8
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(message), &_Py_ID(category), &_Py_ID(filename), &_Py_ID(lineno), &_Py_ID(module), &_Py_ID(registry), &_Py_ID(module_globals), &_Py_ID(source), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"message", "category", "filename", "lineno", "module", "registry", "module_globals", "source", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "warn_explicit", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "warn_explicit",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[8];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4;
PyObject *message;
@@ -147,4 +219,4 @@ skip_optional_pos:
exit:
return return_value;
}
-/*[clinic end generated code: output=596b370838b95386 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=264258fa6b1b0c36 input=a9049054013a1b77]*/
diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h
index 48f6509..76f9fca 100644
--- a/Python/clinic/bltinmodule.c.h
+++ b/Python/clinic/bltinmodule.c.h
@@ -2,6 +2,12 @@
preserve
[clinic start generated code]*/
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+# include "pycore_gc.h" // PyGC_Head
+# include "pycore_runtime.h" // _Py_ID()
+#endif
+
+
PyDoc_STRVAR(builtin___import____doc__,
"__import__($module, /, name, globals=None, locals=None, fromlist=(),\n"
" level=0)\n"
@@ -34,8 +40,41 @@ static PyObject *
builtin___import__(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 5
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(name), &_Py_ID(globals), &_Py_ID(locals), &_Py_ID(fromlist), &_Py_ID(level), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"name", "globals", "locals", "fromlist", "level", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "__import__", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "__import__",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[5];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
PyObject *name;
@@ -253,8 +292,41 @@ static PyObject *
builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 7
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(source), &_Py_ID(filename), &_Py_ID(mode), &_Py_ID(flags), &_Py_ID(dont_inherit), &_Py_ID(optimize), &_Py_ID(_feature_version), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", "_feature_version", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "compile",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[7];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3;
PyObject *source;
@@ -432,8 +504,41 @@ static PyObject *
builtin_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 1
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(closure), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"", "", "", "closure", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "exec", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "exec",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[4];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
PyObject *source;
@@ -743,8 +848,41 @@ static PyObject *
builtin_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 3
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(base), &_Py_ID(exp), &_Py_ID(mod), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"base", "exp", "mod", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "pow", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "pow",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[3];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
PyObject *base;
@@ -794,8 +932,41 @@ static PyObject *
builtin_print(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 4
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(sep), &_Py_ID(end), &_Py_ID(file), &_Py_ID(flush), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"sep", "end", "file", "flush", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "print", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "print",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[5];
Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
PyObject *__clinic_args = NULL;
@@ -910,8 +1081,41 @@ static PyObject *
builtin_round(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 2
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(number), &_Py_ID(ndigits), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"number", "ndigits", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "round", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "round",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[2];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
PyObject *number;
@@ -953,8 +1157,41 @@ static PyObject *
builtin_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 1
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(start), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"", "start", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "sum", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "sum",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[2];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
PyObject *iterable;
@@ -1045,4 +1282,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=a2c5c53e8aead7c3 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=4590e66a40312a9f input=a9049054013a1b77]*/
diff --git a/Python/clinic/context.c.h b/Python/clinic/context.c.h
index 292d3f7..27c3757 100644
--- a/Python/clinic/context.c.h
+++ b/Python/clinic/context.c.h
@@ -2,6 +2,12 @@
preserve
[clinic start generated code]*/
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+# include "pycore_gc.h" // PyGC_Head
+# include "pycore_runtime.h" // _Py_ID()
+#endif
+
+
PyDoc_STRVAR(_contextvars_Context_get__doc__,
"get($self, key, default=None, /)\n"
"--\n"
@@ -177,4 +183,4 @@ PyDoc_STRVAR(_contextvars_ContextVar_reset__doc__,
#define _CONTEXTVARS_CONTEXTVAR_RESET_METHODDEF \
{"reset", (PyCFunction)_contextvars_ContextVar_reset, METH_O, _contextvars_ContextVar_reset__doc__},
-/*[clinic end generated code: output=2436b16a92452869 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=0c94d4b919500438 input=a9049054013a1b77]*/
diff --git a/Python/clinic/import.c.h b/Python/clinic/import.c.h
index 0451d97..69eebde 100644
--- a/Python/clinic/import.c.h
+++ b/Python/clinic/import.c.h
@@ -2,6 +2,12 @@
preserve
[clinic start generated code]*/
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+# include "pycore_gc.h" // PyGC_Head
+# include "pycore_runtime.h" // _Py_ID()
+#endif
+
+
PyDoc_STRVAR(_imp_lock_held__doc__,
"lock_held($module, /)\n"
"--\n"
@@ -193,8 +199,41 @@ static PyObject *
_imp_find_frozen(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 1
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(withdata), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"", "withdata", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "find_frozen", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "find_frozen",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[2];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
PyObject *name;
@@ -526,8 +565,41 @@ static PyObject *
_imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 2
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(key), &_Py_ID(source), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"key", "source", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "source_hash", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "source_hash",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[2];
long key;
Py_buffer source = {NULL, NULL};
@@ -565,4 +637,4 @@ exit:
#ifndef _IMP_EXEC_DYNAMIC_METHODDEF
#define _IMP_EXEC_DYNAMIC_METHODDEF
#endif /* !defined(_IMP_EXEC_DYNAMIC_METHODDEF) */
-/*[clinic end generated code: output=8d0f4305b1d0714b input=a9049054013a1b77]*/
+/*[clinic end generated code: output=7d75c10a93f2f26c input=a9049054013a1b77]*/
diff --git a/Python/clinic/marshal.c.h b/Python/clinic/marshal.c.h
index 36f2afd..a593b98 100644
--- a/Python/clinic/marshal.c.h
+++ b/Python/clinic/marshal.c.h
@@ -2,6 +2,12 @@
preserve
[clinic start generated code]*/
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+# include "pycore_gc.h" // PyGC_Head
+# include "pycore_runtime.h" // _Py_ID()
+#endif
+
+
PyDoc_STRVAR(marshal_dump__doc__,
"dump($module, value, file, version=version, /)\n"
"--\n"
@@ -155,4 +161,4 @@ exit:
return return_value;
}
-/*[clinic end generated code: output=b9e838edee43fe87 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=12082d61d2942473 input=a9049054013a1b77]*/
diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h
index 76b4cc5..e1021bb 100644
--- a/Python/clinic/sysmodule.c.h
+++ b/Python/clinic/sysmodule.c.h
@@ -2,6 +2,12 @@
preserve
[clinic start generated code]*/
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+# include "pycore_gc.h" // PyGC_Head
+# include "pycore_runtime.h" // _Py_ID()
+#endif
+
+
PyDoc_STRVAR(sys_addaudithook__doc__,
"addaudithook($module, /, hook)\n"
"--\n"
@@ -18,8 +24,41 @@ static PyObject *
sys_addaudithook(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 1
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(hook), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"hook", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "addaudithook", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "addaudithook",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[1];
PyObject *hook;
@@ -425,8 +464,41 @@ static PyObject *
sys_set_coroutine_origin_tracking_depth(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 1
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(depth), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"depth", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "set_coroutine_origin_tracking_depth", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "set_coroutine_origin_tracking_depth",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[1];
int depth;
@@ -1118,4 +1190,4 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored))
#ifndef SYS_GETANDROIDAPILEVEL_METHODDEF
#define SYS_GETANDROIDAPILEVEL_METHODDEF
#endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */
-/*[clinic end generated code: output=41122dae1bb7158c input=a9049054013a1b77]*/
+/*[clinic end generated code: output=b8b125686bc745a6 input=a9049054013a1b77]*/
diff --git a/Python/clinic/traceback.c.h b/Python/clinic/traceback.c.h
index 404a0c4..5de1102 100644
--- a/Python/clinic/traceback.c.h
+++ b/Python/clinic/traceback.c.h
@@ -2,6 +2,12 @@
preserve
[clinic start generated code]*/
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+# include "pycore_gc.h" // PyGC_Head
+# include "pycore_runtime.h" // _Py_ID()
+#endif
+
+
PyDoc_STRVAR(tb_new__doc__,
"TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)\n"
"--\n"
@@ -16,8 +22,41 @@ static PyObject *
tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
PyObject *return_value = NULL;
+ #define NUM_KEYWORDS 4
+ #if NUM_KEYWORDS == 0
+
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+ # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+ # else
+ # define KWTUPLE NULL
+ # endif
+
+ #else // NUM_KEYWORDS != 0
+ # if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+ static struct {
+ PyGC_Head _this_is_not_used;
+ PyObject_VAR_HEAD
+ PyObject *ob_item[NUM_KEYWORDS];
+ } _kwtuple = {
+ .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+ .ob_item = { &_Py_ID(tb_next), &_Py_ID(tb_frame), &_Py_ID(tb_lasti), &_Py_ID(tb_lineno), },
+ };
+ # define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+ # else // !Py_BUILD_CORE
+ # define KWTUPLE NULL
+ # endif // !Py_BUILD_CORE
+ #endif // NUM_KEYWORDS != 0
+ #undef NUM_KEYWORDS
+
static const char * const _keywords[] = {"tb_next", "tb_frame", "tb_lasti", "tb_lineno", NULL};
- static _PyArg_Parser _parser = {NULL, _keywords, "TracebackType", 0};
+ static _PyArg_Parser _parser = {
+ .keywords = _keywords,
+ .fname = "TracebackType",
+ .kwtuple = KWTUPLE,
+ };
+ #undef KWTUPLE
PyObject *argsbuf[4];
PyObject * const *fastargs;
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
@@ -49,4 +88,4 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=403778d7af5ebef9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=130ba2a638849c70 input=a9049054013a1b77]*/
diff --git a/Python/getargs.c b/Python/getargs.c
index 2efd330..457dd99 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -1851,118 +1851,183 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
static struct _PyArg_Parser *static_arg_parsers = NULL;
static int
-parser_init(struct _PyArg_Parser *parser)
+scan_keywords(const char * const *keywords, int *ptotal, int *pposonly)
{
- const char * const *keywords;
- const char *format, *msg;
- int i, len, min, max, nkw;
- PyObject *kwtuple;
-
- assert(parser->keywords != NULL);
- if (parser->kwtuple != NULL) {
- return 1;
- }
-
- keywords = parser->keywords;
/* scan keywords and count the number of positional-only parameters */
+ int i;
for (i = 0; keywords[i] && !*keywords[i]; i++) {
}
- parser->pos = i;
+ *pposonly = i;
+
/* scan keywords and get greatest possible nbr of args */
for (; keywords[i]; i++) {
if (!*keywords[i]) {
PyErr_SetString(PyExc_SystemError,
"Empty keyword parameter name");
- return 0;
+ return -1;
}
}
- len = i;
+ *ptotal = i;
+ return 0;
+}
- format = parser->format;
- if (format) {
- /* grab the function name or custom error msg first (mutually exclusive) */
- parser->fname = strchr(parser->format, ':');
- if (parser->fname) {
- parser->fname++;
- parser->custom_msg = NULL;
+static int
+parse_format(const char *format, int total, int npos,
+ const char **pfname, const char **pcustommsg,
+ int *pmin, int *pmax)
+{
+ /* grab the function name or custom error msg first (mutually exclusive) */
+ const char *custommsg;
+ const char *fname = strchr(format, ':');
+ if (fname) {
+ fname++;
+ custommsg = NULL;
+ }
+ else {
+ custommsg = strchr(format,';');
+ if (custommsg) {
+ custommsg++;
}
- else {
- parser->custom_msg = strchr(parser->format,';');
- if (parser->custom_msg)
- parser->custom_msg++;
- }
-
- min = max = INT_MAX;
- for (i = 0; i < len; i++) {
- if (*format == '|') {
- if (min != INT_MAX) {
- PyErr_SetString(PyExc_SystemError,
- "Invalid format string (| specified twice)");
- return 0;
- }
- if (max != INT_MAX) {
- PyErr_SetString(PyExc_SystemError,
- "Invalid format string ($ before |)");
- return 0;
- }
- min = i;
- format++;
+ }
+
+ int min = INT_MAX;
+ int max = INT_MAX;
+ for (int i = 0; i < total; i++) {
+ if (*format == '|') {
+ if (min != INT_MAX) {
+ PyErr_SetString(PyExc_SystemError,
+ "Invalid format string (| specified twice)");
+ return -1;
}
- if (*format == '$') {
- if (max != INT_MAX) {
- PyErr_SetString(PyExc_SystemError,
- "Invalid format string ($ specified twice)");
- return 0;
- }
- if (i < parser->pos) {
- PyErr_SetString(PyExc_SystemError,
- "Empty parameter name after $");
- return 0;
- }
- max = i;
- format++;
+ if (max != INT_MAX) {
+ PyErr_SetString(PyExc_SystemError,
+ "Invalid format string ($ before |)");
+ return -1;
}
- if (IS_END_OF_FORMAT(*format)) {
- PyErr_Format(PyExc_SystemError,
- "More keyword list entries (%d) than "
- "format specifiers (%d)", len, i);
- return 0;
+ min = i;
+ format++;
+ }
+ if (*format == '$') {
+ if (max != INT_MAX) {
+ PyErr_SetString(PyExc_SystemError,
+ "Invalid format string ($ specified twice)");
+ return -1;
}
-
- msg = skipitem(&format, NULL, 0);
- if (msg) {
- PyErr_Format(PyExc_SystemError, "%s: '%s'", msg,
- format);
- return 0;
+ if (i < npos) {
+ PyErr_SetString(PyExc_SystemError,
+ "Empty parameter name after $");
+ return -1;
}
+ max = i;
+ format++;
}
- parser->min = Py_MIN(min, len);
- parser->max = Py_MIN(max, len);
-
- if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
+ if (IS_END_OF_FORMAT(*format)) {
PyErr_Format(PyExc_SystemError,
- "more argument specifiers than keyword list entries "
- "(remaining format:'%s')", format);
- return 0;
+ "More keyword list entries (%d) than "
+ "format specifiers (%d)", total, i);
+ return -1;
+ }
+
+ const char *msg = skipitem(&format, NULL, 0);
+ if (msg) {
+ PyErr_Format(PyExc_SystemError, "%s: '%s'", msg,
+ format);
+ return -1;
}
}
+ min = Py_MIN(min, total);
+ max = Py_MIN(max, total);
- nkw = len - parser->pos;
- kwtuple = PyTuple_New(nkw);
+ if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
+ PyErr_Format(PyExc_SystemError,
+ "more argument specifiers than keyword list entries "
+ "(remaining format:'%s')", format);
+ return -1;
+ }
+
+ *pfname = fname;
+ *pcustommsg = custommsg;
+ *pmin = min;
+ *pmax = max;
+ return 0;
+}
+
+static PyObject *
+new_kwtuple(const char * const *keywords, int total, int pos)
+{
+ int nkw = total - pos;
+ PyObject *kwtuple = PyTuple_New(nkw);
if (kwtuple == NULL) {
- return 0;
+ return NULL;
}
- keywords = parser->keywords + parser->pos;
- for (i = 0; i < nkw; i++) {
+ keywords += pos;
+ for (int i = 0; i < nkw; i++) {
PyObject *str = PyUnicode_FromString(keywords[i]);
if (str == NULL) {
Py_DECREF(kwtuple);
- return 0;
+ return NULL;
}
PyUnicode_InternInPlace(&str);
PyTuple_SET_ITEM(kwtuple, i, str);
}
+ return kwtuple;
+}
+
+static int
+parser_init(struct _PyArg_Parser *parser)
+{
+ const char * const *keywords = parser->keywords;
+ assert(keywords != NULL);
+
+ if (parser->initialized) {
+ assert(parser->kwtuple != NULL);
+ return 1;
+ }
+ assert(parser->pos == 0 &&
+ (parser->format == NULL || parser->fname == NULL) &&
+ parser->custom_msg == NULL &&
+ parser->min == 0 &&
+ parser->max == 0);
+
+ int len, pos;
+ if (scan_keywords(keywords, &len, &pos) < 0) {
+ return 0;
+ }
+
+ const char *fname, *custommsg = NULL;
+ int min = 0, max = 0;
+ if (parser->format) {
+ assert(parser->fname == NULL);
+ if (parse_format(parser->format, len, pos,
+ &fname, &custommsg, &min, &max) < 0) {
+ return 0;
+ }
+ }
+ else {
+ assert(parser->fname != NULL);
+ fname = parser->fname;
+ }
+
+ int owned;
+ PyObject *kwtuple = parser->kwtuple;
+ if (kwtuple == NULL) {
+ kwtuple = new_kwtuple(keywords, len, pos);
+ if (kwtuple == NULL) {
+ return 0;
+ }
+ owned = 1;
+ }
+ else {
+ owned = 0;
+ }
+
+ parser->pos = pos;
+ parser->fname = fname;
+ parser->custom_msg = custommsg;
+ parser->min = min;
+ parser->max = max;
parser->kwtuple = kwtuple;
+ parser->initialized = owned ? 1 : -1;
assert(parser->next == NULL);
parser->next = static_arg_parsers;
@@ -1973,7 +2038,9 @@ parser_init(struct _PyArg_Parser *parser)
static void
parser_clear(struct _PyArg_Parser *parser)
{
- Py_CLEAR(parser->kwtuple);
+ if (parser->initialized == 1) {
+ Py_CLEAR(parser->kwtuple);
+ }
}
static PyObject*
@@ -2100,6 +2167,7 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs,
}
format = parser->format;
+ assert(format != NULL || len == 0);
/* convert tuple args and keyword args in same loop, using kwtuple to drive process */
for (i = 0; i < len; i++) {
if (*format == '|') {