-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
bpo-32604: PEP 554 for use in test suite #19985
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
nanjekyejoannah
merged 13 commits into
python:master
from
nanjekyejoannah:pep_554_test_suite
May 19, 2020
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
02086f7
PEP 554 for use in test suite
b2fda3c
📜🤖 Added by blurb_it.
blurb-it[bot] 3667626
Fix space
cb594dd
Add doc to doc tree
0448a8a
Move to modules doc tree
85fde9f
Fix suspicious doc errors
f6af61c
Fix test__all
0decbee
Docs docs docs
3b35e1b
Support isolated and fix wait
nanjekyejoannah af90b25
Fix white space
nanjekyejoannah 90ec54b
Remove undefined from __all__
nanjekyejoannah 049aa3a
Fix recv and add exceptions
nanjekyejoannah 9577395
Remove unused exceptions, fix pep 8 formatting errors and fix _NOT_SE…
nanjekyejoannah File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
"""Subinterpreters High Level Module.""" | ||
|
||
import _xxsubinterpreters as _interpreters | ||
|
||
# aliases: | ||
from _xxsubinterpreters import ( | ||
ChannelError, ChannelNotFoundError, ChannelEmptyError, | ||
is_shareable, | ||
) | ||
|
||
nanjekyejoannah marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
__all__ = [ | ||
'Interpreter', 'get_current', 'get_main', 'create', 'list_all', | ||
'SendChannel', 'RecvChannel', | ||
'create_channel', 'list_all_channels', 'is_shareable', | ||
'ChannelError', 'ChannelNotFoundError', | ||
'ChannelEmptyError', | ||
] | ||
nanjekyejoannah marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
def create(*, isolated=True): | ||
""" | ||
Initialize a new (idle) Python interpreter. | ||
""" | ||
id = _interpreters.create(isolated=isolated) | ||
return Interpreter(id, isolated=isolated) | ||
|
||
nanjekyejoannah marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def list_all(): | ||
""" | ||
Get all existing interpreters. | ||
""" | ||
return [Interpreter(id) for id in | ||
_interpreters.list_all()] | ||
|
||
nanjekyejoannah marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def get_current(): | ||
""" | ||
Get the currently running interpreter. | ||
""" | ||
id = _interpreters.get_current() | ||
return Interpreter(id) | ||
|
||
nanjekyejoannah marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def get_main(): | ||
""" | ||
Get the main interpreter. | ||
""" | ||
id = _interpreters.get_main() | ||
return Interpreter(id) | ||
|
||
|
||
class Interpreter: | ||
""" | ||
The Interpreter object represents | ||
a single interpreter. | ||
""" | ||
|
||
def __init__(self, id, *, isolated=None): | ||
self._id = id | ||
self._isolated = isolated | ||
|
||
@property | ||
def id(self): | ||
return self._id | ||
|
||
@property | ||
def isolated(self): | ||
if self._isolated is None: | ||
self._isolated = _interpreters.is_isolated(self._id) | ||
return self._isolated | ||
|
||
def is_running(self): | ||
""" | ||
Return whether or not the identified | ||
interpreter is running. | ||
""" | ||
return _interpreters.is_running(self._id) | ||
|
||
def close(self): | ||
""" | ||
Finalize and destroy the interpreter. | ||
|
||
Attempting to destroy the current | ||
interpreter results in a RuntimeError. | ||
""" | ||
return _interpreters.destroy(self._id) | ||
|
||
def run(self, src_str, /, *, channels=None): | ||
""" | ||
Run the given source code in the interpreter. | ||
This blocks the current Python thread until done. | ||
""" | ||
_interpreters.run_string(self._id, src_str) | ||
|
||
|
||
def create_channel(): | ||
""" | ||
Create a new channel for passing data between | ||
interpreters. | ||
""" | ||
|
||
cid = _interpreters.channel_create() | ||
return (RecvChannel(cid), SendChannel(cid)) | ||
|
||
nanjekyejoannah marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def list_all_channels(): | ||
""" | ||
Get all open channels. | ||
""" | ||
return [(RecvChannel(cid), SendChannel(cid)) | ||
for cid in _interpreters.channel_list_all()] | ||
|
||
|
||
_NOT_SET = object() | ||
|
||
|
||
class RecvChannel: | ||
nanjekyejoannah marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
The RecvChannel object represents | ||
a recieving channel. | ||
""" | ||
|
||
def __init__(self, id): | ||
self._id = id | ||
|
||
def recv(self, *, _delay=10 / 1000): # 10 milliseconds | ||
""" | ||
Get the next object from the channel, | ||
and wait if none have been sent. | ||
Associate the interpreter with the channel. | ||
""" | ||
import time | ||
sentinel = object() | ||
obj = _interpreters.channel_recv(self._id, sentinel) | ||
while obj is sentinel: | ||
time.sleep(_delay) | ||
obj = _interpreters.channel_recv(self._id, sentinel) | ||
return obj | ||
|
||
def recv_nowait(self, default=_NOT_SET): | ||
""" | ||
Like recv(), but return the default | ||
instead of waiting. | ||
|
||
This function is blocked by a missing low-level | ||
implementation of channel_recv_wait(). | ||
""" | ||
if default is _NOT_SET: | ||
return _interpreters.channel_recv(self._id) | ||
else: | ||
return _interpreters.channel_recv(self._id, default) | ||
|
||
nanjekyejoannah marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
nanjekyejoannah marked this conversation as resolved.
Show resolved
Hide resolved
|
||
class SendChannel: | ||
""" | ||
The SendChannel object represents | ||
a sending channel. | ||
""" | ||
|
||
def __init__(self, id): | ||
self._id = id | ||
|
||
def send(self, obj): | ||
""" | ||
Send the object (i.e. its data) to the receiving | ||
end of the channel and wait. Associate the interpreter | ||
with the channel. | ||
""" | ||
import time | ||
_interpreters.channel_send(self._id, obj) | ||
time.sleep(2) | ||
|
||
def send_nowait(self, obj): | ||
""" | ||
Like send(), but return False if not received. | ||
|
||
This function is blocked by a missing low-level | ||
implementation of channel_send_wait(). | ||
""" | ||
|
||
_interpreters.channel_send(self._id, obj) | ||
return False |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
High-level implementation of Subinterpreters | ||
============================================ | ||
|
||
**Source code:** :source:`Lib/test/support/_interpreters.py` | ||
|
||
-------------- | ||
|
||
This module provides high-level tools for working with sub-interpreters, | ||
such as creating them, running code in them, or sending data between them. | ||
It is a wrapper around the low-level ``__xxsubinterpreters`` module. | ||
|
||
.. versionchanged:: added in 3.9 | ||
|
||
Interpreter Objects | ||
------------------- | ||
|
||
The ``Interpreter`` object represents a single interpreter. | ||
|
||
.. class:: Interpreter(id) | ||
|
||
The class implementing a subinterpreter object. | ||
|
||
.. method:: is_running() | ||
|
||
Return ``True`` if the identified interpreter is running. | ||
|
||
.. method:: close() | ||
|
||
Destroy the interpreter. Attempting to destroy the current | ||
interpreter results in a `RuntimeError`. | ||
|
||
.. method:: run(self, src_str, /, *, channels=None): | ||
|
||
Run the given source code in the interpreter. This blocks | ||
the current thread until done. ``channels`` should be in | ||
the form : `(RecvChannel, SendChannel)`. | ||
|
||
RecvChannel Objects | ||
------------------- | ||
|
||
The ``RecvChannel`` object represents a recieving channel. | ||
|
||
.. class:: RecvChannel(id) | ||
|
||
This class represents the receiving end of a channel. | ||
|
||
.. method:: recv() | ||
|
||
Get the next object from the channel, and wait if | ||
none have been sent. Associate the interpreter | ||
with the channel. | ||
|
||
.. method:: recv_nowait(default=None) | ||
|
||
Like ``recv()``, but return the default result | ||
instead of waiting. | ||
|
||
|
||
SendChannel Objects | ||
-------------------- | ||
|
||
The ``SendChannel`` object represents a sending channel. | ||
|
||
.. class:: SendChannel(id) | ||
|
||
This class represents the sending end of a channel. | ||
|
||
.. method:: send(obj) | ||
|
||
Send the object ``obj`` to the receiving end of the channel | ||
and wait. Associate the interpreter with the channel. | ||
|
||
.. method:: send_nowait(obj) | ||
|
||
Similar to ``send()``, but returns ``False`` if | ||
*obj* is not immediately received instead of blocking. | ||
|
||
|
||
This module defines the following global functions: | ||
|
||
|
||
.. function:: is_shareable(obj) | ||
|
||
Return ``True`` if the object's data can be shared between | ||
interpreters. | ||
|
||
.. function:: create_channel() | ||
|
||
Create a new channel for passing data between interpreters. | ||
|
||
.. function:: list_all_channels() | ||
|
||
Return all open channels. | ||
|
||
.. function:: create(*, isolated=True) | ||
|
||
Initialize a new (idle) Python interpreter. Get the currently | ||
running interpreter. This method returns an ``Interpreter`` object. | ||
|
||
.. function:: get_current() | ||
|
||
Get the currently running interpreter. This method returns | ||
an ``Interpreter`` object. | ||
|
||
.. function:: get_main() | ||
|
||
Get the main interpreter. This method returns | ||
an ``Interpreter`` object. | ||
|
||
.. function:: list_all() | ||
|
||
Get all existing interpreters. Returns a list | ||
of ``Interpreter`` objects. | ||
|
||
This module also defines the following exceptions. | ||
|
||
.. exception:: RunFailedError | ||
|
||
This exception, a subclass of :exc:`RuntimeError`, is raised when the | ||
``Interpreter.run()`` results in an uncaught exception. | ||
|
||
.. exception:: ChannelError | ||
|
||
This exception is a subclass of :exc:`Exception`, and is the base | ||
class for all channel-related exceptions. | ||
|
||
.. exception:: ChannelNotFoundError | ||
|
||
This exception is a subclass of :exc:`ChannelError`, and is raised | ||
when the the identified channel is not found. | ||
|
||
.. exception:: ChannelEmptyError | ||
|
||
This exception is a subclass of :exc:`ChannelError`, and is raised when | ||
the channel is unexpectedly empty. | ||
|
||
.. exception:: ChannelNotEmptyError | ||
|
||
This exception is a subclass of :exc:`ChannelError`, and is raised when | ||
the channel is unexpectedly not empty. | ||
|
||
.. exception:: NotReceivedError | ||
|
||
This exception is a subclass of :exc:`ChannelError`, and is raised when | ||
nothing was waiting to receive a sent object. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.