mirror of
https://github.com/python/cpython.git
synced 2025-08-03 08:34:29 +00:00
gh-132661: Add default value (of ""
) for Interpolation.expression
(#136441)
This commit is contained in:
parent
f519918ec6
commit
f1b8d01c80
5 changed files with 58 additions and 27 deletions
|
@ -2,33 +2,45 @@ from string.templatelib import Interpolation
|
||||||
|
|
||||||
|
|
||||||
class TStringBaseCase:
|
class TStringBaseCase:
|
||||||
|
def assertInterpolationEqual(self, i, exp):
|
||||||
|
"""Test Interpolation equality.
|
||||||
|
|
||||||
|
The *i* argument must be an Interpolation instance.
|
||||||
|
|
||||||
|
The *exp* argument must be a tuple of the form
|
||||||
|
(value, expression, conversion, format_spec) where the final three
|
||||||
|
items may be omitted and are assumed to be '', None and '' respectively.
|
||||||
|
"""
|
||||||
|
if len(exp) == 4:
|
||||||
|
actual = (i.value, i.expression, i.conversion, i.format_spec)
|
||||||
|
self.assertEqual(actual, exp)
|
||||||
|
elif len(exp) == 3:
|
||||||
|
self.assertEqual((i.value, i.expression, i.conversion), exp)
|
||||||
|
self.assertEqual(i.format_spec, "")
|
||||||
|
elif len(exp) == 2:
|
||||||
|
self.assertEqual((i.value, i.expression), exp)
|
||||||
|
self.assertEqual(i.conversion, None)
|
||||||
|
self.assertEqual(i.format_spec, "")
|
||||||
|
elif len(exp) == 1:
|
||||||
|
self.assertEqual((i.value,), exp)
|
||||||
|
self.assertEqual(i.expression, "")
|
||||||
|
self.assertEqual(i.conversion, None)
|
||||||
|
self.assertEqual(i.format_spec, "")
|
||||||
|
|
||||||
def assertTStringEqual(self, t, strings, interpolations):
|
def assertTStringEqual(self, t, strings, interpolations):
|
||||||
"""Test template string literal equality.
|
"""Test template string literal equality.
|
||||||
|
|
||||||
The *strings* argument must be a tuple of strings equal to *t.strings*.
|
The *strings* argument must be a tuple of strings equal to *t.strings*.
|
||||||
|
|
||||||
The *interpolations* argument must be a sequence of tuples which are
|
The *interpolations* argument must be a sequence of tuples which are
|
||||||
compared against *t.interpolations*. Each tuple consists of
|
compared against *t.interpolations*. Each tuple must match the form
|
||||||
(value, expression, conversion, format_spec), though the final two
|
described in the `assertInterpolationEqual` method.
|
||||||
items may be omitted, and are assumed to be None and '' respectively.
|
|
||||||
"""
|
"""
|
||||||
self.assertEqual(t.strings, strings)
|
self.assertEqual(t.strings, strings)
|
||||||
self.assertEqual(len(t.interpolations), len(interpolations))
|
self.assertEqual(len(t.interpolations), len(interpolations))
|
||||||
|
|
||||||
for i, exp in zip(t.interpolations, interpolations, strict=True):
|
for i, exp in zip(t.interpolations, interpolations, strict=True):
|
||||||
if len(exp) == 4:
|
self.assertInterpolationEqual(i, exp)
|
||||||
actual = (i.value, i.expression, i.conversion, i.format_spec)
|
|
||||||
self.assertEqual(actual, exp)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if len(exp) == 3:
|
|
||||||
self.assertEqual((i.value, i.expression, i.conversion), exp)
|
|
||||||
self.assertEqual(i.format_spec, '')
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.assertEqual((i.value, i.expression), exp)
|
|
||||||
self.assertEqual(i.format_spec, '')
|
|
||||||
self.assertIsNone(i.conversion)
|
|
||||||
|
|
||||||
|
|
||||||
def convert(value, conversion):
|
def convert(value, conversion):
|
||||||
|
|
|
@ -45,6 +45,19 @@ world"""
|
||||||
self.assertEqual(len(t.interpolations), 0)
|
self.assertEqual(len(t.interpolations), 0)
|
||||||
self.assertEqual(fstring(t), 'Hello,\nworld')
|
self.assertEqual(fstring(t), 'Hello,\nworld')
|
||||||
|
|
||||||
|
def test_interpolation_creation(self):
|
||||||
|
i = Interpolation('Maria', 'name', 'a', 'fmt')
|
||||||
|
self.assertInterpolationEqual(i, ('Maria', 'name', 'a', 'fmt'))
|
||||||
|
|
||||||
|
i = Interpolation('Maria', 'name', 'a')
|
||||||
|
self.assertInterpolationEqual(i, ('Maria', 'name', 'a'))
|
||||||
|
|
||||||
|
i = Interpolation('Maria', 'name')
|
||||||
|
self.assertInterpolationEqual(i, ('Maria', 'name'))
|
||||||
|
|
||||||
|
i = Interpolation('Maria')
|
||||||
|
self.assertInterpolationEqual(i, ('Maria',))
|
||||||
|
|
||||||
def test_creation_interleaving(self):
|
def test_creation_interleaving(self):
|
||||||
# Should add strings on either side
|
# Should add strings on either side
|
||||||
t = Template(Interpolation('Maria', 'name', None, ''))
|
t = Template(Interpolation('Maria', 'name', None, ''))
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
``Interpolation.expression`` now has a default, the empty string.
|
23
Objects/clinic/interpolationobject.c.h
generated
23
Objects/clinic/interpolationobject.c.h
generated
|
@ -47,26 +47,31 @@ interpolation_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||||
PyObject *argsbuf[4];
|
PyObject *argsbuf[4];
|
||||||
PyObject * const *fastargs;
|
PyObject * const *fastargs;
|
||||||
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
|
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
|
||||||
Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 2;
|
Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1;
|
||||||
PyObject *value;
|
PyObject *value;
|
||||||
PyObject *expression;
|
PyObject *expression = &_Py_STR(empty);
|
||||||
PyObject *conversion = Py_None;
|
PyObject *conversion = Py_None;
|
||||||
PyObject *format_spec = &_Py_STR(empty);
|
PyObject *format_spec = &_Py_STR(empty);
|
||||||
|
|
||||||
fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
|
fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser,
|
||||||
/*minpos*/ 2, /*maxpos*/ 4, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
|
/*minpos*/ 1, /*maxpos*/ 4, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
|
||||||
if (!fastargs) {
|
if (!fastargs) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
value = fastargs[0];
|
value = fastargs[0];
|
||||||
if (!PyUnicode_Check(fastargs[1])) {
|
|
||||||
_PyArg_BadArgument("Interpolation", "argument 'expression'", "str", fastargs[1]);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
expression = fastargs[1];
|
|
||||||
if (!noptargs) {
|
if (!noptargs) {
|
||||||
goto skip_optional_pos;
|
goto skip_optional_pos;
|
||||||
}
|
}
|
||||||
|
if (fastargs[1]) {
|
||||||
|
if (!PyUnicode_Check(fastargs[1])) {
|
||||||
|
_PyArg_BadArgument("Interpolation", "argument 'expression'", "str", fastargs[1]);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
expression = fastargs[1];
|
||||||
|
if (!--noptargs) {
|
||||||
|
goto skip_optional_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (fastargs[2]) {
|
if (fastargs[2]) {
|
||||||
if (!_conversion_converter(fastargs[2], &conversion)) {
|
if (!_conversion_converter(fastargs[2], &conversion)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -86,4 +91,4 @@ skip_optional_pos:
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=599742a5ccd6f060 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=2391391e2d7708c0 input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -54,7 +54,7 @@ typedef struct {
|
||||||
Interpolation.__new__ as interpolation_new
|
Interpolation.__new__ as interpolation_new
|
||||||
|
|
||||||
value: object
|
value: object
|
||||||
expression: object(subclass_of='&PyUnicode_Type')
|
expression: object(subclass_of='&PyUnicode_Type', c_default='&_Py_STR(empty)') = ""
|
||||||
conversion: object(converter='_conversion_converter') = None
|
conversion: object(converter='_conversion_converter') = None
|
||||||
format_spec: object(subclass_of='&PyUnicode_Type', c_default='&_Py_STR(empty)') = ""
|
format_spec: object(subclass_of='&PyUnicode_Type', c_default='&_Py_STR(empty)') = ""
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
@ -63,7 +63,7 @@ static PyObject *
|
||||||
interpolation_new_impl(PyTypeObject *type, PyObject *value,
|
interpolation_new_impl(PyTypeObject *type, PyObject *value,
|
||||||
PyObject *expression, PyObject *conversion,
|
PyObject *expression, PyObject *conversion,
|
||||||
PyObject *format_spec)
|
PyObject *format_spec)
|
||||||
/*[clinic end generated code: output=6488e288765bc1a9 input=d91711024068528c]*/
|
/*[clinic end generated code: output=6488e288765bc1a9 input=fc5c285c1dd23d36]*/
|
||||||
{
|
{
|
||||||
interpolationobject *self = PyObject_GC_New(interpolationobject, type);
|
interpolationobject *self = PyObject_GC_New(interpolationobject, type);
|
||||||
if (!self) {
|
if (!self) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue