mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
gh-111178: fix UBSan failures in Objects/typevarobject.c
(GH-129800)
Fix UBSan failures for `typealiasobject`, `paramspecobject`, `typevarobject`, `typevartupleobject`, `paramspecattrobject` Use _PyCFunction_CAST macros Use macro for `constevaluatorobject` casts
This commit is contained in:
parent
ead091357d
commit
ecde940025
1 changed files with 114 additions and 89 deletions
|
@ -57,6 +57,11 @@ typedef struct {
|
||||||
PyObject *module;
|
PyObject *module;
|
||||||
} typealiasobject;
|
} typealiasobject;
|
||||||
|
|
||||||
|
#define typevarobject_CAST(op) ((typevarobject *)(op))
|
||||||
|
#define typevartupleobject_CAST(op) ((typevartupleobject *)(op))
|
||||||
|
#define paramspecobject_CAST(op) ((paramspecobject *)(op))
|
||||||
|
#define typealiasobject_CAST(op) ((typealiasobject *)(op))
|
||||||
|
|
||||||
#include "clinic/typevarobject.c.h"
|
#include "clinic/typevarobject.c.h"
|
||||||
|
|
||||||
/* NoDefault is a marker object to indicate that a parameter has no default. */
|
/* NoDefault is a marker object to indicate that a parameter has no default. */
|
||||||
|
@ -121,11 +126,13 @@ typedef struct {
|
||||||
PyObject *value;
|
PyObject *value;
|
||||||
} constevaluatorobject;
|
} constevaluatorobject;
|
||||||
|
|
||||||
|
#define constevaluatorobject_CAST(op) ((constevaluatorobject *)(op))
|
||||||
|
|
||||||
static void
|
static void
|
||||||
constevaluator_dealloc(PyObject *self)
|
constevaluator_dealloc(PyObject *self)
|
||||||
{
|
{
|
||||||
PyTypeObject *tp = Py_TYPE(self);
|
PyTypeObject *tp = Py_TYPE(self);
|
||||||
constevaluatorobject *ce = (constevaluatorobject *)self;
|
constevaluatorobject *ce = constevaluatorobject_CAST(self);
|
||||||
|
|
||||||
_PyObject_GC_UNTRACK(self);
|
_PyObject_GC_UNTRACK(self);
|
||||||
|
|
||||||
|
@ -138,7 +145,7 @@ constevaluator_dealloc(PyObject *self)
|
||||||
static int
|
static int
|
||||||
constevaluator_traverse(PyObject *self, visitproc visit, void *arg)
|
constevaluator_traverse(PyObject *self, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
constevaluatorobject *ce = (constevaluatorobject *)self;
|
constevaluatorobject *ce = constevaluatorobject_CAST(self);
|
||||||
Py_VISIT(ce->value);
|
Py_VISIT(ce->value);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -146,20 +153,22 @@ constevaluator_traverse(PyObject *self, visitproc visit, void *arg)
|
||||||
static int
|
static int
|
||||||
constevaluator_clear(PyObject *self)
|
constevaluator_clear(PyObject *self)
|
||||||
{
|
{
|
||||||
Py_CLEAR(((constevaluatorobject *)self)->value);
|
constevaluatorobject *ce = constevaluatorobject_CAST(self);
|
||||||
|
Py_CLEAR(ce->value);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
constevaluator_repr(PyObject *self)
|
constevaluator_repr(PyObject *self)
|
||||||
{
|
{
|
||||||
PyObject *value = ((constevaluatorobject *)self)->value;
|
constevaluatorobject *ce = constevaluatorobject_CAST(self);
|
||||||
return PyUnicode_FromFormat("<constevaluator %R>", value);
|
return PyUnicode_FromFormat("<constevaluator %R>", ce->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
constevaluator_call(PyObject *self, PyObject *args, PyObject *kwargs)
|
constevaluator_call(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
|
constevaluatorobject *ce = constevaluatorobject_CAST(self);
|
||||||
if (!_PyArg_NoKeywords("constevaluator.__call__", kwargs)) {
|
if (!_PyArg_NoKeywords("constevaluator.__call__", kwargs)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -167,7 +176,7 @@ constevaluator_call(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
if (!PyArg_ParseTuple(args, "i:constevaluator.__call__", &format)) {
|
if (!PyArg_ParseTuple(args, "i:constevaluator.__call__", &format)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyObject *value = ((constevaluatorobject *)self)->value;
|
PyObject *value = ce->value;
|
||||||
if (format == _Py_ANNOTATE_FORMAT_STRING) {
|
if (format == _Py_ANNOTATE_FORMAT_STRING) {
|
||||||
PyUnicodeWriter *writer = PyUnicodeWriter_Create(5); // cannot be <5
|
PyUnicodeWriter *writer = PyUnicodeWriter_Create(5); // cannot be <5
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
|
@ -453,7 +462,7 @@ static void
|
||||||
typevar_dealloc(PyObject *self)
|
typevar_dealloc(PyObject *self)
|
||||||
{
|
{
|
||||||
PyTypeObject *tp = Py_TYPE(self);
|
PyTypeObject *tp = Py_TYPE(self);
|
||||||
typevarobject *tv = (typevarobject *)self;
|
typevarobject *tv = typevarobject_CAST(self);
|
||||||
|
|
||||||
_PyObject_GC_UNTRACK(self);
|
_PyObject_GC_UNTRACK(self);
|
||||||
|
|
||||||
|
@ -475,7 +484,7 @@ static int
|
||||||
typevar_traverse(PyObject *self, visitproc visit, void *arg)
|
typevar_traverse(PyObject *self, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
Py_VISIT(Py_TYPE(self));
|
Py_VISIT(Py_TYPE(self));
|
||||||
typevarobject *tv = (typevarobject *)self;
|
typevarobject *tv = typevarobject_CAST(self);
|
||||||
Py_VISIT(tv->bound);
|
Py_VISIT(tv->bound);
|
||||||
Py_VISIT(tv->evaluate_bound);
|
Py_VISIT(tv->evaluate_bound);
|
||||||
Py_VISIT(tv->constraints);
|
Py_VISIT(tv->constraints);
|
||||||
|
@ -487,22 +496,23 @@ typevar_traverse(PyObject *self, visitproc visit, void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
typevar_clear(typevarobject *self)
|
typevar_clear(PyObject *op)
|
||||||
{
|
{
|
||||||
|
typevarobject *self = typevarobject_CAST(op);
|
||||||
Py_CLEAR(self->bound);
|
Py_CLEAR(self->bound);
|
||||||
Py_CLEAR(self->evaluate_bound);
|
Py_CLEAR(self->evaluate_bound);
|
||||||
Py_CLEAR(self->constraints);
|
Py_CLEAR(self->constraints);
|
||||||
Py_CLEAR(self->evaluate_constraints);
|
Py_CLEAR(self->evaluate_constraints);
|
||||||
Py_CLEAR(self->default_value);
|
Py_CLEAR(self->default_value);
|
||||||
Py_CLEAR(self->evaluate_default);
|
Py_CLEAR(self->evaluate_default);
|
||||||
PyObject_ClearManagedDict((PyObject *)self);
|
PyObject_ClearManagedDict(op);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typevar_repr(PyObject *self)
|
typevar_repr(PyObject *self)
|
||||||
{
|
{
|
||||||
typevarobject *tv = (typevarobject *)self;
|
typevarobject *tv = typevarobject_CAST(self);
|
||||||
|
|
||||||
if (tv->infer_variance) {
|
if (tv->infer_variance) {
|
||||||
return Py_NewRef(tv->name);
|
return Py_NewRef(tv->name);
|
||||||
|
@ -521,8 +531,9 @@ static PyMemberDef typevar_members[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typevar_bound(typevarobject *self, void *Py_UNUSED(ignored))
|
typevar_bound(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
typevarobject *self = typevarobject_CAST(op);
|
||||||
if (self->bound != NULL) {
|
if (self->bound != NULL) {
|
||||||
return Py_NewRef(self->bound);
|
return Py_NewRef(self->bound);
|
||||||
}
|
}
|
||||||
|
@ -535,8 +546,9 @@ typevar_bound(typevarobject *self, void *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typevar_default(typevarobject *self, void *unused)
|
typevar_default(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
typevarobject *self = typevarobject_CAST(op);
|
||||||
if (self->default_value != NULL) {
|
if (self->default_value != NULL) {
|
||||||
return Py_NewRef(self->default_value);
|
return Py_NewRef(self->default_value);
|
||||||
}
|
}
|
||||||
|
@ -549,8 +561,9 @@ typevar_default(typevarobject *self, void *unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typevar_constraints(typevarobject *self, void *Py_UNUSED(ignored))
|
typevar_constraints(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
typevarobject *self = typevarobject_CAST(op);
|
||||||
if (self->constraints != NULL) {
|
if (self->constraints != NULL) {
|
||||||
return Py_NewRef(self->constraints);
|
return Py_NewRef(self->constraints);
|
||||||
}
|
}
|
||||||
|
@ -563,8 +576,9 @@ typevar_constraints(typevarobject *self, void *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typevar_evaluate_bound(typevarobject *self, void *Py_UNUSED(ignored))
|
typevar_evaluate_bound(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
typevarobject *self = typevarobject_CAST(op);
|
||||||
if (self->evaluate_bound != NULL) {
|
if (self->evaluate_bound != NULL) {
|
||||||
return Py_NewRef(self->evaluate_bound);
|
return Py_NewRef(self->evaluate_bound);
|
||||||
}
|
}
|
||||||
|
@ -575,8 +589,9 @@ typevar_evaluate_bound(typevarobject *self, void *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typevar_evaluate_constraints(typevarobject *self, void *Py_UNUSED(ignored))
|
typevar_evaluate_constraints(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
typevarobject *self = typevarobject_CAST(op);
|
||||||
if (self->evaluate_constraints != NULL) {
|
if (self->evaluate_constraints != NULL) {
|
||||||
return Py_NewRef(self->evaluate_constraints);
|
return Py_NewRef(self->evaluate_constraints);
|
||||||
}
|
}
|
||||||
|
@ -587,8 +602,9 @@ typevar_evaluate_constraints(typevarobject *self, void *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typevar_evaluate_default(typevarobject *self, void *Py_UNUSED(ignored))
|
typevar_evaluate_default(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
typevarobject *self = typevarobject_CAST(op);
|
||||||
if (self->evaluate_default != NULL) {
|
if (self->evaluate_default != NULL) {
|
||||||
return Py_NewRef(self->evaluate_default);
|
return Py_NewRef(self->evaluate_default);
|
||||||
}
|
}
|
||||||
|
@ -599,12 +615,12 @@ typevar_evaluate_default(typevarobject *self, void *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyGetSetDef typevar_getset[] = {
|
static PyGetSetDef typevar_getset[] = {
|
||||||
{"__bound__", (getter)typevar_bound, NULL, NULL, NULL},
|
{"__bound__", typevar_bound, NULL, NULL, NULL},
|
||||||
{"__constraints__", (getter)typevar_constraints, NULL, NULL, NULL},
|
{"__constraints__", typevar_constraints, NULL, NULL, NULL},
|
||||||
{"__default__", (getter)typevar_default, NULL, NULL, NULL},
|
{"__default__", typevar_default, NULL, NULL, NULL},
|
||||||
{"evaluate_bound", (getter)typevar_evaluate_bound, NULL, NULL, NULL},
|
{"evaluate_bound", typevar_evaluate_bound, NULL, NULL, NULL},
|
||||||
{"evaluate_constraints", (getter)typevar_evaluate_constraints, NULL, NULL, NULL},
|
{"evaluate_constraints", typevar_evaluate_constraints, NULL, NULL, NULL},
|
||||||
{"evaluate_default", (getter)typevar_evaluate_default, NULL, NULL, NULL},
|
{"evaluate_default", typevar_evaluate_default, NULL, NULL, NULL},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -772,7 +788,7 @@ typevar_typing_prepare_subst_impl(typevarobject *self, PyObject *alias,
|
||||||
}
|
}
|
||||||
else if (i == args_len) {
|
else if (i == args_len) {
|
||||||
// If the TypeVar has a default, use it.
|
// If the TypeVar has a default, use it.
|
||||||
PyObject *dflt = typevar_default(self, NULL);
|
PyObject *dflt = typevar_default((PyObject *)self, NULL);
|
||||||
if (dflt == NULL) {
|
if (dflt == NULL) {
|
||||||
Py_DECREF(params);
|
Py_DECREF(params);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -918,11 +934,13 @@ typedef struct {
|
||||||
PyObject *__origin__;
|
PyObject *__origin__;
|
||||||
} paramspecattrobject;
|
} paramspecattrobject;
|
||||||
|
|
||||||
|
#define paramspecattrobject_CAST(op) ((paramspecattrobject *)(op))
|
||||||
|
|
||||||
static void
|
static void
|
||||||
paramspecattr_dealloc(PyObject *self)
|
paramspecattr_dealloc(PyObject *self)
|
||||||
{
|
{
|
||||||
PyTypeObject *tp = Py_TYPE(self);
|
PyTypeObject *tp = Py_TYPE(self);
|
||||||
paramspecattrobject *psa = (paramspecattrobject *)self;
|
paramspecattrobject *psa = paramspecattrobject_CAST(self);
|
||||||
|
|
||||||
_PyObject_GC_UNTRACK(self);
|
_PyObject_GC_UNTRACK(self);
|
||||||
|
|
||||||
|
@ -935,14 +953,15 @@ paramspecattr_dealloc(PyObject *self)
|
||||||
static int
|
static int
|
||||||
paramspecattr_traverse(PyObject *self, visitproc visit, void *arg)
|
paramspecattr_traverse(PyObject *self, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
paramspecattrobject *psa = (paramspecattrobject *)self;
|
paramspecattrobject *psa = paramspecattrobject_CAST(self);
|
||||||
Py_VISIT(psa->__origin__);
|
Py_VISIT(psa->__origin__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
paramspecattr_clear(paramspecattrobject *self)
|
paramspecattr_clear(PyObject *op)
|
||||||
{
|
{
|
||||||
|
paramspecattrobject *self = paramspecattrobject_CAST(op);
|
||||||
Py_CLEAR(self->__origin__);
|
Py_CLEAR(self->__origin__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -956,11 +975,9 @@ paramspecattr_richcompare(PyObject *a, PyObject *b, int op)
|
||||||
if (op != Py_EQ && op != Py_NE) {
|
if (op != Py_EQ && op != Py_NE) {
|
||||||
Py_RETURN_NOTIMPLEMENTED;
|
Py_RETURN_NOTIMPLEMENTED;
|
||||||
}
|
}
|
||||||
return PyObject_RichCompare(
|
paramspecattrobject *lhs = paramspecattrobject_CAST(a); // may be unsafe
|
||||||
((paramspecattrobject *)a)->__origin__,
|
paramspecattrobject *rhs = (paramspecattrobject *)b; // safe fast cast
|
||||||
((paramspecattrobject *)b)->__origin__,
|
return PyObject_RichCompare(lhs->__origin__, rhs->__origin__, op);
|
||||||
op
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMemberDef paramspecattr_members[] = {
|
static PyMemberDef paramspecattr_members[] = {
|
||||||
|
@ -983,8 +1000,7 @@ paramspecattr_new(PyTypeObject *tp, PyObject *origin)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
paramspecargs_repr(PyObject *self)
|
paramspecargs_repr(PyObject *self)
|
||||||
{
|
{
|
||||||
paramspecattrobject *psa = (paramspecattrobject *)self;
|
paramspecattrobject *psa = paramspecattrobject_CAST(self);
|
||||||
|
|
||||||
PyTypeObject *tp = _PyInterpreterState_GET()->cached_objects.paramspec_type;
|
PyTypeObject *tp = _PyInterpreterState_GET()->cached_objects.paramspec_type;
|
||||||
if (Py_IS_TYPE(psa->__origin__, tp)) {
|
if (Py_IS_TYPE(psa->__origin__, tp)) {
|
||||||
return PyUnicode_FromFormat("%U.args",
|
return PyUnicode_FromFormat("%U.args",
|
||||||
|
@ -1046,7 +1062,7 @@ static PyType_Slot paramspecargs_slots[] = {
|
||||||
{Py_tp_alloc, PyType_GenericAlloc},
|
{Py_tp_alloc, PyType_GenericAlloc},
|
||||||
{Py_tp_free, PyObject_GC_Del},
|
{Py_tp_free, PyObject_GC_Del},
|
||||||
{Py_tp_traverse, paramspecattr_traverse},
|
{Py_tp_traverse, paramspecattr_traverse},
|
||||||
{Py_tp_clear, (inquiry)paramspecattr_clear},
|
{Py_tp_clear, paramspecattr_clear},
|
||||||
{Py_tp_repr, paramspecargs_repr},
|
{Py_tp_repr, paramspecargs_repr},
|
||||||
{Py_tp_members, paramspecattr_members},
|
{Py_tp_members, paramspecattr_members},
|
||||||
{Py_tp_richcompare, paramspecattr_richcompare},
|
{Py_tp_richcompare, paramspecattr_richcompare},
|
||||||
|
@ -1064,7 +1080,7 @@ PyType_Spec paramspecargs_spec = {
|
||||||
static PyObject *
|
static PyObject *
|
||||||
paramspeckwargs_repr(PyObject *self)
|
paramspeckwargs_repr(PyObject *self)
|
||||||
{
|
{
|
||||||
paramspecattrobject *psk = (paramspecattrobject *)self;
|
paramspecattrobject *psk = paramspecattrobject_CAST(self);
|
||||||
|
|
||||||
PyTypeObject *tp = _PyInterpreterState_GET()->cached_objects.paramspec_type;
|
PyTypeObject *tp = _PyInterpreterState_GET()->cached_objects.paramspec_type;
|
||||||
if (Py_IS_TYPE(psk->__origin__, tp)) {
|
if (Py_IS_TYPE(psk->__origin__, tp)) {
|
||||||
|
@ -1126,7 +1142,7 @@ static PyType_Slot paramspeckwargs_slots[] = {
|
||||||
{Py_tp_alloc, PyType_GenericAlloc},
|
{Py_tp_alloc, PyType_GenericAlloc},
|
||||||
{Py_tp_free, PyObject_GC_Del},
|
{Py_tp_free, PyObject_GC_Del},
|
||||||
{Py_tp_traverse, paramspecattr_traverse},
|
{Py_tp_traverse, paramspecattr_traverse},
|
||||||
{Py_tp_clear, (inquiry)paramspecattr_clear},
|
{Py_tp_clear, paramspecattr_clear},
|
||||||
{Py_tp_repr, paramspeckwargs_repr},
|
{Py_tp_repr, paramspeckwargs_repr},
|
||||||
{Py_tp_members, paramspecattr_members},
|
{Py_tp_members, paramspecattr_members},
|
||||||
{Py_tp_richcompare, paramspecattr_richcompare},
|
{Py_tp_richcompare, paramspecattr_richcompare},
|
||||||
|
@ -1145,7 +1161,7 @@ static void
|
||||||
paramspec_dealloc(PyObject *self)
|
paramspec_dealloc(PyObject *self)
|
||||||
{
|
{
|
||||||
PyTypeObject *tp = Py_TYPE(self);
|
PyTypeObject *tp = Py_TYPE(self);
|
||||||
paramspecobject *ps = (paramspecobject *)self;
|
paramspecobject *ps = paramspecobject_CAST(self);
|
||||||
|
|
||||||
_PyObject_GC_UNTRACK(self);
|
_PyObject_GC_UNTRACK(self);
|
||||||
|
|
||||||
|
@ -1164,7 +1180,7 @@ static int
|
||||||
paramspec_traverse(PyObject *self, visitproc visit, void *arg)
|
paramspec_traverse(PyObject *self, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
Py_VISIT(Py_TYPE(self));
|
Py_VISIT(Py_TYPE(self));
|
||||||
paramspecobject *ps = (paramspecobject *)self;
|
paramspecobject *ps = paramspecobject_CAST(self);
|
||||||
Py_VISIT(ps->bound);
|
Py_VISIT(ps->bound);
|
||||||
Py_VISIT(ps->default_value);
|
Py_VISIT(ps->default_value);
|
||||||
Py_VISIT(ps->evaluate_default);
|
Py_VISIT(ps->evaluate_default);
|
||||||
|
@ -1173,19 +1189,20 @@ paramspec_traverse(PyObject *self, visitproc visit, void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
paramspec_clear(paramspecobject *self)
|
paramspec_clear(PyObject *op)
|
||||||
{
|
{
|
||||||
|
paramspecobject *self = paramspecobject_CAST(op);
|
||||||
Py_CLEAR(self->bound);
|
Py_CLEAR(self->bound);
|
||||||
Py_CLEAR(self->default_value);
|
Py_CLEAR(self->default_value);
|
||||||
Py_CLEAR(self->evaluate_default);
|
Py_CLEAR(self->evaluate_default);
|
||||||
PyObject_ClearManagedDict((PyObject *)self);
|
PyObject_ClearManagedDict(op);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
paramspec_repr(PyObject *self)
|
paramspec_repr(PyObject *self)
|
||||||
{
|
{
|
||||||
paramspecobject *ps = (paramspecobject *)self;
|
paramspecobject *ps = paramspecobject_CAST(self);
|
||||||
|
|
||||||
if (ps->infer_variance) {
|
if (ps->infer_variance) {
|
||||||
return Py_NewRef(ps->name);
|
return Py_NewRef(ps->name);
|
||||||
|
@ -1205,22 +1222,23 @@ static PyMemberDef paramspec_members[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
paramspec_args(PyObject *self, void *unused)
|
paramspec_args(PyObject *self, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
PyTypeObject *tp = _PyInterpreterState_GET()->cached_objects.paramspecargs_type;
|
PyTypeObject *tp = _PyInterpreterState_GET()->cached_objects.paramspecargs_type;
|
||||||
return (PyObject *)paramspecattr_new(tp, self);
|
return (PyObject *)paramspecattr_new(tp, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
paramspec_kwargs(PyObject *self, void *unused)
|
paramspec_kwargs(PyObject *self, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
PyTypeObject *tp = _PyInterpreterState_GET()->cached_objects.paramspeckwargs_type;
|
PyTypeObject *tp = _PyInterpreterState_GET()->cached_objects.paramspeckwargs_type;
|
||||||
return (PyObject *)paramspecattr_new(tp, self);
|
return (PyObject *)paramspecattr_new(tp, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
paramspec_default(paramspecobject *self, void *unused)
|
paramspec_default(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
paramspecobject *self = paramspecobject_CAST(op);
|
||||||
if (self->default_value != NULL) {
|
if (self->default_value != NULL) {
|
||||||
return Py_NewRef(self->default_value);
|
return Py_NewRef(self->default_value);
|
||||||
}
|
}
|
||||||
|
@ -1233,8 +1251,9 @@ paramspec_default(paramspecobject *self, void *unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
paramspec_evaluate_default(paramspecobject *self, void *unused)
|
paramspec_evaluate_default(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
paramspecobject *self = paramspecobject_CAST(op);
|
||||||
if (self->evaluate_default != NULL) {
|
if (self->evaluate_default != NULL) {
|
||||||
return Py_NewRef(self->evaluate_default);
|
return Py_NewRef(self->evaluate_default);
|
||||||
}
|
}
|
||||||
|
@ -1245,10 +1264,10 @@ paramspec_evaluate_default(paramspecobject *self, void *unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyGetSetDef paramspec_getset[] = {
|
static PyGetSetDef paramspec_getset[] = {
|
||||||
{"args", (getter)paramspec_args, NULL, PyDoc_STR("Represents positional arguments."), NULL},
|
{"args", paramspec_args, NULL, PyDoc_STR("Represents positional arguments."), NULL},
|
||||||
{"kwargs", (getter)paramspec_kwargs, NULL, PyDoc_STR("Represents keyword arguments."), NULL},
|
{"kwargs", paramspec_kwargs, NULL, PyDoc_STR("Represents keyword arguments."), NULL},
|
||||||
{"__default__", (getter)paramspec_default, NULL, "The default value for this ParamSpec.", NULL},
|
{"__default__", paramspec_default, NULL, "The default value for this ParamSpec.", NULL},
|
||||||
{"evaluate_default", (getter)paramspec_evaluate_default, NULL, NULL, NULL},
|
{"evaluate_default", paramspec_evaluate_default, NULL, NULL, NULL},
|
||||||
{0},
|
{0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1492,7 +1511,7 @@ typevartuple_dealloc(PyObject *self)
|
||||||
{
|
{
|
||||||
PyTypeObject *tp = Py_TYPE(self);
|
PyTypeObject *tp = Py_TYPE(self);
|
||||||
_PyObject_GC_UNTRACK(self);
|
_PyObject_GC_UNTRACK(self);
|
||||||
typevartupleobject *tvt = (typevartupleobject *)self;
|
typevartupleobject *tvt = typevartupleobject_CAST(self);
|
||||||
|
|
||||||
Py_DECREF(tvt->name);
|
Py_DECREF(tvt->name);
|
||||||
Py_XDECREF(tvt->default_value);
|
Py_XDECREF(tvt->default_value);
|
||||||
|
@ -1525,8 +1544,7 @@ typevartuple_iter(PyObject *self)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typevartuple_repr(PyObject *self)
|
typevartuple_repr(PyObject *self)
|
||||||
{
|
{
|
||||||
typevartupleobject *tvt = (typevartupleobject *)self;
|
typevartupleobject *tvt = typevartupleobject_CAST(self);
|
||||||
|
|
||||||
return Py_NewRef(tvt->name);
|
return Py_NewRef(tvt->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1658,8 +1676,9 @@ static int
|
||||||
typevartuple_traverse(PyObject *self, visitproc visit, void *arg)
|
typevartuple_traverse(PyObject *self, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
Py_VISIT(Py_TYPE(self));
|
Py_VISIT(Py_TYPE(self));
|
||||||
Py_VISIT(((typevartupleobject *)self)->default_value);
|
typevartupleobject *tvt = typevartupleobject_CAST(self);
|
||||||
Py_VISIT(((typevartupleobject *)self)->evaluate_default);
|
Py_VISIT(tvt->default_value);
|
||||||
|
Py_VISIT(tvt->evaluate_default);
|
||||||
PyObject_VisitManagedDict(self, visit, arg);
|
PyObject_VisitManagedDict(self, visit, arg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1667,15 +1686,17 @@ typevartuple_traverse(PyObject *self, visitproc visit, void *arg)
|
||||||
static int
|
static int
|
||||||
typevartuple_clear(PyObject *self)
|
typevartuple_clear(PyObject *self)
|
||||||
{
|
{
|
||||||
Py_CLEAR(((typevartupleobject *)self)->default_value);
|
typevartupleobject *tvt = typevartupleobject_CAST(self);
|
||||||
Py_CLEAR(((typevartupleobject *)self)->evaluate_default);
|
Py_CLEAR(tvt->default_value);
|
||||||
|
Py_CLEAR(tvt->evaluate_default);
|
||||||
PyObject_ClearManagedDict(self);
|
PyObject_ClearManagedDict(self);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typevartuple_default(typevartupleobject *self, void *unused)
|
typevartuple_default(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
typevartupleobject *self = typevartupleobject_CAST(op);
|
||||||
if (self->default_value != NULL) {
|
if (self->default_value != NULL) {
|
||||||
return Py_NewRef(self->default_value);
|
return Py_NewRef(self->default_value);
|
||||||
}
|
}
|
||||||
|
@ -1688,8 +1709,9 @@ typevartuple_default(typevartupleobject *self, void *unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typevartuple_evaluate_default(typevartupleobject *self, void *unused)
|
typevartuple_evaluate_default(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
typevartupleobject *self = typevartupleobject_CAST(op);
|
||||||
if (self->evaluate_default != NULL) {
|
if (self->evaluate_default != NULL) {
|
||||||
return Py_NewRef(self->evaluate_default);
|
return Py_NewRef(self->evaluate_default);
|
||||||
}
|
}
|
||||||
|
@ -1700,8 +1722,8 @@ typevartuple_evaluate_default(typevartupleobject *self, void *unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyGetSetDef typevartuple_getset[] = {
|
static PyGetSetDef typevartuple_getset[] = {
|
||||||
{"__default__", (getter)typevartuple_default, NULL, "The default value for this TypeVarTuple.", NULL},
|
{"__default__", typevartuple_default, NULL, "The default value for this TypeVarTuple.", NULL},
|
||||||
{"evaluate_default", (getter)typevartuple_evaluate_default, NULL, NULL, NULL},
|
{"evaluate_default", typevartuple_evaluate_default, NULL, NULL, NULL},
|
||||||
{0},
|
{0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1803,13 +1825,13 @@ static PyObject *
|
||||||
get_type_param_default(PyThreadState *ts, PyObject *typeparam) {
|
get_type_param_default(PyThreadState *ts, PyObject *typeparam) {
|
||||||
// Does not modify refcount of existing objects.
|
// Does not modify refcount of existing objects.
|
||||||
if (Py_IS_TYPE(typeparam, ts->interp->cached_objects.typevar_type)) {
|
if (Py_IS_TYPE(typeparam, ts->interp->cached_objects.typevar_type)) {
|
||||||
return typevar_default((typevarobject *)typeparam, NULL);
|
return typevar_default(typeparam, NULL);
|
||||||
}
|
}
|
||||||
else if (Py_IS_TYPE(typeparam, ts->interp->cached_objects.paramspec_type)) {
|
else if (Py_IS_TYPE(typeparam, ts->interp->cached_objects.paramspec_type)) {
|
||||||
return paramspec_default((paramspecobject *)typeparam, NULL);
|
return paramspec_default(typeparam, NULL);
|
||||||
}
|
}
|
||||||
else if (Py_IS_TYPE(typeparam, ts->interp->cached_objects.typevartuple_type)) {
|
else if (Py_IS_TYPE(typeparam, ts->interp->cached_objects.typevartuple_type)) {
|
||||||
return typevartuple_default((typevartupleobject *)typeparam, NULL);
|
return typevartuple_default(typeparam, NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyErr_Format(PyExc_TypeError, "Expected a type param, got %R", typeparam);
|
PyErr_Format(PyExc_TypeError, "Expected a type param, got %R", typeparam);
|
||||||
|
@ -1822,7 +1844,7 @@ typealias_dealloc(PyObject *self)
|
||||||
{
|
{
|
||||||
PyTypeObject *tp = Py_TYPE(self);
|
PyTypeObject *tp = Py_TYPE(self);
|
||||||
_PyObject_GC_UNTRACK(self);
|
_PyObject_GC_UNTRACK(self);
|
||||||
typealiasobject *ta = (typealiasobject *)self;
|
typealiasobject *ta = typealiasobject_CAST(self);
|
||||||
Py_DECREF(ta->name);
|
Py_DECREF(ta->name);
|
||||||
Py_XDECREF(ta->type_params);
|
Py_XDECREF(ta->type_params);
|
||||||
Py_XDECREF(ta->compute_value);
|
Py_XDECREF(ta->compute_value);
|
||||||
|
@ -1859,16 +1881,16 @@ static PyMemberDef typealias_members[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typealias_value(PyObject *self, void *unused)
|
typealias_value(PyObject *self, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
typealiasobject *ta = (typealiasobject *)self;
|
typealiasobject *ta = typealiasobject_CAST(self);
|
||||||
return typealias_get_value(ta);
|
return typealias_get_value(ta);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typealias_evaluate_value(PyObject *self, void *unused)
|
typealias_evaluate_value(PyObject *self, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
typealiasobject *ta = (typealiasobject *)self;
|
typealiasobject *ta = typealiasobject_CAST(self);
|
||||||
if (ta->compute_value != NULL) {
|
if (ta->compute_value != NULL) {
|
||||||
return Py_NewRef(ta->compute_value);
|
return Py_NewRef(ta->compute_value);
|
||||||
}
|
}
|
||||||
|
@ -1877,9 +1899,9 @@ typealias_evaluate_value(PyObject *self, void *unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typealias_parameters(PyObject *self, void *unused)
|
typealias_parameters(PyObject *self, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
typealiasobject *ta = (typealiasobject *)self;
|
typealiasobject *ta = typealiasobject_CAST(self);
|
||||||
if (ta->type_params == NULL) {
|
if (ta->type_params == NULL) {
|
||||||
return PyTuple_New(0);
|
return PyTuple_New(0);
|
||||||
}
|
}
|
||||||
|
@ -1887,9 +1909,9 @@ typealias_parameters(PyObject *self, void *unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typealias_type_params(PyObject *self, void *unused)
|
typealias_type_params(PyObject *self, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
typealiasobject *ta = (typealiasobject *)self;
|
typealiasobject *ta = typealiasobject_CAST(self);
|
||||||
if (ta->type_params == NULL) {
|
if (ta->type_params == NULL) {
|
||||||
return PyTuple_New(0);
|
return PyTuple_New(0);
|
||||||
}
|
}
|
||||||
|
@ -1897,9 +1919,9 @@ typealias_type_params(PyObject *self, void *unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typealias_module(PyObject *self, void *unused)
|
typealias_module(PyObject *self, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
typealiasobject *ta = (typealiasobject *)self;
|
typealiasobject *ta = typealiasobject_CAST(self);
|
||||||
if (ta->module != NULL) {
|
if (ta->module != NULL) {
|
||||||
return Py_NewRef(ta->module);
|
return Py_NewRef(ta->module);
|
||||||
}
|
}
|
||||||
|
@ -1916,11 +1938,11 @@ typealias_module(PyObject *self, void *unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyGetSetDef typealias_getset[] = {
|
static PyGetSetDef typealias_getset[] = {
|
||||||
{"__parameters__", typealias_parameters, (setter)NULL, NULL, NULL},
|
{"__parameters__", typealias_parameters, NULL, NULL, NULL},
|
||||||
{"__type_params__", typealias_type_params, (setter)NULL, NULL, NULL},
|
{"__type_params__", typealias_type_params, NULL, NULL, NULL},
|
||||||
{"__value__", typealias_value, (setter)NULL, NULL, NULL},
|
{"__value__", typealias_value, NULL, NULL, NULL},
|
||||||
{"evaluate_value", typealias_evaluate_value, (setter)NULL, NULL, NULL},
|
{"evaluate_value", typealias_evaluate_value, NULL, NULL, NULL},
|
||||||
{"__module__", typealias_module, (setter)NULL, NULL, NULL},
|
{"__module__", typealias_module, NULL, NULL, NULL},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2001,8 +2023,9 @@ typealias_alloc(PyObject *name, PyObject *type_params, PyObject *compute_value,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
typealias_traverse(typealiasobject *self, visitproc visit, void *arg)
|
typealias_traverse(PyObject *op, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
|
typealiasobject *self = typealiasobject_CAST(op);
|
||||||
Py_VISIT(self->type_params);
|
Py_VISIT(self->type_params);
|
||||||
Py_VISIT(self->compute_value);
|
Py_VISIT(self->compute_value);
|
||||||
Py_VISIT(self->value);
|
Py_VISIT(self->value);
|
||||||
|
@ -2011,8 +2034,9 @@ typealias_traverse(typealiasobject *self, visitproc visit, void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
typealias_clear(typealiasobject *self)
|
typealias_clear(PyObject *op)
|
||||||
{
|
{
|
||||||
|
typealiasobject *self = typealiasobject_CAST(op);
|
||||||
Py_CLEAR(self->type_params);
|
Py_CLEAR(self->type_params);
|
||||||
Py_CLEAR(self->compute_value);
|
Py_CLEAR(self->compute_value);
|
||||||
Py_CLEAR(self->value);
|
Py_CLEAR(self->value);
|
||||||
|
@ -2033,14 +2057,15 @@ typealias_reduce_impl(typealiasobject *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
typealias_subscript(PyObject *self, PyObject *args)
|
typealias_subscript(PyObject *op, PyObject *args)
|
||||||
{
|
{
|
||||||
if (((typealiasobject *)self)->type_params == NULL) {
|
typealiasobject *self = typealiasobject_CAST(op);
|
||||||
|
if (self->type_params == NULL) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"Only generic type aliases are subscriptable");
|
"Only generic type aliases are subscriptable");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return Py_GenericAlias(self, args);
|
return Py_GenericAlias(op, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef typealias_methods[] = {
|
static PyMethodDef typealias_methods[] = {
|
||||||
|
@ -2133,8 +2158,8 @@ PyTypeObject _PyTypeAlias_Type = {
|
||||||
.tp_dealloc = typealias_dealloc,
|
.tp_dealloc = typealias_dealloc,
|
||||||
.tp_new = typealias_new,
|
.tp_new = typealias_new,
|
||||||
.tp_free = PyObject_GC_Del,
|
.tp_free = PyObject_GC_Del,
|
||||||
.tp_traverse = (traverseproc)typealias_traverse,
|
.tp_traverse = typealias_traverse,
|
||||||
.tp_clear = (inquiry)typealias_clear,
|
.tp_clear = typealias_clear,
|
||||||
.tp_repr = typealias_repr,
|
.tp_repr = typealias_repr,
|
||||||
.tp_as_number = &typealias_as_number,
|
.tp_as_number = &typealias_as_number,
|
||||||
.tp_as_mapping = &typealias_as_mapping,
|
.tp_as_mapping = &typealias_as_mapping,
|
||||||
|
@ -2252,10 +2277,10 @@ _Py_subscript_generic(PyThreadState* unused, PyObject *params)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef generic_methods[] = {
|
static PyMethodDef generic_methods[] = {
|
||||||
{"__class_getitem__", (PyCFunction)(void (*)(void))generic_class_getitem,
|
{"__class_getitem__", _PyCFunction_CAST(generic_class_getitem),
|
||||||
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
|
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
|
||||||
generic_class_getitem_doc},
|
generic_class_getitem_doc},
|
||||||
{"__init_subclass__", (PyCFunction)(void (*)(void))generic_init_subclass,
|
{"__init_subclass__", _PyCFunction_CAST(generic_init_subclass),
|
||||||
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
|
METH_VARARGS | METH_KEYWORDS | METH_CLASS,
|
||||||
PyDoc_STR("Function to initialize subclasses.")},
|
PyDoc_STR("Function to initialize subclasses.")},
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue