1- """Subinterpreters High Level Module."""
1+ """Cross-interpreter Channels High Level Module."""
22
33import time
4- import _xxsubinterpreters as _interpreters
54import _xxinterpchannels as _channels
65
76# aliases:
8- from _xxsubinterpreters import is_shareable
97from _xxinterpchannels import (
108 ChannelError , ChannelNotFoundError , ChannelClosedError ,
119 ChannelEmptyError , ChannelNotEmptyError ,
1210)
1311
1412
1513__all__ = [
16- 'Interpreter' , 'get_current' , 'get_main' , 'create' , 'list_all' ,
17- 'RunFailedError' ,
14+ 'create' , 'list_all' ,
1815 'SendChannel' , 'RecvChannel' ,
19- 'create_channel' , 'list_all_channels' , 'is_shareable' ,
20- 'ChannelError' , 'ChannelNotFoundError' ,
21- 'ChannelEmptyError' ,
22- ]
16+ 'ChannelError' , 'ChannelNotFoundError' , 'ChannelEmptyError' ,
17+ ]
2318
2419
25- class RunFailedError (RuntimeError ):
26-
27- def __init__ (self , excinfo ):
28- msg = excinfo .formatted
29- if not msg :
30- if excinfo .type and snapshot .msg :
31- msg = f'{ snapshot .type .__name__ } : { snapshot .msg } '
32- else :
33- msg = snapshot .type .__name__ or snapshot .msg
34- super ().__init__ (msg )
35- self .snapshot = excinfo
36-
37-
38- def create (* , isolated = True ):
39- """Return a new (idle) Python interpreter."""
40- id = _interpreters .create (isolated = isolated )
41- return Interpreter (id , isolated = isolated )
42-
43-
44- def list_all ():
45- """Return all existing interpreters."""
46- return [Interpreter (id ) for id in _interpreters .list_all ()]
47-
48-
49- def get_current ():
50- """Return the currently running interpreter."""
51- id = _interpreters .get_current ()
52- return Interpreter (id )
53-
54-
55- def get_main ():
56- """Return the main interpreter."""
57- id = _interpreters .get_main ()
58- return Interpreter (id )
59-
60-
61- class Interpreter :
62- """A single Python interpreter."""
63-
64- def __init__ (self , id , * , isolated = None ):
65- if not isinstance (id , (int , _interpreters .InterpreterID )):
66- raise TypeError (f'id must be an int, got { id !r} ' )
67- self ._id = id
68- self ._isolated = isolated
69-
70- def __repr__ (self ):
71- data = dict (id = int (self ._id ), isolated = self ._isolated )
72- kwargs = (f'{ k } ={ v !r} ' for k , v in data .items ())
73- return f'{ type (self ).__name__ } ({ ", " .join (kwargs )} )'
74-
75- def __hash__ (self ):
76- return hash (self ._id )
77-
78- def __eq__ (self , other ):
79- if not isinstance (other , Interpreter ):
80- return NotImplemented
81- else :
82- return other ._id == self ._id
83-
84- @property
85- def id (self ):
86- return self ._id
87-
88- @property
89- def isolated (self ):
90- if self ._isolated is None :
91- # XXX The low-level function has not been added yet.
92- # See bpo-....
93- self ._isolated = _interpreters .is_isolated (self ._id )
94- return self ._isolated
95-
96- def is_running (self ):
97- """Return whether or not the identified interpreter is running."""
98- return _interpreters .is_running (self ._id )
99-
100- def close (self ):
101- """Finalize and destroy the interpreter.
102-
103- Attempting to destroy the current interpreter results
104- in a RuntimeError.
105- """
106- return _interpreters .destroy (self ._id )
107-
108- # XXX Rename "run" to "exec"?
109- def run (self , src_str , / , channels = None ):
110- """Run the given source code in the interpreter.
111-
112- This is essentially the same as calling the builtin "exec"
113- with this interpreter, using the __dict__ of its __main__
114- module as both globals and locals.
115-
116- There is no return value.
117-
118- If the code raises an unhandled exception then a RunFailedError
119- is raised, which summarizes the unhandled exception. The actual
120- exception is discarded because objects cannot be shared between
121- interpreters.
122-
123- This blocks the current Python thread until done. During
124- that time, the previous interpreter is allowed to run
125- in other threads.
126- """
127- excinfo = _interpreters .exec (self ._id , src_str , channels )
128- if excinfo is not None :
129- raise RunFailedError (excinfo )
130-
131-
132- def create_channel ():
20+ def create ():
13321 """Return (recv, send) for a new cross-interpreter channel.
13422
13523 The channel may be used to pass data safely between interpreters.
@@ -139,7 +27,7 @@ def create_channel():
13927 return recv , send
14028
14129
142- def list_all_channels ():
30+ def list_all ():
14331 """Return a list of (recv, send) for all open channels."""
14432 return [(RecvChannel (cid ), SendChannel (cid ))
14533 for cid in _channels .list_all ()]
0 commit comments