bpo-30696: Fix the REPL looping endlessly when no memory (GH-4160) · python/cpython@e0582a3

@@ -65,6 +65,7 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,

6565

PyCompilerFlags *);

6666

static void err_input(perrdetail *);

6767

static void err_free(perrdetail *);

68+

static int PyRun_InteractiveOneObjectEx(FILE *, PyObject *, PyCompilerFlags *);

68696970

/* Parse input from a file and execute it */

7071

int

@@ -89,6 +90,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *

8990

PyObject *filename, *v;

9091

int ret, err;

9192

PyCompilerFlags local_flags;

93+

int nomem_count = 0;

92949395

filename = PyUnicode_DecodeFSDefault(filename_str);

9496

if (filename == NULL) {

@@ -110,22 +112,32 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *

110112

_PySys_SetObjectId(&PyId_ps2, v = PyUnicode_FromString("... "));

111113

Py_XDECREF(v);

112114

}

113-

err = -1;

114-

for (;;) {

115-

ret = PyRun_InteractiveOneObject(fp, filename, flags);

115+

err = 0;

116+

do {

117+

ret = PyRun_InteractiveOneObjectEx(fp, filename, flags);

118+

if (ret == -1 && PyErr_Occurred()) {

119+

/* Prevent an endless loop after multiple consecutive MemoryErrors

120+

* while still allowing an interactive command to fail with a

121+

* MemoryError. */

122+

if (PyErr_ExceptionMatches(PyExc_MemoryError)) {

123+

if (++nomem_count > 16) {

124+

PyErr_Clear();

125+

err = -1;

126+

break;

127+

}

128+

} else {

129+

nomem_count = 0;

130+

}

131+

PyErr_Print();

132+

flush_io();

133+

} else {

134+

nomem_count = 0;

135+

}

116136

#ifdef Py_REF_DEBUG

117137

if (_PyDebug_XOptionShowRefCount() == Py_True)

118138

_PyDebug_PrintTotalRefs();

119139

#endif

120-

if (ret == E_EOF) {

121-

err = 0;

122-

break;

123-

}

124-

/*

125-

if (ret == E_NOMEM)

126-

break;

127-

*/

128-

}

140+

} while (ret != E_EOF);

129141

Py_DECREF(filename);

130142

return err;

131143

}

@@ -154,8 +166,11 @@ static int PARSER_FLAGS(PyCompilerFlags *flags)

154166

PyPARSE_WITH_IS_KEYWORD : 0)) : 0)

155167

#endif

156168157-

int

158-

PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)

169+

/* A PyRun_InteractiveOneObject() auxiliary function that does not print the

170+

* error on failure. */

171+

static int

172+

PyRun_InteractiveOneObjectEx(FILE *fp, PyObject *filename,

173+

PyCompilerFlags *flags)

159174

{

160175

PyObject *m, *d, *v, *w, *oenc = NULL, *mod_name;

161176

mod_ty mod;

@@ -167,7 +182,6 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)

167182168183

mod_name = _PyUnicode_FromId(&PyId___main__); /* borrowed */

169184

if (mod_name == NULL) {

170-

PyErr_Print();

171185

return -1;

172186

}

173187

@@ -227,7 +241,6 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)

227241

PyErr_Clear();

228242

return E_EOF;

229243

}

230-

PyErr_Print();

231244

return -1;

232245

}

233246

m = PyImport_AddModuleObject(mod_name);

@@ -239,15 +252,26 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)

239252

v = run_mod(mod, filename, d, d, flags, arena);

240253

PyArena_Free(arena);

241254

if (v == NULL) {

242-

PyErr_Print();

243-

flush_io();

244255

return -1;

245256

}

246257

Py_DECREF(v);

247258

flush_io();

248259

return 0;

249260

}

250261262+

int

263+

PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)

264+

{

265+

int res;

266+267+

res = PyRun_InteractiveOneObjectEx(fp, filename, flags);

268+

if (res == -1) {

269+

PyErr_Print();

270+

flush_io();

271+

}

272+

return res;

273+

}

274+251275

int

252276

PyRun_InteractiveOneFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags)

253277

{