Skip to content

Commit dafada3

Browse files
pablogsalmloskot
andauthored
[3.9] bpo-46502: Remove "How do I tell incomplete input" from FAQ (GH-30925) (GH-30934)
Since, - Py_CompileString no longer allows to distinguish "incomplete input" from "invalid input" - there is no alternative solution available from the Python C API due to how the new parser works (rewritten in 3.9) - the only supported way is to manually import the codeop module from C and use its API as IDLE does, and accept its own complications it is desirable to remove this Q&A from the official FAQ.. (cherry picked from commit f0a6481) Co-authored-by: Mateusz Łoskot <[email protected]> Co-authored-by: Mateusz Łoskot <[email protected]>
1 parent ff11eff commit dafada3

File tree

1 file changed

+0
-156
lines changed

1 file changed

+0
-156
lines changed

Doc/faq/extending.rst

Lines changed: 0 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,6 @@ For Red Hat, install the python-devel RPM to get the necessary files.
254254

255255
For Debian, run ``apt-get install python-dev``.
256256

257-
258257
How do I tell "incomplete input" from "invalid input"?
259258
------------------------------------------------------
260259

@@ -273,161 +272,6 @@ you. You can also set the :c:func:`PyOS_ReadlineFunctionPointer` to point at you
273272
custom input function. See ``Modules/readline.c`` and ``Parser/myreadline.c``
274273
for more hints.
275274

276-
However sometimes you have to run the embedded Python interpreter in the same
277-
thread as your rest application and you can't allow the
278-
:c:func:`PyRun_InteractiveLoop` to stop while waiting for user input. The one
279-
solution then is to call :c:func:`PyParser_ParseString` and test for ``e.error``
280-
equal to ``E_EOF``, which means the input is incomplete. Here's a sample code
281-
fragment, untested, inspired by code from Alex Farber::
282-
283-
#define PY_SSIZE_T_CLEAN
284-
#include <Python.h>
285-
#include <node.h>
286-
#include <errcode.h>
287-
#include <grammar.h>
288-
#include <parsetok.h>
289-
#include <compile.h>
290-
291-
int testcomplete(char *code)
292-
/* code should end in \n */
293-
/* return -1 for error, 0 for incomplete, 1 for complete */
294-
{
295-
node *n;
296-
perrdetail e;
297-
298-
n = PyParser_ParseString(code, &_PyParser_Grammar,
299-
Py_file_input, &e);
300-
if (n == NULL) {
301-
if (e.error == E_EOF)
302-
return 0;
303-
return -1;
304-
}
305-
306-
PyNode_Free(n);
307-
return 1;
308-
}
309-
310-
Another solution is trying to compile the received string with
311-
:c:func:`Py_CompileString`. If it compiles without errors, try to execute the
312-
returned code object by calling :c:func:`PyEval_EvalCode`. Otherwise save the
313-
input for later. If the compilation fails, find out if it's an error or just
314-
more input is required - by extracting the message string from the exception
315-
tuple and comparing it to the string "unexpected EOF while parsing". Here is a
316-
complete example using the GNU readline library (you may want to ignore
317-
**SIGINT** while calling readline())::
318-
319-
#include <stdio.h>
320-
#include <readline.h>
321-
322-
#define PY_SSIZE_T_CLEAN
323-
#include <Python.h>
324-
#include <object.h>
325-
#include <compile.h>
326-
#include <eval.h>
327-
328-
int main (int argc, char* argv[])
329-
{
330-
int i, j, done = 0; /* lengths of line, code */
331-
char ps1[] = ">>> ";
332-
char ps2[] = "... ";
333-
char *prompt = ps1;
334-
char *msg, *line, *code = NULL;
335-
PyObject *src, *glb, *loc;
336-
PyObject *exc, *val, *trb, *obj, *dum;
337-
338-
Py_Initialize ();
339-
loc = PyDict_New ();
340-
glb = PyDict_New ();
341-
PyDict_SetItemString (glb, "__builtins__", PyEval_GetBuiltins ());
342-
343-
while (!done)
344-
{
345-
line = readline (prompt);
346-
347-
if (NULL == line) /* Ctrl-D pressed */
348-
{
349-
done = 1;
350-
}
351-
else
352-
{
353-
i = strlen (line);
354-
355-
if (i > 0)
356-
add_history (line); /* save non-empty lines */
357-
358-
if (NULL == code) /* nothing in code yet */
359-
j = 0;
360-
else
361-
j = strlen (code);
362-
363-
code = realloc (code, i + j + 2);
364-
if (NULL == code) /* out of memory */
365-
exit (1);
366-
367-
if (0 == j) /* code was empty, so */
368-
code[0] = '\0'; /* keep strncat happy */
369-
370-
strncat (code, line, i); /* append line to code */
371-
code[i + j] = '\n'; /* append '\n' to code */
372-
code[i + j + 1] = '\0';
373-
374-
src = Py_CompileString (code, "<stdin>", Py_single_input);
375-
376-
if (NULL != src) /* compiled just fine - */
377-
{
378-
if (ps1 == prompt || /* ">>> " or */
379-
'\n' == code[i + j - 1]) /* "... " and double '\n' */
380-
{ /* so execute it */
381-
dum = PyEval_EvalCode (src, glb, loc);
382-
Py_XDECREF (dum);
383-
Py_XDECREF (src);
384-
free (code);
385-
code = NULL;
386-
if (PyErr_Occurred ())
387-
PyErr_Print ();
388-
prompt = ps1;
389-
}
390-
} /* syntax error or E_EOF? */
391-
else if (PyErr_ExceptionMatches (PyExc_SyntaxError))
392-
{
393-
PyErr_Fetch (&exc, &val, &trb); /* clears exception! */
394-
395-
if (PyArg_ParseTuple (val, "sO", &msg, &obj) &&
396-
!strcmp (msg, "unexpected EOF while parsing")) /* E_EOF */
397-
{
398-
Py_XDECREF (exc);
399-
Py_XDECREF (val);
400-
Py_XDECREF (trb);
401-
prompt = ps2;
402-
}
403-
else /* some other syntax error */
404-
{
405-
PyErr_Restore (exc, val, trb);
406-
PyErr_Print ();
407-
free (code);
408-
code = NULL;
409-
prompt = ps1;
410-
}
411-
}
412-
else /* some non-syntax error */
413-
{
414-
PyErr_Print ();
415-
free (code);
416-
code = NULL;
417-
prompt = ps1;
418-
}
419-
420-
free (line);
421-
}
422-
}
423-
424-
Py_XDECREF(glb);
425-
Py_XDECREF(loc);
426-
Py_Finalize();
427-
exit(0);
428-
}
429-
430-
431275
How do I find undefined g++ symbols __builtin_new or __pure_virtual?
432276
--------------------------------------------------------------------
433277

0 commit comments

Comments
 (0)