@@ -61,6 +61,7 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
6161 PyCompilerFlags * );
6262static void err_input (perrdetail * );
6363static void err_free (perrdetail * );
64+ static int PyRun_InteractiveOneObjectEx (FILE * , PyObject * , PyCompilerFlags * );
6465
6566/* Parse input from a file and execute it */
6667
@@ -86,6 +87,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
8687 PyObject * filename , * v ;
8788 int ret , err ;
8889 PyCompilerFlags local_flags ;
90+ int nomem_count = 0 ;
8991
9092 filename = PyUnicode_DecodeFSDefault (filename_str );
9193 if (filename == NULL ) {
@@ -107,19 +109,29 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
107109 _PySys_SetObjectId (& PyId_ps2 , v = PyUnicode_FromString ("... " ));
108110 Py_XDECREF (v );
109111 }
110- err = -1 ;
111- for (;;) {
112- ret = PyRun_InteractiveOneObject (fp , filename , flags );
113- _PY_DEBUG_PRINT_TOTAL_REFS ();
114- if (ret == E_EOF ) {
115- err = 0 ;
116- break ;
112+ err = 0 ;
113+ do {
114+ ret = PyRun_InteractiveOneObjectEx (fp , filename , flags );
115+ if (ret == -1 && PyErr_Occurred ()) {
116+ /* Prevent an endless loop after multiple consecutive MemoryErrors
117+ * while still allowing an interactive command to fail with a
118+ * MemoryError. */
119+ if (PyErr_ExceptionMatches (PyExc_MemoryError )) {
120+ if (++ nomem_count > 16 ) {
121+ PyErr_Clear ();
122+ err = -1 ;
123+ break ;
124+ }
125+ } else {
126+ nomem_count = 0 ;
127+ }
128+ PyErr_Print ();
129+ flush_io ();
130+ } else {
131+ nomem_count = 0 ;
117132 }
118- /*
119- if (ret == E_NOMEM)
120- break;
121- */
122- }
133+ _PY_DEBUG_PRINT_TOTAL_REFS ();
134+ } while (ret != E_EOF );
123135 Py_DECREF (filename );
124136 return err ;
125137}
@@ -148,8 +160,11 @@ static int PARSER_FLAGS(PyCompilerFlags *flags)
148160 PyPARSE_WITH_IS_KEYWORD : 0)) : 0)
149161#endif
150162
151- int
152- PyRun_InteractiveOneObject (FILE * fp , PyObject * filename , PyCompilerFlags * flags )
163+ /* A PyRun_InteractiveOneObject() auxiliary function that does not print the
164+ * error on failure. */
165+ static int
166+ PyRun_InteractiveOneObjectEx (FILE * fp , PyObject * filename ,
167+ PyCompilerFlags * flags )
153168{
154169 PyObject * m , * d , * v , * w , * oenc = NULL , * mod_name ;
155170 mod_ty mod ;
@@ -161,7 +176,6 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
161176
162177 mod_name = _PyUnicode_FromId (& PyId___main__ ); /* borrowed */
163178 if (mod_name == NULL ) {
164- PyErr_Print ();
165179 return -1 ;
166180 }
167181
@@ -221,7 +235,6 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
221235 PyErr_Clear ();
222236 return E_EOF ;
223237 }
224- PyErr_Print ();
225238 return -1 ;
226239 }
227240 m = PyImport_AddModuleObject (mod_name );
@@ -233,15 +246,26 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
233246 v = run_mod (mod , filename , d , d , flags , arena );
234247 PyArena_Free (arena );
235248 if (v == NULL ) {
236- PyErr_Print ();
237- flush_io ();
238249 return -1 ;
239250 }
240251 Py_DECREF (v );
241252 flush_io ();
242253 return 0 ;
243254}
244255
256+ int
257+ PyRun_InteractiveOneObject (FILE * fp , PyObject * filename , PyCompilerFlags * flags )
258+ {
259+ int res ;
260+
261+ res = PyRun_InteractiveOneObjectEx (fp , filename , flags );
262+ if (res == -1 ) {
263+ PyErr_Print ();
264+ flush_io ();
265+ }
266+ return res ;
267+ }
268+
245269int
246270PyRun_InteractiveOneFlags (FILE * fp , const char * filename_str , PyCompilerFlags * flags )
247271{
0 commit comments