@@ -30,6 +30,18 @@ For example:
3030 interp.prepare_main(file = proxy)
3131 interp.exec(" file.write('I didn't expect the Spanish Inquisition')" )
3232
33+ Terminology
34+ ===========
35+
36+ This PEP uses the term "share", "sharing", and "shareable" to refer to objects
37+ that are *natively * shareable between interpreters. This differs from :pep: `734 `,
38+ which uses these terms to also describe an object that supports the :mod: `pickle `
39+ module.
40+
41+ In addition to the new :class: `~concurrent.interpreters.SharedObjectProxy ` type,
42+ the list of natively shareable objects can be found in :ref: `the documentation
43+ <interp-object-sharing>`.
44+
3345Motivation
3446==========
3547
@@ -69,21 +81,56 @@ implementing other methods to share objects between interpreters.
6981Specification
7082=============
7183
72- .. class :: concurrent.interpreters.SharedObjectProxy
84+
85+ .. function :: concurrent.interpreters.share(obj)
86+
87+ Ensure *obj * is natively shareable.
88+
89+ If *obj * is natively shareable, this function does not create a proxy and
90+ simply returns *obj *. Otherwise, *obj * is wrapped in an instance of
91+ :class: `~concurrent.interpreters.SharedObjectProxy ` and returned.
92+
93+ If *obj * has a :meth: `~object.__share__ ` method, the default behavior of
94+ this function is overridden; the object's ``__share__ `` method will be
95+ called to convert *obj * into a natively shareable version of itself, which
96+ will be returned by this function. If the object returned by ``__share__ ``
97+ is not natively shareable, this function raises an exception.
98+
99+ The behavior of this function is roughly equivalent to:
100+
101+ .. code-block :: python
102+
103+ def share (obj ):
104+ if _is_natively_shareable(obj):
105+ return obj
106+
107+ if hasattr (obj, " __share__" ):
108+ shareable = obj.__share__()
109+ if not _is_natively_shareable(shareable):
110+ raise TypeError (f " __share__() returned unshareable object: { shareable!r } " )
111+
112+ return shareable
113+
114+ return SharedObjectProxy(obj)
115+
116+
117+ .. class :: concurrent.interpreters.SharedObjectProxy(obj)
73118
74119 A proxy type that allows access to an object across multiple interpreters.
75- This cannot be constructed from Python; instead, use the
76- :func: `~concurrent.interpreters.share ` function.
120+ Instances of this object are natively shareable between subinterpreters.
77121
122+ Unlike :func: `~concurrent.interpreters.share `, *obj * will always be wrapped,
123+ even if it is natively shareable already or already a ``SharedObjectProxy ``
124+ instance. The object's :meth: `~object.__share__ ` method is not invoked if
125+ it is available. Thus, prefer using ``share `` where possible.
78126
79- .. function :: concurrent.interpreters.share(obj)
80127
81- Wrap *obj * in a :class: `~concurrent.interpreters.SharedObjectProxy `,
82- allowing it to be used in other interpreter APIs as if it were natively
83- shareable.
128+ .. function :: object.__share__()
84129
85- If *obj * is natively shareable, this function does not create a proxy and
86- simply returns *obj *.
130+ Return a natively shareable version of the current object. This includes
131+ shared object proxies, as they are also natively shareable. Objects composed
132+ of shared object proxies are also allowed, such as a :class: `tuple ` whose
133+ elements are :class: `~concurrent.interpreters.SharedObjectProxy ` instances.
87134
88135
89136Interpreter Switching
@@ -108,6 +155,26 @@ accessed in subinterpreters through a proxy:
108155 interp.exec(" foo()" )
109156
110157
158+ Method Proxying
159+ ---------------
160+
161+ Methods on a shared object proxy will switch to their owning interpreter when
162+ accessed. In addition, any arguments passed to the method are implicitly called
163+ with :func: `~concurrent.interpreters.share ` to ensure they are shareable (only
164+ types that are not natively shareable are wrapped in a proxy). The same happens
165+ to the return value of the method.
166+
167+ For example, the ``__add__ `` method on an object proxy is roughly equivalent
168+ to the following code:
169+
170+ .. code-block :: python
171+
172+ def __add__ (self , other ):
173+ with self .switch_interpreter():
174+ result = self .value.__add__ (share(other))
175+ return share(result)
176+
177+
111178 Multithreaded Scaling
112179---------------------
113180
0 commit comments