[3.6] bpo-30696: Fix the REPL looping endlessly when no memory (GH-41… · python/cpython@ea5b545

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

6161

PyCompilerFlags *);

6262

static void err_input(perrdetail *);

6363

static void err_free(perrdetail *);

64+

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

64656566

/* 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;

89919092

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

150162151-

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)

161176162177

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

}

244255256+

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+245269

int

246270

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

247271

{