mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-132661: Implement PEP 750 (#132662)
Co-authored-by: Lysandros Nikolaou <lisandrosnik@gmail.com> Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Wingy <git@wingysam.xyz> Co-authored-by: Koudai Aono <koxudaxi@gmail.com> Co-authored-by: Dave Peck <davepeck@gmail.com> Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu> Co-authored-by: Paul Everitt <pauleveritt@me.com> Co-authored-by: sobolevn <mail@sobolevn.me>
This commit is contained in:
parent
5ea9010e89
commit
60202609a2
81 changed files with 7716 additions and 3761 deletions
229
Objects/interpolationobject.c
Normal file
229
Objects/interpolationobject.c
Normal file
|
@ -0,0 +1,229 @@
|
|||
/* t-string Interpolation object implementation */
|
||||
|
||||
#include "Python.h"
|
||||
#include "pycore_initconfig.h" // _PyStatus_OK
|
||||
#include "pycore_interpolation.h"
|
||||
#include "pycore_typeobject.h" // _PyType_GetDict
|
||||
|
||||
static int
|
||||
_conversion_converter(PyObject *arg, PyObject **conversion)
|
||||
{
|
||||
if (arg == Py_None) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!PyUnicode_Check(arg)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Interpolation() argument 'conversion' must be str, not %T",
|
||||
arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py_ssize_t len;
|
||||
const char *conv_str = PyUnicode_AsUTF8AndSize(arg, &len);
|
||||
if (len != 1 || !(conv_str[0] == 'a' || conv_str[0] == 'r' || conv_str[0] == 's')) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Interpolation() argument 'conversion' must be one of 's', 'a' or 'r'");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*conversion = arg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include "clinic/interpolationobject.c.h"
|
||||
|
||||
/*[clinic input]
|
||||
class Interpolation "interpolationobject *" "&_PyInterpolation_Type"
|
||||
[clinic start generated code]*/
|
||||
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=161c64a16f9c4544]*/
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject *value;
|
||||
PyObject *expression;
|
||||
PyObject *conversion;
|
||||
PyObject *format_spec;
|
||||
} interpolationobject;
|
||||
|
||||
#define interpolationobject_CAST(op) \
|
||||
(assert(_PyInterpolation_CheckExact(op)), _Py_CAST(interpolationobject*, (op)))
|
||||
|
||||
/*[clinic input]
|
||||
@classmethod
|
||||
Interpolation.__new__ as interpolation_new
|
||||
|
||||
value: object
|
||||
expression: object(subclass_of='&PyUnicode_Type')
|
||||
conversion: object(converter='_conversion_converter') = None
|
||||
format_spec: object(subclass_of='&PyUnicode_Type', c_default='&_Py_STR(empty)') = ""
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
interpolation_new_impl(PyTypeObject *type, PyObject *value,
|
||||
PyObject *expression, PyObject *conversion,
|
||||
PyObject *format_spec)
|
||||
/*[clinic end generated code: output=6488e288765bc1a9 input=d91711024068528c]*/
|
||||
{
|
||||
interpolationobject *self = PyObject_GC_New(interpolationobject, type);
|
||||
if (!self) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->value = Py_NewRef(value);
|
||||
self->expression = Py_NewRef(expression);
|
||||
self->conversion = Py_NewRef(conversion);
|
||||
self->format_spec = Py_NewRef(format_spec);
|
||||
PyObject_GC_Track(self);
|
||||
return (PyObject *) self;
|
||||
}
|
||||
|
||||
static void
|
||||
interpolation_dealloc(PyObject *op)
|
||||
{
|
||||
PyObject_GC_UnTrack(op);
|
||||
Py_TYPE(op)->tp_clear(op);
|
||||
Py_TYPE(op)->tp_free(op);
|
||||
}
|
||||
|
||||
static int
|
||||
interpolation_clear(PyObject *op)
|
||||
{
|
||||
interpolationobject *self = interpolationobject_CAST(op);
|
||||
Py_CLEAR(self->value);
|
||||
Py_CLEAR(self->expression);
|
||||
Py_CLEAR(self->conversion);
|
||||
Py_CLEAR(self->format_spec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
interpolation_traverse(PyObject *op, visitproc visit, void *arg)
|
||||
{
|
||||
interpolationobject *self = interpolationobject_CAST(op);
|
||||
Py_VISIT(self->value);
|
||||
Py_VISIT(self->expression);
|
||||
Py_VISIT(self->conversion);
|
||||
Py_VISIT(self->format_spec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
interpolation_repr(PyObject *op)
|
||||
{
|
||||
interpolationobject *self = interpolationobject_CAST(op);
|
||||
return PyUnicode_FromFormat("%s(%R, %R, %R, %R)",
|
||||
_PyType_Name(Py_TYPE(self)), self->value, self->expression,
|
||||
self->conversion, self->format_spec);
|
||||
}
|
||||
|
||||
static PyMemberDef interpolation_members[] = {
|
||||
{"value", Py_T_OBJECT_EX, offsetof(interpolationobject, value), Py_READONLY, "Value"},
|
||||
{"expression", Py_T_OBJECT_EX, offsetof(interpolationobject, expression), Py_READONLY, "Expression"},
|
||||
{"conversion", Py_T_OBJECT_EX, offsetof(interpolationobject, conversion), Py_READONLY, "Conversion"},
|
||||
{"format_spec", Py_T_OBJECT_EX, offsetof(interpolationobject, format_spec), Py_READONLY, "Format specifier"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static PyObject*
|
||||
interpolation_reduce(PyObject *op, PyObject *Py_UNUSED(dummy))
|
||||
{
|
||||
interpolationobject *self = interpolationobject_CAST(op);
|
||||
return Py_BuildValue("(O(OOOO))", (PyObject *)Py_TYPE(op),
|
||||
self->value, self->expression,
|
||||
self->conversion, self->format_spec);
|
||||
}
|
||||
|
||||
static PyMethodDef interpolation_methods[] = {
|
||||
{"__reduce__", interpolation_reduce, METH_NOARGS,
|
||||
PyDoc_STR("__reduce__() -> (cls, state)")},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
PyTypeObject _PyInterpolation_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "string.templatelib.Interpolation",
|
||||
.tp_doc = PyDoc_STR("Interpolation object"),
|
||||
.tp_basicsize = sizeof(interpolationobject),
|
||||
.tp_itemsize = 0,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
|
||||
.tp_new = interpolation_new,
|
||||
.tp_alloc = PyType_GenericAlloc,
|
||||
.tp_dealloc = interpolation_dealloc,
|
||||
.tp_clear = interpolation_clear,
|
||||
.tp_free = PyObject_GC_Del,
|
||||
.tp_repr = interpolation_repr,
|
||||
.tp_members = interpolation_members,
|
||||
.tp_methods = interpolation_methods,
|
||||
.tp_traverse = interpolation_traverse,
|
||||
};
|
||||
|
||||
PyStatus
|
||||
_PyInterpolation_InitTypes(PyInterpreterState *interp)
|
||||
{
|
||||
PyObject *tuple = Py_BuildValue("(ssss)", "value", "expression", "conversion", "format_spec");
|
||||
if (!tuple) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
PyObject *dict = _PyType_GetDict(&_PyInterpolation_Type);
|
||||
if (!dict) {
|
||||
Py_DECREF(tuple);
|
||||
goto error;
|
||||
}
|
||||
|
||||
int status = PyDict_SetItemString(dict, "__match_args__", tuple);
|
||||
Py_DECREF(tuple);
|
||||
if (status < 0) {
|
||||
goto error;
|
||||
}
|
||||
return _PyStatus_OK();
|
||||
|
||||
error:
|
||||
return _PyStatus_ERR("Can't initialize interpolation types");
|
||||
}
|
||||
|
||||
PyObject *
|
||||
_PyInterpolation_Build(PyObject *value, PyObject *str, int conversion, PyObject *format_spec)
|
||||
{
|
||||
interpolationobject *interpolation = PyObject_GC_New(interpolationobject, &_PyInterpolation_Type);
|
||||
if (!interpolation) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
interpolation->value = Py_NewRef(value);
|
||||
interpolation->expression = Py_NewRef(str);
|
||||
interpolation->format_spec = Py_NewRef(format_spec);
|
||||
interpolation->conversion = NULL;
|
||||
|
||||
if (conversion == 0) {
|
||||
interpolation->conversion = Py_None;
|
||||
}
|
||||
else {
|
||||
switch (conversion) {
|
||||
case FVC_ASCII:
|
||||
interpolation->conversion = _Py_LATIN1_CHR('a');
|
||||
break;
|
||||
case FVC_REPR:
|
||||
interpolation->conversion = _Py_LATIN1_CHR('r');
|
||||
break;
|
||||
case FVC_STR:
|
||||
interpolation->conversion = _Py_LATIN1_CHR('s');
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"Interpolation() argument 'conversion' must be one of 's', 'a' or 'r'");
|
||||
Py_DECREF(interpolation);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject_GC_Track(interpolation);
|
||||
return (PyObject *) interpolation;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
_PyInterpolation_GetValueRef(PyObject *interpolation)
|
||||
{
|
||||
return Py_NewRef(interpolationobject_CAST(interpolation)->value);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue