From 57364ce34e0492fbc8b0a6b8c882f384bb489457 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 24 Mar 2021 01:29:09 +0100 Subject: [PATCH] bpo-43244: Remove parser_interface.h header file (GH-25001) Remove parser functions using the "struct _mod" type, because the AST C API was removed: * PyParser_ASTFromFile() * PyParser_ASTFromFileObject() * PyParser_ASTFromFilename() * PyParser_ASTFromString() * PyParser_ASTFromStringObject() These functions were undocumented and excluded from the limited C API. Add pycore_parser.h internal header file. Rename functions: * PyParser_ASTFromFileObject() => _PyParser_ASTFromFile() * PyParser_ASTFromStringObject() => _PyParser_ASTFromString() These functions are no longer exported (replace PyAPI_FUNC() with extern). Remove also _PyPegen_run_parser_from_file() function. Update test_peg_generator to use _PyPegen_run_parser_from_file_pointer() instead. --- Doc/whatsnew/3.10.rst | 9 +++- Include/Python.h | 1 - Include/cpython/parser_interface.h | 52 ------------------- Include/internal/pycore_parser.h | 31 +++++++++++ Makefile.pre.in | 2 +- .../2021-03-23-20-53-41.bpo-43244.VK3sLH.rst | 9 +++- Parser/peg_api.c | 51 ++---------------- Parser/pegen.c | 17 ------ Parser/pegen.h | 1 - Python/pythonrun.c | 13 ++--- Python/symtable.c | 3 +- .../peg_extension/peg_extension.c | 11 +++- 12 files changed, 70 insertions(+), 130 deletions(-) delete mode 100644 Include/cpython/parser_interface.h create mode 100644 Include/internal/pycore_parser.h diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 97442aa6b3d..bb3da4f565f 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -1403,14 +1403,19 @@ Removed Windows ```` header. Use the Python :mod:`ast` module instead. (Contributed by Victor Stinner in :issue:`43244`.) -* Remove the compiler functions using ``struct _mod`` type, because the public - AST C API was removed: +* Remove the compiler and parser functions using ``struct _mod`` type, because + the public AST C API was removed: * ``PyAST_Compile()`` * ``PyAST_CompileEx()`` * ``PyAST_CompileObject()`` * ``PyFuture_FromAST()`` * ``PyFuture_FromASTObject()`` + * ``PyParser_ASTFromFile()`` + * ``PyParser_ASTFromFileObject()`` + * ``PyParser_ASTFromFilename()`` + * ``PyParser_ASTFromString()`` + * ``PyParser_ASTFromStringObject()`` These functions were undocumented and excluded from the limited C API. (Contributed by Victor Stinner in :issue:`43244`.) diff --git a/Include/Python.h b/Include/Python.h index 86dbbcf6bd8..c87a7dd3ac1 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -141,7 +141,6 @@ #include "modsupport.h" #include "compile.h" #include "pythonrun.h" -#include "cpython/parser_interface.h" #include "pylifecycle.h" #include "ceval.h" #include "sysmodule.h" diff --git a/Include/cpython/parser_interface.h b/Include/cpython/parser_interface.h deleted file mode 100644 index 1c6576d926d..00000000000 --- a/Include/cpython/parser_interface.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef Py_PEGENINTERFACE -#define Py_PEGENINTERFACE -#ifdef __cplusplus -extern "C" { -#endif - -#include "Python.h" - -#ifndef Py_LIMITED_API -PyAPI_FUNC(struct _mod *) PyParser_ASTFromString( - const char *str, - const char *filename, - int mode, - PyCompilerFlags *flags, - PyArena *arena); -PyAPI_FUNC(struct _mod *) PyParser_ASTFromStringObject( - const char *str, - PyObject* filename, - int mode, - PyCompilerFlags *flags, - PyArena *arena); -PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile( - FILE *fp, - const char *filename, - const char* enc, - int mode, - const char *ps1, - const char *ps2, - PyCompilerFlags *flags, - int *errcode, - PyArena *arena); -PyAPI_FUNC(struct _mod *) PyParser_ASTFromFileObject( - FILE *fp, - PyObject *filename_ob, - const char *enc, - int mode, - const char *ps1, - const char *ps2, - PyCompilerFlags *flags, - int *errcode, - PyArena *arena); -PyAPI_FUNC(struct _mod *) PyParser_ASTFromFilename( - const char *filename, - int mode, - PyCompilerFlags *flags, - PyArena *arena); -#endif /* !Py_LIMITED_API */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_PEGENINTERFACE */ diff --git a/Include/internal/pycore_parser.h b/Include/internal/pycore_parser.h new file mode 100644 index 00000000000..e2de24e2ca9 --- /dev/null +++ b/Include/internal/pycore_parser.h @@ -0,0 +1,31 @@ +#ifndef Py_INTERNAL_PARSER_H +#define Py_INTERNAL_PARSER_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +extern struct _mod* _PyParser_ASTFromString( + const char *str, + PyObject* filename, + int mode, + PyCompilerFlags *flags, + PyArena *arena); +extern struct _mod* _PyParser_ASTFromFile( + FILE *fp, + PyObject *filename_ob, + const char *enc, + int mode, + const char *ps1, + const char *ps2, + PyCompilerFlags *flags, + int *errcode, + PyArena *arena); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PARSER_H */ diff --git a/Makefile.pre.in b/Makefile.pre.in index 5cfa0582b1b..ed168d88720 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -317,7 +317,7 @@ PEGEN_OBJS= \ PEGEN_HEADERS= \ - $(srcdir)/Include/cpython/parser_interface.h \ + $(srcdir)/Include/internal/pycore_parser.h \ $(srcdir)/Parser/pegen.h \ $(srcdir)/Parser/string_parser.h diff --git a/Misc/NEWS.d/next/C API/2021-03-23-20-53-41.bpo-43244.VK3sLH.rst b/Misc/NEWS.d/next/C API/2021-03-23-20-53-41.bpo-43244.VK3sLH.rst index 6cfe642d429..fcc8076dea6 100644 --- a/Misc/NEWS.d/next/C API/2021-03-23-20-53-41.bpo-43244.VK3sLH.rst +++ b/Misc/NEWS.d/next/C API/2021-03-23-20-53-41.bpo-43244.VK3sLH.rst @@ -1,11 +1,16 @@ -Remove the compiler functions using ``struct _mod`` type, because the public -AST C API was removed: +Remove the compiler and parser functions using ``struct _mod`` type, because +the public AST C API was removed: * ``PyAST_Compile()`` * ``PyAST_CompileEx()`` * ``PyAST_CompileObject()`` * ``PyFuture_FromAST()`` * ``PyFuture_FromASTObject()`` +* ``PyParser_ASTFromFile()`` +* ``PyParser_ASTFromFileObject()`` +* ``PyParser_ASTFromFilename()`` +* ``PyParser_ASTFromString()`` +* ``PyParser_ASTFromStringObject()`` These functions were undocumented and excluded from the limited C API. Patch by Victor Stinner. diff --git a/Parser/peg_api.c b/Parser/peg_api.c index 1555dea51c2..1487ac4ff85 100644 --- a/Parser/peg_api.c +++ b/Parser/peg_api.c @@ -4,21 +4,8 @@ #include "pegen.h" mod_ty -PyParser_ASTFromString(const char *str, const char *filename, int mode, - PyCompilerFlags *flags, PyArena *arena) -{ - PyObject *filename_ob = PyUnicode_FromString(filename); - if (filename_ob == NULL) { - return NULL; - } - mod_ty result = PyParser_ASTFromStringObject(str, filename_ob, mode, flags, arena); - Py_XDECREF(filename_ob); - return result; -} - -mod_ty -PyParser_ASTFromStringObject(const char *str, PyObject* filename, int mode, - PyCompilerFlags *flags, PyArena *arena) +_PyParser_ASTFromString(const char *str, PyObject* filename, int mode, + PyCompilerFlags *flags, PyArena *arena) { if (PySys_Audit("compile", "yO", str, filename) < 0) { return NULL; @@ -29,37 +16,9 @@ PyParser_ASTFromStringObject(const char *str, PyObject* filename, int mode, } mod_ty -PyParser_ASTFromFilename(const char *filename, int mode, PyCompilerFlags *flags, PyArena *arena) -{ - PyObject *filename_ob = PyUnicode_FromString(filename); - if (filename_ob == NULL) { - return NULL; - } - - mod_ty result = _PyPegen_run_parser_from_file(filename, mode, filename_ob, flags, arena); - Py_XDECREF(filename_ob); - return result; -} - -mod_ty -PyParser_ASTFromFile(FILE *fp, const char *filename, const char *enc, - int mode, const char *ps1, const char* ps2, - PyCompilerFlags *flags, int *errcode, PyArena *arena) -{ - PyObject *filename_ob = PyUnicode_FromString(filename); - if (filename_ob == NULL) { - return NULL; - } - mod_ty result = PyParser_ASTFromFileObject(fp, filename_ob, enc, mode, - ps1, ps2, flags, errcode, arena); - Py_XDECREF(filename_ob); - return result; -} - -mod_ty -PyParser_ASTFromFileObject(FILE *fp, PyObject *filename_ob, const char *enc, - int mode, const char *ps1, const char* ps2, - PyCompilerFlags *flags, int *errcode, PyArena *arena) +_PyParser_ASTFromFile(FILE *fp, PyObject *filename_ob, const char *enc, + int mode, const char *ps1, const char* ps2, + PyCompilerFlags *flags, int *errcode, PyArena *arena) { if (PySys_Audit("compile", "OO", Py_None, filename_ob) < 0) { return NULL; diff --git a/Parser/pegen.c b/Parser/pegen.c index f5c7994061e..ce2135c7b70 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -1321,23 +1321,6 @@ error: return result; } -mod_ty -_PyPegen_run_parser_from_file(const char *filename, int start_rule, - PyObject *filename_ob, PyCompilerFlags *flags, PyArena *arena) -{ - FILE *fp = fopen(filename, "rb"); - if (fp == NULL) { - PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); - return NULL; - } - - mod_ty result = _PyPegen_run_parser_from_file_pointer(fp, start_rule, filename_ob, - NULL, NULL, NULL, flags, NULL, arena); - - fclose(fp); - return result; -} - mod_ty _PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filename_ob, PyCompilerFlags *flags, PyArena *arena) diff --git a/Parser/pegen.h b/Parser/pegen.h index 66de75c133e..af160d6a43d 100644 --- a/Parser/pegen.h +++ b/Parser/pegen.h @@ -227,7 +227,6 @@ void _PyPegen_Parser_Free(Parser *); mod_ty _PyPegen_run_parser_from_file_pointer(FILE *, int, PyObject *, const char *, const char *, const char *, PyCompilerFlags *, int *, PyArena *); void *_PyPegen_run_parser(Parser *); -mod_ty _PyPegen_run_parser_from_file(const char *, int, PyObject *, PyCompilerFlags *, PyArena *); mod_ty _PyPegen_run_parser_from_string(const char *, int, PyObject *, PyCompilerFlags *, PyArena *); asdl_stmt_seq *_PyPegen_interactive_exit(Parser *); asdl_seq *_PyPegen_singleton_seq(Parser *, void *); diff --git a/Python/pythonrun.c b/Python/pythonrun.c index e16835b13e8..79ff42ba95a 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -16,6 +16,7 @@ #include "pycore_compile.h" // _PyAST_Compile() #include "pycore_interp.h" // PyInterpreterState.importlib #include "pycore_object.h" // _PyDebug_PrintTotalRefs() +#include "pycore_parser.h" // _PyParser_ASTFromString() #include "pycore_pyerrors.h" // _PyErr_Fetch #include "pycore_pylifecycle.h" // _Py_UnhandledKeyboardInterrupt #include "pycore_pystate.h" // _PyInterpreterState_GET() @@ -254,8 +255,8 @@ PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename, return -1; } - mod = PyParser_ASTFromFileObject(fp, filename, enc, Py_single_input, - ps1, ps2, flags, &errcode, arena); + mod = _PyParser_ASTFromFile(fp, filename, enc, Py_single_input, + ps1, ps2, flags, &errcode, arena); Py_XDECREF(v); Py_XDECREF(w); @@ -1102,7 +1103,7 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals, if (arena == NULL) return NULL; - mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); + mod = _PyParser_ASTFromString(str, filename, start, flags, arena); if (mod != NULL) ret = run_mod(mod, filename, globals, locals, flags, arena); @@ -1121,8 +1122,8 @@ pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals, } mod_ty mod; - mod = PyParser_ASTFromFileObject(fp, filename, NULL, start, NULL, NULL, - flags, NULL, arena); + mod = _PyParser_ASTFromFile(fp, filename, NULL, start, NULL, NULL, + flags, NULL, arena); if (closeit) { fclose(fp); @@ -1292,7 +1293,7 @@ Py_CompileStringObject(const char *str, PyObject *filename, int start, if (arena == NULL) return NULL; - mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); + mod = _PyParser_ASTFromString(str, filename, start, flags, arena); if (mod == NULL) { PyArena_Free(arena); return NULL; diff --git a/Python/symtable.c b/Python/symtable.c index a149e28dcb3..efe6d50f350 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -2,6 +2,7 @@ #include "pycore_ast.h" // identifier, stmt_ty #undef Yield /* undefine macro conflicting with */ #include "pycore_compile.h" // _Py_Mangle() +#include "pycore_parser.h" // _PyParser_ASTFromString() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_symtable.h" // PySTEntryObject #include "structmember.h" // PyMemberDef @@ -1975,7 +1976,7 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename, if (arena == NULL) return NULL; - mod = PyParser_ASTFromStringObject(str, filename, start, flags, arena); + mod = _PyParser_ASTFromString(str, filename, start, flags, arena); if (mod == NULL) { PyArena_Free(arena); return NULL; diff --git a/Tools/peg_generator/peg_extension/peg_extension.c b/Tools/peg_generator/peg_extension/peg_extension.c index f2a870ee8b5..209a34c1138 100644 --- a/Tools/peg_generator/peg_extension/peg_extension.c +++ b/Tools/peg_generator/peg_extension/peg_extension.c @@ -44,8 +44,17 @@ parse_file(PyObject *self, PyObject *args, PyObject *kwds) goto error; } + FILE *fp = fopen(filename, "rb"); + if (fp == NULL) { + PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename); + goto error; + } + PyCompilerFlags flags = _PyCompilerFlags_INIT; - mod_ty res = _PyPegen_run_parser_from_file(filename, Py_file_input, filename_ob, &flags, arena); + mod_ty res = _PyPegen_run_parser_from_file_pointer( + fp, Py_file_input, filename_ob, + NULL, NULL, NULL, &flags, NULL, arena); + fclose(fp); if (res == NULL) { goto error; }