@@ -348,36 +348,98 @@ _PyXIData_UnregisterClass(PyThreadState *tstate, PyTypeObject *cls)
348348
349349// bytes
350350
351- struct _shared_bytes_data {
351+ int
352+ _PyBytes_GetData (PyObject * obj , _PyBytes_data_t * data )
353+ {
354+ if (!PyBytes_Check (obj )) {
355+ PyErr_Format (PyExc_TypeError , "expected bytes, got %R" , obj );
356+ return -1 ;
357+ }
352358 char * bytes ;
353359 Py_ssize_t len ;
354- };
360+ if (PyBytes_AsStringAndSize (obj , & bytes , & len ) < 0 ) {
361+ return -1 ;
362+ }
363+ * data = (_PyBytes_data_t ){
364+ .bytes = bytes ,
365+ .len = len ,
366+ };
367+ return 0 ;
368+ }
355369
356- static PyObject *
357- _new_bytes_object ( _PyXIData_t * xidata )
370+ PyObject *
371+ _PyBytes_FromData ( _PyBytes_data_t * data )
358372{
359- struct _shared_bytes_data * shared = (struct _shared_bytes_data * )(xidata -> data );
360- return PyBytes_FromStringAndSize (shared -> bytes , shared -> len );
373+ return PyBytes_FromStringAndSize (data -> bytes , data -> len );
374+ }
375+
376+ PyObject *
377+ _PyBytes_FromXIData (_PyXIData_t * xidata )
378+ {
379+ _PyBytes_data_t * data = (_PyBytes_data_t * )xidata -> data ;
380+ assert (_PyXIData_OBJ (xidata ) != NULL
381+ && PyBytes_Check (_PyXIData_OBJ (xidata )));
382+ return _PyBytes_FromData (data );
361383}
362384
363385static int
364- _bytes_shared (PyThreadState * tstate , PyObject * obj , _PyXIData_t * xidata )
386+ _bytes_shared (PyThreadState * tstate ,
387+ PyObject * obj , size_t size , xid_newobjfunc newfunc ,
388+ _PyXIData_t * xidata )
365389{
390+ assert (size >= sizeof (_PyBytes_data_t ));
391+ assert (newfunc != NULL );
366392 if (_PyXIData_InitWithSize (
367- xidata , tstate -> interp , sizeof (struct _shared_bytes_data ), obj ,
368- _new_bytes_object
369- ) < 0 )
393+ xidata , tstate -> interp , size , obj , newfunc ) < 0 )
370394 {
371395 return -1 ;
372396 }
373- struct _shared_bytes_data * shared = (struct _shared_bytes_data * )xidata -> data ;
374- if (PyBytes_AsStringAndSize (obj , & shared -> bytes , & shared -> len ) < 0 ) {
397+ _PyBytes_data_t * data = (_PyBytes_data_t * )xidata -> data ;
398+ if (_PyBytes_GetData (obj , data ) < 0 ) {
375399 _PyXIData_Clear (tstate -> interp , xidata );
376400 return -1 ;
377401 }
378402 return 0 ;
379403}
380404
405+ int
406+ _PyBytes_GetXIData (PyThreadState * tstate , PyObject * obj , _PyXIData_t * xidata )
407+ {
408+ if (!PyBytes_Check (obj )) {
409+ PyErr_Format (PyExc_TypeError , "expected bytes, got %R" , obj );
410+ return -1 ;
411+ }
412+ size_t size = sizeof (_PyBytes_data_t );
413+ return _bytes_shared (tstate , obj , size , _PyBytes_FromXIData , xidata );
414+ }
415+
416+ _PyBytes_data_t *
417+ _PyBytes_GetXIDataWrapped (PyThreadState * tstate ,
418+ PyObject * obj , size_t size , xid_newobjfunc newfunc ,
419+ _PyXIData_t * xidata )
420+ {
421+ if (!PyBytes_Check (obj )) {
422+ PyErr_Format (PyExc_TypeError , "expected bytes, got %R" , obj );
423+ return NULL ;
424+ }
425+ if (size < sizeof (_PyBytes_data_t )) {
426+ PyErr_Format (PyExc_ValueError , "expected size >= %d, got %d" ,
427+ sizeof (_PyBytes_data_t ), size );
428+ return NULL ;
429+ }
430+ if (newfunc == NULL ) {
431+ if (size == sizeof (_PyBytes_data_t )) {
432+ PyErr_SetString (PyExc_ValueError , "missing new_object func" );
433+ return NULL ;
434+ }
435+ newfunc = _PyBytes_FromXIData ;
436+ }
437+ if (_bytes_shared (tstate , obj , size , newfunc , xidata ) < 0 ) {
438+ return NULL ;
439+ }
440+ return (_PyBytes_data_t * )xidata -> data ;
441+ }
442+
381443// str
382444
383445struct _shared_str_data {
@@ -608,7 +670,7 @@ _register_builtins_for_crossinterpreter_data(dlregistry_t *xidregistry)
608670 }
609671
610672 // bytes
611- if (_xidregistry_add_type (xidregistry , & PyBytes_Type , _bytes_shared ) != 0 ) {
673+ if (_xidregistry_add_type (xidregistry , & PyBytes_Type , _PyBytes_GetXIData ) != 0 ) {
612674 Py_FatalError ("could not register bytes for cross-interpreter sharing" );
613675 }
614676
0 commit comments