@@ -1356,8 +1356,6 @@ _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n)
13561356{
13571357 assert (n != READ_WHOLE_LINE );
13581358
1359- /* XXX add tests from ogrisel's use case */
1360-
13611359 /* Read from available buffer data, if any */
13621360 Py_ssize_t in_buffer = self -> input_len - self -> next_read_idx ;
13631361 if (in_buffer > 0 ) {
@@ -1373,30 +1371,21 @@ _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n)
13731371 }
13741372
13751373 /* Read from file */
1374+ if (!self -> readinto )
1375+ return bad_readline ();
13761376 if (_Unpickler_SkipConsumed (self ) < 0 )
13771377 return -1 ;
13781378
1379- Py_ssize_t read_size ;
1380-
1381- if (self -> readinto == NULL ) {
1382- /* Call read() and memcpy */
1383- /* XXX do we want this fallback? pickle.py doesn't have it */
1384- char * s ;
1385- read_size = _Unpickler_ReadImpl (self , & s , n );
1386- if (read_size < 0 ) {
1387- return -1 ;
1388- }
1389- assert (read_size == n );
1390- memcpy (buf , s , n );
1391- return n ;
1392- }
1393-
13941379 /* Call readinto() into user buffer */
13951380 PyObject * buf_obj = PyMemoryView_FromMemory (buf , n , PyBUF_WRITE );
1396- if (buf_obj == NULL )
1381+ if (buf_obj == NULL ) {
13971382 return -1 ;
1383+ }
13981384 PyObject * read_size_obj = _Pickle_FastCall (self -> readinto , buf_obj );
1399- read_size = PyLong_AsSsize_t (read_size_obj );
1385+ if (read_size_obj == NULL ) {
1386+ return -1 ;
1387+ }
1388+ Py_ssize_t read_size = PyLong_AsSsize_t (read_size_obj );
14001389 Py_DECREF (read_size_obj );
14011390
14021391 if (read_size < 0 ) {
@@ -1614,19 +1603,17 @@ _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file)
16141603 _Py_IDENTIFIER (readinto );
16151604 _Py_IDENTIFIER (readline );
16161605
1617- /* Both 'peek' and 'readline' are optional, for compatibility */
16181606 if (_PyObject_LookupAttrId (file , & PyId_peek , & self -> peek ) < 0 ) {
16191607 return -1 ;
16201608 }
1621- if (_PyObject_LookupAttrId (file , & PyId_readinto , & self -> readinto ) < 0 ) {
1622- return -1 ;
1623- }
16241609 (void )_PyObject_LookupAttrId (file , & PyId_read , & self -> read );
1610+ (void )_PyObject_LookupAttrId (file , & PyId_readinto , & self -> readinto );
16251611 (void )_PyObject_LookupAttrId (file , & PyId_readline , & self -> readline );
1626- if (self -> readline == NULL || self -> read == NULL ) {
1612+ if (! self -> readline || ! self -> readinto || ! self -> read ) {
16271613 if (!PyErr_Occurred ()) {
16281614 PyErr_SetString (PyExc_TypeError ,
1629- "file must have 'read' and 'readline' attributes" );
1615+ "file must have 'read', 'readinto' and "
1616+ "'readline' attributes" );
16301617 }
16311618 Py_CLEAR (self -> read );
16321619 Py_CLEAR (self -> readinto );
0 commit comments