@@ -1205,109 +1205,117 @@ _io__Buffered_readinto1_impl(buffered *self, Py_buffer *buffer)
12051205static PyObject *
12061206_buffered_readline (buffered * self , Py_ssize_t limit )
12071207{
1208- PyObject * res = NULL ;
1209- PyObject * chunks = NULL ;
1210- Py_ssize_t n ;
1211- const char * start , * s , * end ;
1208+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (self );
12121209
12131210 CHECK_CLOSED (self , "readline of closed file" )
12141211
12151212 /* First, try to find a line in the buffer. This can run unlocked because
12161213 the calls to the C API are simple enough that they can't trigger
12171214 any thread switch. */
1218- n = Py_SAFE_DOWNCAST (READAHEAD (self ), Py_off_t , Py_ssize_t );
1219- if (limit >= 0 && n > limit )
1215+ Py_ssize_t n = Py_SAFE_DOWNCAST (READAHEAD (self ), Py_off_t , Py_ssize_t );
1216+ if (limit >= 0 && n > limit ) {
12201217 n = limit ;
1221- start = self -> buffer + self -> pos ;
1222- s = memchr (start , '\n' , n );
1218+ }
1219+ const char * start = self -> buffer + self -> pos ;
1220+ const char * s = memchr (start , '\n' , n );
12231221 if (s != NULL ) {
1224- res = PyBytes_FromStringAndSize (start , s - start + 1 );
1225- if (res != NULL )
1226- self -> pos += s - start + 1 ;
1227- goto end_unlocked ;
1222+ n = s - start + 1 ;
1223+ PyObject * res = PyBytes_FromStringAndSize (start , n );
1224+ if (res == NULL ) {
1225+ return NULL ;
1226+ }
1227+ self -> pos += n ;
1228+ return res ;
12281229 }
1230+
12291231 if (n == limit ) {
1230- res = PyBytes_FromStringAndSize (start , n );
1231- if (res != NULL )
1232- self -> pos += n ;
1233- goto end_unlocked ;
1232+ PyObject * res = PyBytes_FromStringAndSize (start , n );
1233+ if (res == NULL ) {
1234+ return NULL ;
1235+ }
1236+ self -> pos += n ;
1237+ return res ;
12341238 }
12351239
1236- if (!ENTER_BUFFERED (self ))
1237- goto end_unlocked ;
1240+ PyBytesWriter * writer = NULL ;
1241+ int locked = 0 ;
1242+ if (!ENTER_BUFFERED (self )) {
1243+ goto error ;
1244+ }
1245+ locked = 1 ;
12381246
12391247 /* Now we try to get some more from the raw stream */
1240- chunks = PyList_New (0 );
1241- if (chunks == NULL )
1242- goto end ;
1248+ writer = PyBytesWriter_Create (0 );
1249+ if (writer == NULL ) {
1250+ goto error ;
1251+ }
1252+
12431253 if (n > 0 ) {
1244- res = PyBytes_FromStringAndSize (start , n );
1245- if (res == NULL )
1246- goto end ;
1247- if (PyList_Append (chunks , res ) < 0 ) {
1248- Py_CLEAR (res );
1249- goto end ;
1254+ if (PyBytesWriter_WriteBytes (writer , start , n ) < 0 ) {
1255+ goto error ;
12501256 }
1251- Py_CLEAR (res );
12521257 self -> pos += n ;
1253- if (limit >= 0 )
1258+ if (limit >= 0 ) {
12541259 limit -= n ;
1260+ }
12551261 }
12561262 if (self -> writable ) {
1257- PyObject * r = buffered_flush_and_rewind_unlocked (self );
1258- if (r == NULL )
1259- goto end ;
1260- Py_DECREF (r );
1263+ PyObject * res = buffered_flush_and_rewind_unlocked (self );
1264+ if (res == NULL ) {
1265+ goto error ;
1266+ }
1267+ Py_DECREF (res );
12611268 }
12621269
12631270 for (;;) {
12641271 _bufferedreader_reset_buf (self );
12651272 n = _bufferedreader_fill_buffer (self );
1266- if (n == -1 )
1267- goto end ;
1268- if (n <= 0 )
1273+ if (n == -1 ) {
1274+ goto error ;
1275+ }
1276+ if (n <= 0 ) {
12691277 break ;
1270- if (limit >= 0 && n > limit )
1278+ }
1279+ if (limit >= 0 && n > limit ) {
12711280 n = limit ;
1281+ }
12721282 start = self -> buffer ;
1273- end = start + n ;
1283+ const char * end = start + n ;
12741284 s = start ;
12751285 while (s < end ) {
12761286 if (* s ++ == '\n' ) {
1277- res = PyBytes_FromStringAndSize ( start , s - start );
1278- if ( res == NULL )
1279- goto end ;
1287+ if ( PyBytesWriter_WriteBytes ( writer , start , s - start ) < 0 ) {
1288+ goto error ;
1289+ }
12801290 self -> pos = s - start ;
12811291 goto found ;
12821292 }
12831293 }
1284- res = PyBytes_FromStringAndSize (start , n );
1285- if (res == NULL )
1286- goto end ;
1294+
1295+ if (PyBytesWriter_WriteBytes (writer , start , n ) < 0 ) {
1296+ goto error ;
1297+ }
12871298 if (n == limit ) {
12881299 self -> pos = n ;
12891300 break ;
12901301 }
1291- if (PyList_Append (chunks , res ) < 0 ) {
1292- Py_CLEAR (res );
1293- goto end ;
1294- }
1295- Py_CLEAR (res );
1296- if (limit >= 0 )
1302+ if (limit >= 0 ) {
12971303 limit -= n ;
1304+ }
12981305 }
1306+
12991307found :
1300- if (res != NULL && PyList_Append (chunks , res ) < 0 ) {
1301- Py_CLEAR (res );
1302- goto end ;
1308+ if (locked ) {
1309+ LEAVE_BUFFERED (self )
13031310 }
1304- Py_XSETREF ( res , PyBytes_Join (( PyObject * ) & _Py_SINGLETON ( bytes_empty ), chunks ) );
1311+ return PyBytesWriter_Finish ( writer );
13051312
1306- end :
1307- LEAVE_BUFFERED (self )
1308- end_unlocked :
1309- Py_XDECREF (chunks );
1310- return res ;
1313+ error :
1314+ PyBytesWriter_Discard (writer );
1315+ if (locked ) {
1316+ LEAVE_BUFFERED (self )
1317+ }
1318+ return NULL ;
13111319}
13121320
13131321/*[clinic input]
0 commit comments