3333
3434/*[clinic input]
3535module _interpreters
36+ class _interpreters.SharedObjectProxy "SharedObjectProxy *" "&PyType_Type"
3637[clinic start generated code]*/
37- /*[clinic end generated code: output=da39a3ee5e6b4b0d input=bfd967980a0de892 ]*/
38+ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=4bb543de3f19aa0b ]*/
3839
3940static PyInterpreterState *
4041_get_current_interp (void )
@@ -458,17 +459,44 @@ _sharedobjectproxy_exit(SharedObjectProxy *self, _PyXI_proxy_state *state)
458459 return 0 ;
459460}
460461
461- static PyObject *
462- sharedobjectproxy_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
462+ static SharedObjectProxy *
463+ sharedobjectproxy_alloc (PyTypeObject * type )
463464{
464- SharedObjectProxy * self = (SharedObjectProxy * )type -> tp_alloc (type , 0 );
465+ assert (type != NULL );
466+ assert (PyType_Check (type ));
467+ SharedObjectProxy * self = SharedObjectProxy_CAST (type -> tp_alloc (type , 0 ));
465468 if (self == NULL ) {
466469 return NULL ;
467470 }
468471
469- self -> object = Py_None ;
470472 self -> interp = _PyInterpreterState_GET ();
473+ #ifndef NDEBUG
474+ self -> object = NULL ;
475+ #endif
476+
477+ return self ;
478+ }
479+
480+ /*[clinic input]
481+ @classmethod
482+ _interpreters.SharedObjectProxy.__new__ as sharedobjectproxy_new
483+
484+ obj: object,
485+ /
486+
487+ Create a new cross-interpreter proxy.
488+ [clinic start generated code]*/
471489
490+ static PyObject *
491+ sharedobjectproxy_new_impl (PyTypeObject * type , PyObject * obj )
492+ /*[clinic end generated code: output=42ed0a0bc47ecedf input=fce004d93517c6df]*/
493+ {
494+ SharedObjectProxy * self = sharedobjectproxy_alloc (type );
495+ if (self == NULL ) {
496+ return NULL ;
497+ }
498+
499+ self -> object = Py_NewRef (obj );
472500 return (PyObject * )self ;
473501}
474502
@@ -483,8 +511,7 @@ _sharedobjectproxy_create(PyObject *object, PyInterpreterState *owning_interp)
483511 return NULL ;
484512 }
485513 assert (Py_TYPE (object ) != type );
486- SharedObjectProxy * proxy = SharedObjectProxy_CAST (sharedobjectproxy_new (type ,
487- NULL , NULL ));
514+ SharedObjectProxy * proxy = sharedobjectproxy_alloc (type );
488515 if (proxy == NULL ) {
489516 return NULL ;
490517 }
@@ -1278,8 +1305,7 @@ static PyType_Slot SharedObjectProxy_slots[] = {
12781305static PyType_Spec SharedObjectProxy_spec = {
12791306 .name = MODULE_NAME_STR ".SharedObjectProxy" ,
12801307 .basicsize = sizeof (SharedObjectProxy ),
1281- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1282- Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE
1308+ .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE
12831309 | Py_TPFLAGS_HAVE_GC ),
12841310 .slots = SharedObjectProxy_slots ,
12851311};
@@ -2521,22 +2547,53 @@ _interpreters_capture_exception_impl(PyObject *module, PyObject *exc_arg)
25212547 return captured ;
25222548}
25232549
2550+ static PyObject *
2551+ call_share_method_steal (PyObject * method )
2552+ {
2553+ assert (method != NULL );
2554+ PyObject * result = PyObject_CallNoArgs (method );
2555+ Py_DECREF (method );
2556+ if (result == NULL ) {
2557+ return NULL ;
2558+ }
2559+
2560+ PyThreadState * tstate = _PyThreadState_GET ();
2561+ assert (tstate != NULL );
2562+
2563+ if (_PyObject_CheckXIData (tstate , result ) < 0 ) {
2564+ PyObject * exc = _PyErr_GetRaisedException (tstate );
2565+ _PyXIData_FormatNotShareableError (tstate , "__share__() returned unshareable object: %R" , result );
2566+ PyObject * new_exc = _PyErr_GetRaisedException (tstate );
2567+ PyException_SetCause (new_exc , exc );
2568+ PyErr_SetRaisedException (new_exc );
2569+ Py_DECREF (result );
2570+ return NULL ;
2571+ }
2572+
2573+ return result ;
2574+ }
2575+
25242576/*[clinic input]
25252577_interpreters.share
25262578 op: object,
25272579 /
25282580
25292581
25302582Wrap an object in a shareable proxy that allows cross-interpreter access.
2531-
2532- The proxy will be assigned a context and may have its references cleared by
2533- _interpreters.close_proxy().
25342583[clinic start generated code]*/
25352584
25362585static PyObject *
25372586_interpreters_share (PyObject * module , PyObject * op )
2538- /*[clinic end generated code: output=e2ce861ae3b58508 input=d333c93f128faf93 ]*/
2587+ /*[clinic end generated code: output=e2ce861ae3b58508 input=5fb300b5598bb7d2 ]*/
25392588{
2589+ PyObject * share_method ;
2590+ if (PyObject_GetOptionalAttrString (op , "__share__" , & share_method ) < 0 ) {
2591+ return NULL ;
2592+ }
2593+ if (share_method != NULL ) {
2594+ return call_share_method_steal (share_method /* stolen */ );
2595+ }
2596+
25402597 return _sharedobjectproxy_create (op , _PyInterpreterState_GET ());
25412598}
25422599
0 commit comments