mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Issue 25483: Add an opcode to make f-string formatting more robust.
This commit is contained in:
parent
2753a096e0
commit
a78c7954d5
8 changed files with 205 additions and 168 deletions
|
@ -3363,6 +3363,63 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(FORMAT_VALUE) {
|
||||
/* Handles f-string value formatting. */
|
||||
PyObject *result;
|
||||
PyObject *fmt_spec;
|
||||
PyObject *value;
|
||||
PyObject *(*conv_fn)(PyObject *);
|
||||
int which_conversion = oparg & FVC_MASK;
|
||||
int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC;
|
||||
|
||||
fmt_spec = have_fmt_spec ? POP() : NULL;
|
||||
value = TOP();
|
||||
|
||||
/* See if any conversion is specified. */
|
||||
switch (which_conversion) {
|
||||
case FVC_STR: conv_fn = PyObject_Str; break;
|
||||
case FVC_REPR: conv_fn = PyObject_Repr; break;
|
||||
case FVC_ASCII: conv_fn = PyObject_ASCII; break;
|
||||
|
||||
/* Must be 0 (meaning no conversion), since only four
|
||||
values are allowed by (oparg & FVC_MASK). */
|
||||
default: conv_fn = NULL; break;
|
||||
}
|
||||
|
||||
/* If there's a conversion function, call it and replace
|
||||
value with that result. Otherwise, just use value,
|
||||
without conversion. */
|
||||
if (conv_fn) {
|
||||
result = conv_fn(value);
|
||||
Py_DECREF(value);
|
||||
if (!result) {
|
||||
Py_XDECREF(fmt_spec);
|
||||
goto error;
|
||||
}
|
||||
value = result;
|
||||
}
|
||||
|
||||
/* If value is a unicode object, and there's no fmt_spec,
|
||||
then we know the result of format(value) is value
|
||||
itself. In that case, skip calling format(). I plan to
|
||||
move this optimization in to PyObject_Format()
|
||||
itself. */
|
||||
if (PyUnicode_CheckExact(value) && fmt_spec == NULL) {
|
||||
/* Do nothing, just transfer ownership to result. */
|
||||
result = value;
|
||||
} else {
|
||||
/* Actually call format(). */
|
||||
result = PyObject_Format(value, fmt_spec);
|
||||
Py_DECREF(value);
|
||||
Py_XDECREF(fmt_spec);
|
||||
if (!result)
|
||||
goto error;
|
||||
}
|
||||
|
||||
SET_TOP(result);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(EXTENDED_ARG) {
|
||||
opcode = NEXTOP();
|
||||
oparg = oparg<<16 | NEXTARG();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue