bpo-30347: Stop crashes when concurrently iterate over itertools.grou… · python/cpython@c740e4f (original) (raw)

`@@ -73,10 +73,37 @@ groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg)

`

73

73

`return 0;

`

74

74

`}

`

75

75

``

``

76

`+

Py_LOCAL_INLINE(int)

`

``

77

`+

groupby_step(groupbyobject *gbo)

`

``

78

`+

{

`

``

79

`+

PyObject *newvalue, *newkey, *oldvalue;

`

``

80

+

``

81

`+

newvalue = PyIter_Next(gbo->it);

`

``

82

`+

if (newvalue == NULL)

`

``

83

`+

return -1;

`

``

84

+

``

85

`+

if (gbo->keyfunc == Py_None) {

`

``

86

`+

newkey = newvalue;

`

``

87

`+

Py_INCREF(newvalue);

`

``

88

`+

} else {

`

``

89

`+

newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL);

`

``

90

`+

if (newkey == NULL) {

`

``

91

`+

Py_DECREF(newvalue);

`

``

92

`+

return -1;

`

``

93

`+

}

`

``

94

`+

}

`

``

95

+

``

96

`+

oldvalue = gbo->currvalue;

`

``

97

`+

gbo->currvalue = newvalue;

`

``

98

`+

Py_XSETREF(gbo->currkey, newkey);

`

``

99

`+

Py_XDECREF(oldvalue);

`

``

100

`+

return 0;

`

``

101

`+

}

`

``

102

+

76

103

`static PyObject *

`

77

104

`groupby_next(groupbyobject *gbo)

`

78

105

`{

`

79

``

`-

PyObject *newvalue, *newkey, *r, *grouper;

`

``

106

`+

PyObject *r, *grouper;

`

80

107

``

81

108

`gbo->currgrouper = NULL;

`

82

109

`/* skip to next iteration group */

`

`@@ -95,25 +122,9 @@ groupby_next(groupbyobject *gbo)

`

95

122

`break;

`

96

123

` }

`

97

124

``

98

``

`-

newvalue = PyIter_Next(gbo->it);

`

99

``

`-

if (newvalue == NULL)

`

``

125

`+

if (groupby_step(gbo) < 0)

`

100

126

`return NULL;

`

101

``

-

102

``

`-

if (gbo->keyfunc == Py_None) {

`

103

``

`-

newkey = newvalue;

`

104

``

`-

Py_INCREF(newvalue);

`

105

``

`-

} else {

`

106

``

`-

newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL);

`

107

``

`-

if (newkey == NULL) {

`

108

``

`-

Py_DECREF(newvalue);

`

109

``

`-

return NULL;

`

110

``

`-

}

`

111

``

`-

}

`

112

``

-

113

``

`-

Py_XSETREF(gbo->currkey, newkey);

`

114

``

`-

Py_XSETREF(gbo->currvalue, newvalue);

`

115

127

` }

`

116

``

-

117

128

`Py_INCREF(gbo->currkey);

`

118

129

`Py_XSETREF(gbo->tgtkey, gbo->currkey);

`

119

130

``

`@@ -285,30 +296,14 @@ static PyObject *

`

285

296

`_grouper_next(_grouperobject *igo)

`

286

297

`{

`

287

298

`groupbyobject *gbo = (groupbyobject *)igo->parent;

`

288

``

`-

PyObject *newvalue, *newkey, *r;

`

``

299

`+

PyObject *r;

`

289

300

`int rcmp;

`

290

301

``

291

302

`if (gbo->currgrouper != igo)

`

292

303

`return NULL;

`

293

304

`if (gbo->currvalue == NULL) {

`

294

``

`-

newvalue = PyIter_Next(gbo->it);

`

295

``

`-

if (newvalue == NULL)

`

``

305

`+

if (groupby_step(gbo) < 0)

`

296

306

`return NULL;

`

297

``

-

298

``

`-

if (gbo->keyfunc == Py_None) {

`

299

``

`-

newkey = newvalue;

`

300

``

`-

Py_INCREF(newvalue);

`

301

``

`-

} else {

`

302

``

`-

newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL);

`

303

``

`-

if (newkey == NULL) {

`

304

``

`-

Py_DECREF(newvalue);

`

305

``

`-

return NULL;

`

306

``

`-

}

`

307

``

`-

}

`

308

``

-

309

``

`-

assert(gbo->currkey == NULL);

`

310

``

`-

gbo->currkey = newkey;

`

311

``

`-

gbo->currvalue = newvalue;

`

312

307

` }

`

313

308

``

314

309

`assert(gbo->currkey != NULL);

`