[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/python/cpython/3.14/Python/ast_unparse.c [Back]  [Original]

#include "Python.h"
#include "pycore_ast.h"           // expr_ty
#include "pycore_pystate.h"       // _PyInterpreterState_GET()
#include "pycore_runtime.h"       // _Py_ID()
#include 

/* This limited unparser is used to convert annotations back to strings
 * during compilation rather than being a full AST unparser.
 * See ast.unparse for a full unparser (written in Python)
 */

_Py_DECLARE_STR(dbl_open_br, "{{");
_Py_DECLARE_STR(dbl_close_br, "}}");

/* Forward declarations for recursion via helper functions. */
static PyObject *
expr_as_unicode(expr_ty e, int level);
static int
append_ast_expr(PyUnicodeWriter *writer, expr_ty e, int level);
static int
append_templatestr(PyUnicodeWriter *writer, expr_ty e);
static int
append_joinedstr(PyUnicodeWriter *writer, expr_ty e, bool is_format_spec);
static int
append_interpolation(PyUnicodeWriter *writer, expr_ty e);
static int
append_formattedvalue(PyUnicodeWriter *writer, expr_ty e);
static int
append_ast_slice(PyUnicodeWriter *writer, expr_ty e);

static int
append_char(PyUnicodeWriter *writer, Py_UCS4 ch)
{
    return PyUnicodeWriter_WriteChar(writer, ch);
}

static int
append_charp(PyUnicodeWriter *writer, const char *charp)
{
    return PyUnicodeWriter_WriteUTF8(writer, charp, -1);
}

#define APPEND_CHAR_FINISH(ch)  do { \
        return append_char(writer, (ch)); \
    } while (0)

#define APPEND_STR_FINISH(str)  do { \
        return append_charp(writer, (str)); \
    } while (0)

#define APPEND_CHAR(ch)  do { \
        if (-1 == append_char(writer, (ch))) { \
            return -1; \
        } \
    } while (0)

#define APPEND_STR(str)  do { \
        if (-1 == append_charp(writer, (str))) { \
            return -1; \
        } \
    } while (0)

#define APPEND_STR_IF(cond, str)  do { \
        if ((cond) && -1 == append_charp(writer, (str))) { \
            return -1; \
        } \
    } while (0)

#define APPEND_STR_IF_NOT_FIRST(str)  do { \
        APPEND_STR_IF(!first, (str)); \
        first = false; \
    } while (0)

#define APPEND_EXPR(expr, pr)  do { \
        if (-1 == append_ast_expr(writer, (expr), (pr))) { \
            return -1; \
        } \
    } while (0)

#define APPEND(type, value)  do { \
        if (-1 == append_ast_ ## type(writer, (value))) { \
            return -1; \
        } \
    } while (0)

static int
append_repr(PyUnicodeWriter *writer, PyObject *obj)
{
    PyObject *repr = PyObject_Repr(obj);
    if (!repr) {
        return -1;
    }

    if ((PyFloat_CheckExact(obj) && isinf(PyFloat_AS_DOUBLE(obj))) ||
        PyComplex_CheckExact(obj))
    {
        _Py_DECLARE_STR(str_replace_inf, "1e309");  // evaluates to inf
        PyObject *new_repr = PyUnicode_Replace(
            repr,
            &_Py_ID(inf),
            &_Py_STR(str_replace_inf),
            -1
        );
        Py_DECREF(repr);
        if (!new_repr) {
            return -1;
        }
        repr = new_repr;
    }

    int ret = PyUnicodeWriter_WriteStr(writer, repr);
    Py_DECREF(repr);
    return ret;
}

/* Priority levels */

enum {
    PR_TUPLE,
    PR_TEST,            /* 'if'-'else', 'lambda' */
    PR_OR,              /* 'or' */
    PR_AND,             /* 'and' */
    PR_NOT,             /* 'not' */
    PR_CMP,             /* '', '==', '>=', '

Web Proxy Viewer  |  New URL  |  Original Page