mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
gh-103763: Implement PEP 695 (#103764)
This implements PEP 695, Type Parameter Syntax. It adds support for: - Generic functions (def func[T](): ...) - Generic classes (class X[T](): ...) - Type aliases (type X = ...) - New scoping when the new syntax is used within a class body - Compiler and interpreter changes to support the new syntax and scoping rules Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Co-authored-by: Eric Traut <eric@traut.com> Co-authored-by: Larry Hastings <larry@hastings.org> Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
fdafdc235e
commit
24d8b88420
56 changed files with 11405 additions and 5469 deletions
786
Objects/clinic/typevarobject.c.h
generated
Normal file
786
Objects/clinic/typevarobject.c.h
generated
Normal file
|
|
@ -0,0 +1,786 @@
|
|||
/*[clinic input]
|
||||
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(typevar_new__doc__,
|
||||
"typevar(name, *constraints, *, bound=None, covariant=False,\n"
|
||||
" contravariant=False, infer_variance=False)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Create a TypeVar.");
|
||||
|
||||
static PyObject *
|
||||
typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints,
|
||||
PyObject *bound, int covariant, int contravariant,
|
||||
int infer_variance);
|
||||
|
||||
static PyObject *
|
||||
typevar_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 5
|
||||
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(bound), &_Py_ID(covariant), &_Py_ID(contravariant), &_Py_ID(infer_variance), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"name", "bound", "covariant", "contravariant", "infer_variance", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "typevar",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[6];
|
||||
PyObject * const *fastargs;
|
||||
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
|
||||
Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1;
|
||||
PyObject *name;
|
||||
PyObject *constraints = NULL;
|
||||
PyObject *bound = Py_None;
|
||||
int covariant = 0;
|
||||
int contravariant = 0;
|
||||
int infer_variance = 0;
|
||||
|
||||
fastargs = _PyArg_UnpackKeywordsWithVararg(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, 1, argsbuf);
|
||||
if (!fastargs) {
|
||||
goto exit;
|
||||
}
|
||||
if (!PyUnicode_Check(fastargs[0])) {
|
||||
_PyArg_BadArgument("typevar", "argument 'name'", "str", fastargs[0]);
|
||||
goto exit;
|
||||
}
|
||||
name = fastargs[0];
|
||||
constraints = fastargs[1];
|
||||
if (!noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
if (fastargs[2]) {
|
||||
bound = fastargs[2];
|
||||
if (!--noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
}
|
||||
if (fastargs[3]) {
|
||||
covariant = PyObject_IsTrue(fastargs[3]);
|
||||
if (covariant < 0) {
|
||||
goto exit;
|
||||
}
|
||||
if (!--noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
}
|
||||
if (fastargs[4]) {
|
||||
contravariant = PyObject_IsTrue(fastargs[4]);
|
||||
if (contravariant < 0) {
|
||||
goto exit;
|
||||
}
|
||||
if (!--noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
}
|
||||
infer_variance = PyObject_IsTrue(fastargs[5]);
|
||||
if (infer_variance < 0) {
|
||||
goto exit;
|
||||
}
|
||||
skip_optional_kwonly:
|
||||
return_value = typevar_new_impl(type, name, constraints, bound, covariant, contravariant, infer_variance);
|
||||
|
||||
exit:
|
||||
Py_XDECREF(constraints);
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(typevar_typing_subst__doc__,
|
||||
"__typing_subst__($self, /, arg)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define TYPEVAR_TYPING_SUBST_METHODDEF \
|
||||
{"__typing_subst__", _PyCFunction_CAST(typevar_typing_subst), METH_FASTCALL|METH_KEYWORDS, typevar_typing_subst__doc__},
|
||||
|
||||
static PyObject *
|
||||
typevar_typing_subst_impl(typevarobject *self, PyObject *arg);
|
||||
|
||||
static PyObject *
|
||||
typevar_typing_subst(typevarobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 1
|
||||
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(arg), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"arg", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "__typing_subst__",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[1];
|
||||
PyObject *arg;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
|
||||
if (!args) {
|
||||
goto exit;
|
||||
}
|
||||
arg = args[0];
|
||||
return_value = typevar_typing_subst_impl(self, arg);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(typevar_reduce__doc__,
|
||||
"__reduce__($self, /)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define TYPEVAR_REDUCE_METHODDEF \
|
||||
{"__reduce__", (PyCFunction)typevar_reduce, METH_NOARGS, typevar_reduce__doc__},
|
||||
|
||||
static PyObject *
|
||||
typevar_reduce_impl(typevarobject *self);
|
||||
|
||||
static PyObject *
|
||||
typevar_reduce(typevarobject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return typevar_reduce_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(paramspecargs_new__doc__,
|
||||
"paramspecargs(origin)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Create a ParamSpecArgs object.");
|
||||
|
||||
static PyObject *
|
||||
paramspecargs_new_impl(PyTypeObject *type, PyObject *origin);
|
||||
|
||||
static PyObject *
|
||||
paramspecargs_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 1
|
||||
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(origin), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"origin", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "paramspecargs",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[1];
|
||||
PyObject * const *fastargs;
|
||||
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
|
||||
PyObject *origin;
|
||||
|
||||
fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf);
|
||||
if (!fastargs) {
|
||||
goto exit;
|
||||
}
|
||||
origin = fastargs[0];
|
||||
return_value = paramspecargs_new_impl(type, origin);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(paramspeckwargs_new__doc__,
|
||||
"paramspeckwargs(origin)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Create a ParamSpecKwargs object.");
|
||||
|
||||
static PyObject *
|
||||
paramspeckwargs_new_impl(PyTypeObject *type, PyObject *origin);
|
||||
|
||||
static PyObject *
|
||||
paramspeckwargs_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 1
|
||||
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(origin), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"origin", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "paramspeckwargs",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[1];
|
||||
PyObject * const *fastargs;
|
||||
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
|
||||
PyObject *origin;
|
||||
|
||||
fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf);
|
||||
if (!fastargs) {
|
||||
goto exit;
|
||||
}
|
||||
origin = fastargs[0];
|
||||
return_value = paramspeckwargs_new_impl(type, origin);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(paramspec_new__doc__,
|
||||
"paramspec(name, *, bound=None, covariant=False, contravariant=False,\n"
|
||||
" infer_variance=False)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Create a ParamSpec object.");
|
||||
|
||||
static PyObject *
|
||||
paramspec_new_impl(PyTypeObject *type, PyObject *name, PyObject *bound,
|
||||
int covariant, int contravariant, int infer_variance);
|
||||
|
||||
static PyObject *
|
||||
paramspec_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 5
|
||||
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(bound), &_Py_ID(covariant), &_Py_ID(contravariant), &_Py_ID(infer_variance), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"name", "bound", "covariant", "contravariant", "infer_variance", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "paramspec",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[5];
|
||||
PyObject * const *fastargs;
|
||||
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
|
||||
Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1;
|
||||
PyObject *name;
|
||||
PyObject *bound = Py_None;
|
||||
int covariant = 0;
|
||||
int contravariant = 0;
|
||||
int infer_variance = 0;
|
||||
|
||||
fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf);
|
||||
if (!fastargs) {
|
||||
goto exit;
|
||||
}
|
||||
if (!PyUnicode_Check(fastargs[0])) {
|
||||
_PyArg_BadArgument("paramspec", "argument 'name'", "str", fastargs[0]);
|
||||
goto exit;
|
||||
}
|
||||
name = fastargs[0];
|
||||
if (!noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
if (fastargs[1]) {
|
||||
bound = fastargs[1];
|
||||
if (!--noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
}
|
||||
if (fastargs[2]) {
|
||||
covariant = PyObject_IsTrue(fastargs[2]);
|
||||
if (covariant < 0) {
|
||||
goto exit;
|
||||
}
|
||||
if (!--noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
}
|
||||
if (fastargs[3]) {
|
||||
contravariant = PyObject_IsTrue(fastargs[3]);
|
||||
if (contravariant < 0) {
|
||||
goto exit;
|
||||
}
|
||||
if (!--noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
}
|
||||
infer_variance = PyObject_IsTrue(fastargs[4]);
|
||||
if (infer_variance < 0) {
|
||||
goto exit;
|
||||
}
|
||||
skip_optional_kwonly:
|
||||
return_value = paramspec_new_impl(type, name, bound, covariant, contravariant, infer_variance);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(paramspec_typing_subst__doc__,
|
||||
"__typing_subst__($self, /, arg)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define PARAMSPEC_TYPING_SUBST_METHODDEF \
|
||||
{"__typing_subst__", _PyCFunction_CAST(paramspec_typing_subst), METH_FASTCALL|METH_KEYWORDS, paramspec_typing_subst__doc__},
|
||||
|
||||
static PyObject *
|
||||
paramspec_typing_subst_impl(paramspecobject *self, PyObject *arg);
|
||||
|
||||
static PyObject *
|
||||
paramspec_typing_subst(paramspecobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 1
|
||||
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(arg), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"arg", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "__typing_subst__",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[1];
|
||||
PyObject *arg;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
|
||||
if (!args) {
|
||||
goto exit;
|
||||
}
|
||||
arg = args[0];
|
||||
return_value = paramspec_typing_subst_impl(self, arg);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(paramspec_typing_prepare_subst__doc__,
|
||||
"__typing_prepare_subst__($self, /, alias, args)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define PARAMSPEC_TYPING_PREPARE_SUBST_METHODDEF \
|
||||
{"__typing_prepare_subst__", _PyCFunction_CAST(paramspec_typing_prepare_subst), METH_FASTCALL|METH_KEYWORDS, paramspec_typing_prepare_subst__doc__},
|
||||
|
||||
static PyObject *
|
||||
paramspec_typing_prepare_subst_impl(paramspecobject *self, PyObject *alias,
|
||||
PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
paramspec_typing_prepare_subst(paramspecobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 2
|
||||
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(alias), &_Py_ID(args), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"alias", "args", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "__typing_prepare_subst__",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[2];
|
||||
PyObject *alias;
|
||||
PyObject *__clinic_args;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
|
||||
if (!args) {
|
||||
goto exit;
|
||||
}
|
||||
alias = args[0];
|
||||
__clinic_args = args[1];
|
||||
return_value = paramspec_typing_prepare_subst_impl(self, alias, __clinic_args);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(paramspec_reduce__doc__,
|
||||
"__reduce__($self, /)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define PARAMSPEC_REDUCE_METHODDEF \
|
||||
{"__reduce__", (PyCFunction)paramspec_reduce, METH_NOARGS, paramspec_reduce__doc__},
|
||||
|
||||
static PyObject *
|
||||
paramspec_reduce_impl(paramspecobject *self);
|
||||
|
||||
static PyObject *
|
||||
paramspec_reduce(paramspecobject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return paramspec_reduce_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(typevartuple__doc__,
|
||||
"typevartuple(name)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Create a new TypeVarTuple with the given name.");
|
||||
|
||||
static PyObject *
|
||||
typevartuple_impl(PyTypeObject *type, PyObject *name);
|
||||
|
||||
static PyObject *
|
||||
typevartuple(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 1
|
||||
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), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"name", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "typevartuple",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[1];
|
||||
PyObject * const *fastargs;
|
||||
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
|
||||
PyObject *name;
|
||||
|
||||
fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf);
|
||||
if (!fastargs) {
|
||||
goto exit;
|
||||
}
|
||||
if (!PyUnicode_Check(fastargs[0])) {
|
||||
_PyArg_BadArgument("typevartuple", "argument 'name'", "str", fastargs[0]);
|
||||
goto exit;
|
||||
}
|
||||
name = fastargs[0];
|
||||
return_value = typevartuple_impl(type, name);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(typevartuple_typing_subst__doc__,
|
||||
"__typing_subst__($self, /, arg)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define TYPEVARTUPLE_TYPING_SUBST_METHODDEF \
|
||||
{"__typing_subst__", _PyCFunction_CAST(typevartuple_typing_subst), METH_FASTCALL|METH_KEYWORDS, typevartuple_typing_subst__doc__},
|
||||
|
||||
static PyObject *
|
||||
typevartuple_typing_subst_impl(typevartupleobject *self, PyObject *arg);
|
||||
|
||||
static PyObject *
|
||||
typevartuple_typing_subst(typevartupleobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 1
|
||||
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(arg), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"arg", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "__typing_subst__",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[1];
|
||||
PyObject *arg;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
|
||||
if (!args) {
|
||||
goto exit;
|
||||
}
|
||||
arg = args[0];
|
||||
return_value = typevartuple_typing_subst_impl(self, arg);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(typevartuple_typing_prepare_subst__doc__,
|
||||
"__typing_prepare_subst__($self, /, alias, args)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define TYPEVARTUPLE_TYPING_PREPARE_SUBST_METHODDEF \
|
||||
{"__typing_prepare_subst__", _PyCFunction_CAST(typevartuple_typing_prepare_subst), METH_FASTCALL|METH_KEYWORDS, typevartuple_typing_prepare_subst__doc__},
|
||||
|
||||
static PyObject *
|
||||
typevartuple_typing_prepare_subst_impl(typevartupleobject *self,
|
||||
PyObject *alias, PyObject *args);
|
||||
|
||||
static PyObject *
|
||||
typevartuple_typing_prepare_subst(typevartupleobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 2
|
||||
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(alias), &_Py_ID(args), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"alias", "args", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "__typing_prepare_subst__",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[2];
|
||||
PyObject *alias;
|
||||
PyObject *__clinic_args;
|
||||
|
||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
|
||||
if (!args) {
|
||||
goto exit;
|
||||
}
|
||||
alias = args[0];
|
||||
__clinic_args = args[1];
|
||||
return_value = typevartuple_typing_prepare_subst_impl(self, alias, __clinic_args);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(typevartuple_reduce__doc__,
|
||||
"__reduce__($self, /)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define TYPEVARTUPLE_REDUCE_METHODDEF \
|
||||
{"__reduce__", (PyCFunction)typevartuple_reduce, METH_NOARGS, typevartuple_reduce__doc__},
|
||||
|
||||
static PyObject *
|
||||
typevartuple_reduce_impl(typevartupleobject *self);
|
||||
|
||||
static PyObject *
|
||||
typevartuple_reduce(typevartupleobject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return typevartuple_reduce_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(typealias_reduce__doc__,
|
||||
"__reduce__($self, /)\n"
|
||||
"--\n"
|
||||
"\n");
|
||||
|
||||
#define TYPEALIAS_REDUCE_METHODDEF \
|
||||
{"__reduce__", (PyCFunction)typealias_reduce, METH_NOARGS, typealias_reduce__doc__},
|
||||
|
||||
static PyObject *
|
||||
typealias_reduce_impl(typealiasobject *self);
|
||||
|
||||
static PyObject *
|
||||
typealias_reduce(typealiasobject *self, PyObject *Py_UNUSED(ignored))
|
||||
{
|
||||
return typealias_reduce_impl(self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(typealias_new__doc__,
|
||||
"typealias(name, value, *, type_params=<unrepresentable>)\n"
|
||||
"--\n"
|
||||
"\n"
|
||||
"Create a TypeAliasType.");
|
||||
|
||||
static PyObject *
|
||||
typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value,
|
||||
PyObject *type_params);
|
||||
|
||||
static PyObject *
|
||||
typealias_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
PyObject *return_value = NULL;
|
||||
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
|
||||
|
||||
#define NUM_KEYWORDS 3
|
||||
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(value), &_Py_ID(type_params), },
|
||||
};
|
||||
#undef NUM_KEYWORDS
|
||||
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
|
||||
|
||||
#else // !Py_BUILD_CORE
|
||||
# define KWTUPLE NULL
|
||||
#endif // !Py_BUILD_CORE
|
||||
|
||||
static const char * const _keywords[] = {"name", "value", "type_params", NULL};
|
||||
static _PyArg_Parser _parser = {
|
||||
.keywords = _keywords,
|
||||
.fname = "typealias",
|
||||
.kwtuple = KWTUPLE,
|
||||
};
|
||||
#undef KWTUPLE
|
||||
PyObject *argsbuf[3];
|
||||
PyObject * const *fastargs;
|
||||
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
|
||||
Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 2;
|
||||
PyObject *name;
|
||||
PyObject *value;
|
||||
PyObject *type_params = NULL;
|
||||
|
||||
fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 2, 2, 0, argsbuf);
|
||||
if (!fastargs) {
|
||||
goto exit;
|
||||
}
|
||||
if (!PyUnicode_Check(fastargs[0])) {
|
||||
_PyArg_BadArgument("typealias", "argument 'name'", "str", fastargs[0]);
|
||||
goto exit;
|
||||
}
|
||||
name = fastargs[0];
|
||||
value = fastargs[1];
|
||||
if (!noptargs) {
|
||||
goto skip_optional_kwonly;
|
||||
}
|
||||
type_params = fastargs[2];
|
||||
skip_optional_kwonly:
|
||||
return_value = typealias_new_impl(type, name, value, type_params);
|
||||
|
||||
exit:
|
||||
return return_value;
|
||||
}
|
||||
/*[clinic end generated code: output=807bcd30ebd10ac3 input=a9049054013a1b77]*/
|
||||
|
|
@ -127,6 +127,7 @@ _PyFunction_FromConstructor(PyFrameConstructor *constr)
|
|||
PyErr_Clear();
|
||||
}
|
||||
op->func_annotations = NULL;
|
||||
op->func_typeparams = NULL;
|
||||
op->vectorcall = _PyFunction_Vectorcall;
|
||||
op->func_version = 0;
|
||||
_PyObject_GC_TRACK(op);
|
||||
|
|
@ -202,6 +203,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
|
|||
op->func_weakreflist = NULL;
|
||||
op->func_module = module;
|
||||
op->func_annotations = NULL;
|
||||
op->func_typeparams = NULL;
|
||||
op->vectorcall = _PyFunction_Vectorcall;
|
||||
op->func_version = 0;
|
||||
_PyObject_GC_TRACK(op);
|
||||
|
|
@ -652,6 +654,28 @@ func_set_annotations(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(igno
|
|||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
func_get_type_params(PyFunctionObject *op, void *Py_UNUSED(ignored))
|
||||
{
|
||||
if (op->func_typeparams == NULL) {
|
||||
return PyTuple_New(0);
|
||||
}
|
||||
|
||||
assert(PyTuple_Check(op->func_typeparams));
|
||||
return Py_NewRef(op->func_typeparams);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
_Py_set_function_type_params(PyThreadState *Py_UNUSED(ignored), PyObject *func,
|
||||
PyObject *type_params)
|
||||
{
|
||||
assert(PyFunction_Check(func));
|
||||
assert(PyTuple_Check(type_params));
|
||||
PyFunctionObject *f = (PyFunctionObject *)func;
|
||||
Py_XSETREF(f->func_typeparams, Py_NewRef(type_params));
|
||||
return Py_NewRef(func);
|
||||
}
|
||||
|
||||
static PyGetSetDef func_getsetlist[] = {
|
||||
{"__code__", (getter)func_get_code, (setter)func_set_code},
|
||||
{"__defaults__", (getter)func_get_defaults,
|
||||
|
|
@ -663,6 +687,7 @@ static PyGetSetDef func_getsetlist[] = {
|
|||
{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
|
||||
{"__name__", (getter)func_get_name, (setter)func_set_name},
|
||||
{"__qualname__", (getter)func_get_qualname, (setter)func_set_qualname},
|
||||
{"__type_params__", (getter)func_get_type_params, NULL},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
|
@ -783,6 +808,7 @@ func_clear(PyFunctionObject *op)
|
|||
Py_CLEAR(op->func_dict);
|
||||
Py_CLEAR(op->func_closure);
|
||||
Py_CLEAR(op->func_annotations);
|
||||
Py_CLEAR(op->func_typeparams);
|
||||
// Don't Py_CLEAR(op->func_code), since code is always required
|
||||
// to be non-NULL. Similarly, name and qualname shouldn't be NULL.
|
||||
// However, name and qualname could be str subclasses, so they
|
||||
|
|
@ -837,6 +863,7 @@ func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
|
|||
Py_VISIT(f->func_dict);
|
||||
Py_VISIT(f->func_closure);
|
||||
Py_VISIT(f->func_annotations);
|
||||
Py_VISIT(f->func_typeparams);
|
||||
Py_VISIT(f->func_qualname);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
|
||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||
#include "pycore_symtable.h" // PySTEntry_Type
|
||||
#include "pycore_typevarobject.h" // _PyTypeVar_Type etc., _Py_initialize_generic
|
||||
#include "pycore_typeobject.h" // _PyBufferWrapper_Type
|
||||
#include "pycore_unionobject.h" // _PyUnion_Type
|
||||
#include "pycore_interpreteridobject.h" // _PyInterpreterID_Type
|
||||
|
|
@ -2139,6 +2140,11 @@ _PyTypes_InitTypes(PyInterpreterState *interp)
|
|||
}
|
||||
}
|
||||
|
||||
// Must be after static types are initialized
|
||||
if (_Py_initialize_generic(interp) < 0) {
|
||||
return _PyStatus_ERR("Can't initialize generic types");
|
||||
}
|
||||
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1460,6 +1460,18 @@ type_get_annotations(PyTypeObject *type, void *context)
|
|||
return annotations;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
type_get_type_params(PyTypeObject *type, void *context)
|
||||
{
|
||||
PyObject *params = PyDict_GetItem(lookup_tp_dict(type), &_Py_ID(__type_params__));
|
||||
|
||||
if (params) {
|
||||
return Py_NewRef(params);
|
||||
}
|
||||
|
||||
return PyTuple_New(0);
|
||||
}
|
||||
|
||||
static int
|
||||
type_set_annotations(PyTypeObject *type, PyObject *value, void *context)
|
||||
{
|
||||
|
|
@ -1536,6 +1548,7 @@ static PyGetSetDef type_getsets[] = {
|
|||
{"__doc__", (getter)type_get_doc, (setter)type_set_doc, NULL},
|
||||
{"__text_signature__", (getter)type_get_text_signature, NULL, NULL},
|
||||
{"__annotations__", (getter)type_get_annotations, (setter)type_set_annotations, NULL},
|
||||
{"__type_params__", (getter)type_get_type_params, NULL, NULL},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
@ -3130,11 +3143,12 @@ type_new_copy_slots(type_new_ctx *ctx, PyObject *dict)
|
|||
goto error;
|
||||
}
|
||||
if (r > 0) {
|
||||
/* CPython inserts __qualname__ and __classcell__ (when needed)
|
||||
/* CPython inserts these names (when needed)
|
||||
into the namespace when creating a class. They will be deleted
|
||||
below so won't act as class variables. */
|
||||
if (!_PyUnicode_Equal(slot, &_Py_ID(__qualname__)) &&
|
||||
!_PyUnicode_Equal(slot, &_Py_ID(__classcell__)))
|
||||
!_PyUnicode_Equal(slot, &_Py_ID(__classcell__)) &&
|
||||
!_PyUnicode_Equal(slot, &_Py_ID(__classdictcell__)))
|
||||
{
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"%R in __slots__ conflicts with class variable",
|
||||
|
|
@ -3585,6 +3599,32 @@ type_new_set_classcell(PyTypeObject *type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
type_new_set_classdictcell(PyTypeObject *type)
|
||||
{
|
||||
PyObject *dict = lookup_tp_dict(type);
|
||||
PyObject *cell = PyDict_GetItemWithError(dict, &_Py_ID(__classdictcell__));
|
||||
if (cell == NULL) {
|
||||
if (PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* At least one method requires a reference to the dict of its defining class */
|
||||
if (!PyCell_Check(cell)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"__classdictcell__ must be a nonlocal cell, not %.200R",
|
||||
Py_TYPE(cell));
|
||||
return -1;
|
||||
}
|
||||
|
||||
(void)PyCell_Set(cell, (PyObject *)dict);
|
||||
if (PyDict_DelItem(dict, &_Py_ID(__classdictcell__)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
type_new_set_attrs(const type_new_ctx *ctx, PyTypeObject *type)
|
||||
|
|
@ -3629,6 +3669,9 @@ type_new_set_attrs(const type_new_ctx *ctx, PyTypeObject *type)
|
|||
if (type_new_set_classcell(type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (type_new_set_classdictcell(type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
1620
Objects/typevarobject.c
Normal file
1620
Objects/typevarobject.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -147,10 +147,14 @@ get_types(PyObject **obj, Py_ssize_t *size)
|
|||
static int
|
||||
is_unionable(PyObject *obj)
|
||||
{
|
||||
return (obj == Py_None ||
|
||||
if (obj == Py_None ||
|
||||
PyType_Check(obj) ||
|
||||
_PyGenericAlias_Check(obj) ||
|
||||
_PyUnion_Check(obj));
|
||||
_PyUnion_Check(obj)) {
|
||||
return 1;
|
||||
}
|
||||
PyInterpreterState *interp = PyInterpreterState_Get();
|
||||
return Py_IS_TYPE(obj, interp->cached_objects.typealias_type);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue