diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst
index 6d2a61a437..1490d1b03d 100644
--- a/docs/source/contributing.rst
+++ b/docs/source/contributing.rst
@@ -254,7 +254,7 @@ Some rules for writing good tests:
`__
Most major features have both real tests and tests using fakes or
- stubs. For example, :class:`~trio.ssl.SSLStream` has some tests that
+ stubs. For example, :class:`~trio.SSLStream` has some tests that
use Trio to make a real socket connection to real SSL server
implemented using blocking I/O, because it sure would be
embarrassing if that didn't work. And then there are also a bunch of
diff --git a/docs/source/history.rst b/docs/source/history.rst
index cc5bfa6d3b..356293eebb 100644
--- a/docs/source/history.rst
+++ b/docs/source/history.rst
@@ -12,9 +12,9 @@ Features
~~~~~~~~
- Initial :ref:`subprocess support `. Add
- :class:`trio.subprocess.Process`, an async wrapper around the stdlib
+ :class:`trio.subprocess.Process `, an async wrapper around the stdlib
:class:`subprocess.Popen` class, which permits spawning subprocesses and
- communicating with them over standard Trio streams. :mod:`trio.subprocess`
+ communicating with them over standard Trio streams. ``trio.subprocess``
also reexports all the stdlib :mod:`subprocess` exceptions and constants for
convenience. (`#4 `__)
- You can now create an unbounded :class:`CapacityLimiter` by initializing with
@@ -49,12 +49,13 @@ Deprecations and Removals
Miscellaneous internal changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- There are a number of methods on :class:`trio.ssl.SSLStream` that report
- information about the negotiated TLS connection, like
+- There are a number of methods on :class:`trio.ssl.SSLStream `
+ that report information about the negotiated TLS connection, like
``selected_alpn_protocol``, and thus cannot succeed until after the handshake
has been performed. Previously, we returned None from these methods, like the
stdlib :mod:`ssl` module does, but this is confusing, because that can also
- be a valid return value. Now we raise :exc:`trio.ssl.NeedHandshakeError`
+ be a valid return value. Now we raise :exc:`trio.ssl.NeedHandshakeError
+ `
instead. (`#735 `__)
@@ -384,11 +385,11 @@ Highlights
`__.
See: :func:`trio.open_ssl_over_tcp_stream`,
:func:`trio.serve_ssl_over_tcp`,
- :func:`trio.open_ssl_over_tcp_listeners`, and :mod:`trio.ssl`.
+ :func:`trio.open_ssl_over_tcp_listeners`, and ``trio.ssl``.
- Interesting fact: the test suite for :mod:`trio.ssl` has so far
+ Interesting fact: the test suite for ``trio.ssl`` has so far
found bugs in CPython's ssl module, PyPy's ssl module, PyOpenSSL,
- and OpenSSL. (:mod:`trio.ssl` doesn't use PyOpenSSL.) Trio's test
+ and OpenSSL. (``trio.ssl`` doesn't use PyOpenSSL.) Trio's test
suite is fairly thorough.
* You know thread-local storage? Well, Trio now has an equivalent:
@@ -436,7 +437,7 @@ that worked on 0.1.0):
* When a socket ``sendall`` call was cancelled, it used to attach some
metadata to the exception reporting how much data was actually sent.
It no longer does this, because in common configurations like an
- :class:`~trio.ssl.SSLStream` wrapped around a
+ :class:`~trio.SSLStream` wrapped around a
:class:`~trio.SocketStream` it becomes ambiguous which "level" the
partial metadata applies to, leading to confusion and bugs. There is
no longer any way to tell how much data was sent after a ``sendall``
diff --git a/docs/source/reference-io.rst b/docs/source/reference-io.rst
index bb0be79fa9..b42d9d04c2 100644
--- a/docs/source/reference-io.rst
+++ b/docs/source/reference-io.rst
@@ -18,11 +18,11 @@ create complex transport configurations. Here's some examples:
* :class:`trio.SocketStream` wraps a raw socket (like a TCP connection
over the network), and converts it to the standard stream interface.
-* :class:`trio.ssl.SSLStream` is a "stream adapter" that can take any
+* :class:`trio.SSLStream` is a "stream adapter" that can take any
object that implements the :class:`trio.abc.Stream` interface, and
convert it into an encrypted stream. In trio the standard way to
speak SSL over the network is to wrap an
- :class:`~trio.ssl.SSLStream` around a :class:`~trio.SocketStream`.
+ :class:`~trio.SSLStream` around a :class:`~trio.SocketStream`.
* If you spawn a :ref:`subprocess`, you can get a
:class:`~trio.abc.SendStream` that lets you write to its stdin, and
@@ -30,9 +30,9 @@ create complex transport configurations. Here's some examples:
stdout. If for some reason you wanted to speak SSL to a subprocess,
you could use a :class:`StapledStream` to combine its stdin/stdout
into a single bidirectional :class:`~trio.abc.Stream`, and then wrap
- that in an :class:`~trio.ssl.SSLStream`::
+ that in an :class:`~trio.SSLStream`::
- ssl_context = trio.ssl.create_default_context()
+ ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
s = SSLStream(StapledStream(process.stdin, process.stdout), ssl_context)
@@ -41,8 +41,8 @@ create complex transport configurations. Here's some examples:
HTTPS. So you end up having to do `SSL-on-top-of-SSL
`__. In
trio this is trivial – just wrap your first
- :class:`~trio.ssl.SSLStream` in a second
- :class:`~trio.ssl.SSLStream`::
+ :class:`~trio.SSLStream` in a second
+ :class:`~trio.SSLStream`::
# Get a raw SocketStream connection to the proxy:
s0 = await open_tcp_stream("proxy", 443)
@@ -104,7 +104,7 @@ Abstract base classes
- :class:`SendStream`, :class:`ReceiveStream`
-
-
- - :class:`~trio.ssl.SSLStream`
+ - :class:`~trio.SSLStream`
* - :class:`HalfCloseableStream`
- :class:`Stream`
- :meth:`~HalfCloseableStream.send_eof`
@@ -114,7 +114,7 @@ Abstract base classes
- :class:`AsyncResource`
- :meth:`~Listener.accept`
-
- - :class:`~trio.SocketListener`, :class:`~trio.ssl.SSLListener`
+ - :class:`~trio.SocketListener`, :class:`~trio.SSLListener`
* - :class:`SendChannel`
- :class:`AsyncResource`
- :meth:`~SendChannel.send`, :meth:`~SendChannel.send_nowait`
@@ -220,17 +220,18 @@ abstraction.
SSL / TLS support
~~~~~~~~~~~~~~~~~
-.. module:: trio.ssl
+Trio provides SSL/TLS support based on the standard library :mod:`ssl`
+module. Trio's :class:`SSLStream` and :class:`SSLListener` take their
+configuration from a :class:`ssl.SSLContext`, which you can create
+using :func:`ssl.create_default_context` and customize using the
+other constants and functions in the :mod:`ssl` module.
-The :mod:`trio.ssl` module implements SSL/TLS support for Trio, using
-the standard library :mod:`ssl` module. It re-exports most of
-:mod:`ssl`\´s API, with the notable exception of
-:class:`ssl.SSLContext`, which has unsafe defaults; if you really want
-to use :class:`ssl.SSLContext` you can import it from :mod:`ssl`, but
-normally you should create your contexts using
-:func:`trio.ssl.create_default_context `.
+.. warning:: Avoid instantiating :class:`ssl.SSLContext` directly.
+ A newly constructed :class:`~ssl.SSLContext` has less secure
+ defaults than one returned by :func:`ssl.create_default_context`,
+ dramatically so before Python 3.6.
-Instead of using :meth:`ssl.SSLContext.wrap_socket`, though, you
+Instead of using :meth:`ssl.SSLContext.wrap_socket`, you
create a :class:`SSLStream`:
.. autoclass:: SSLStream
@@ -643,24 +644,16 @@ Asynchronous file objects
The underlying synchronous file object.
-.. module:: trio.subprocess
.. _subprocess:
-Spawning subprocesses with :mod:`trio.subprocess`
--------------------------------------------------
+Spawning subprocesses
+---------------------
-The :mod:`trio.subprocess` module provides support for spawning
-other programs, communicating with them via pipes, sending them signals,
-and waiting for them to exit. Its interface is based on the
-:mod:`subprocess` module in the standard library; differences
-are noted below.
-
-The constants and exceptions from the standard :mod:`subprocess`
-module are re-exported by :mod:`trio.subprocess` unchanged.
-So, if you like, you can say ``from trio import subprocess``
-and continue referring to ``subprocess.PIPE``,
-:exc:`subprocess.CalledProcessError`, and so on, in the same
-way you would in synchronous code.
+Trio provides support for spawning other programs as subprocesses,
+communicating with them via pipes, sending them signals, and waiting
+for them to exit. Currently this interface consists of the
+:class:`trio.Process` class, which is modelled after :class:`subprocess.Popen`
+in the standard library.
.. _subprocess-options:
@@ -676,13 +669,15 @@ overwhelming, you're not alone; you might prefer to start with
just the `frequently used ones
`__.)
-Trio makes use of the :mod:`subprocess` module's logic for spawning processes,
-so almost all of these options can be used with their same semantics when
-starting subprocesses under Trio. The exceptions are ``encoding``, ``errors``,
+Trio makes use of the :mod:`subprocess` module's logic for spawning
+processes, so almost all of these options can be used with their same
+semantics when starting subprocesses under Trio. (You may need to
+``import subprocess`` in order to access constants such as ``PIPE`` or
+``DEVNULL``.) The exceptions are ``encoding``, ``errors``,
``universal_newlines`` (and its 3.7+ alias ``text``), and ``bufsize``;
-Trio always uses unbuffered byte streams for communicating with a process,
-so these options don't make sense. Text I/O should use a layer
-on top of the raw byte streams, just as it does with sockets.
+Trio always uses unbuffered byte streams for communicating with a
+process, so these options don't make sense. Text I/O should use a
+layer on top of the raw byte streams, just as it does with sockets.
[This layer does not yet exist, but is in the works.]
@@ -692,7 +687,7 @@ Running a process and waiting for it to finish
We're `working on `__
figuring out the best API for common higher-level subprocess operations.
In the meantime, you can implement something like the standard library
-:func:`subprocess.run` in terms of :class:`trio.subprocess.Process`
+:func:`subprocess.run` in terms of :class:`trio.Process`
as follows::
async def run(
@@ -706,7 +701,7 @@ as follows::
stdout_chunks = []
stderr_chunks = []
- async with trio.subprocess.Process(command, **options) as proc:
+ async with trio.Process(command, **options) as proc:
async def feed_input():
async with proc.stdin:
@@ -750,27 +745,24 @@ Interacting with a process as it runs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can spawn a subprocess by creating an instance of
-:class:`trio.subprocess.Process` and then interact with it using its
-:attr:`~trio.subprocess.Process.stdin`,
-:attr:`~trio.subprocess.Process.stdout`, and/or
-:attr:`~trio.subprocess.Process.stderr` streams.
+:class:`trio.Process` and then interact with it using its
+:attr:`~trio.Process.stdin`,
+:attr:`~trio.Process.stdout`, and/or
+:attr:`~trio.Process.stderr` streams.
-.. autoclass:: trio.subprocess.Process
+.. autoclass:: trio.Process
:members:
-Differences from the standard library
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Differences from :class:`subprocess.Popen`
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* All arguments to the constructor of
- :class:`~trio.subprocess.Process`, except the command to run, must be
+ :class:`~trio.Process`, except the command to run, must be
passed using keywords.
-* :func:`~subprocess.call`, :func:`~subprocess.check_call`, and
- :func:`~subprocess.check_output` are not provided.
-
* :meth:`~subprocess.Popen.communicate` is not provided as a method on
- :class:`~trio.subprocess.Process` objects; use a higher-level
+ :class:`~trio.Process` objects; use a higher-level
function instead, or write the loop yourself if
you have unusual needs. :meth:`~subprocess.Popen.communicate` has
quite unusual cancellation behavior in the standard library (on some
@@ -778,22 +770,22 @@ Differences from the standard library
the child process even after the timeout has expired) and we wanted
to provide an interface with fewer surprises.
-* :meth:`~trio.subprocess.Process.wait` is an async function that does
+* :meth:`~trio.Process.wait` is an async function that does
not take a ``timeout`` argument; combine it with
:func:`~trio.fail_after` if you want a timeout.
* Text I/O is not supported: you may not use the
- :class:`~trio.subprocess.Process` constructor arguments
+ :class:`~trio.Process` constructor arguments
``universal_newlines`` (or its 3.7+ alias ``text``), ``encoding``,
or ``errors``.
-* :attr:`~trio.subprocess.Process.stdin` is a :class:`~trio.abc.SendStream` and
- :attr:`~trio.subprocess.Process.stdout` and :attr:`~trio.subprocess.Process.stderr`
+* :attr:`~trio.Process.stdin` is a :class:`~trio.abc.SendStream` and
+ :attr:`~trio.Process.stdout` and :attr:`~trio.Process.stderr`
are :class:`~trio.abc.ReceiveStream`\s, rather than file objects. The
- :class:`~trio.subprocess.Process` constructor argument ``bufsize`` is
+ :class:`~trio.Process` constructor argument ``bufsize`` is
not supported since there would be no file object to pass it to.
-* :meth:`~trio.subprocess.Process.aclose` (and thus also
+* :meth:`~trio.Process.aclose` (and thus also
``__aexit__``) behave like the standard :class:`~subprocess.Popen`
context manager exit (close pipes to the process, then wait for it
to exit), but add additional behavior if cancelled: kill the process
diff --git a/newsfragments/852.removal.rst b/newsfragments/852.removal.rst
new file mode 100644
index 0000000000..86e96896f7
--- /dev/null
+++ b/newsfragments/852.removal.rst
@@ -0,0 +1,6 @@
+The submodules ``trio.ssl`` and ``trio.subprocess`` are now deprecated.
+Their nontrivial contents (:class:`~trio.Process`, :class:`~trio.SSLStream`,
+and :class:`~trio.SSLListener`) have been moved to the main :mod:`trio`
+namespace. For the numerous constants, exceptions, and other helpers
+that were previously reexported from the standard :mod:`ssl` and
+:mod:`subprocess` modules, you should now use those modules directly.
diff --git a/trio/__init__.py b/trio/__init__.py
index 2cab1e5818..9aac6c1469 100644
--- a/trio/__init__.py
+++ b/trio/__init__.py
@@ -48,6 +48,10 @@
from ._path import Path
+from ._subprocess import Process
+
+from ._ssl import SSLStream, SSLListener, NeedHandshakeError
+
from ._highlevel_serve_listeners import serve_listeners
from ._highlevel_open_tcp_stream import open_tcp_stream
@@ -66,12 +70,13 @@
from . import hazmat
from . import socket
from . import abc
-from . import ssl
-from . import subprocess
# Not imported by default: testing
if False:
from . import testing
+from . import _deprecated_ssl_reexports
+from . import _deprecated_subprocess_reexports
+
_deprecate.enable_attribute_deprecations(__name__)
__deprecated_attributes__ = {
"BrokenStreamError":
@@ -85,6 +90,27 @@
_deprecate.DeprecatedAttribute(
BusyResourceError, "0.8.0", issue=620, instead=BusyResourceError
),
+ "ssl":
+ _deprecate.DeprecatedAttribute(
+ _deprecated_ssl_reexports,
+ "0.11.0",
+ issue=852,
+ instead=(
+ "trio.SSLStream, trio.SSLListener, trio.NeedHandshakeError, "
+ "and the standard library 'ssl' module (minus SSLSocket and "
+ "wrap_socket())"
+ ),
+ ),
+ "subprocess":
+ _deprecate.DeprecatedAttribute(
+ _deprecated_subprocess_reexports,
+ "0.11.0",
+ issue=852,
+ instead=(
+ "trio.Process and the constants in the standard "
+ "library 'subprocess' module"
+ ),
+ ),
}
# Having the public path in .__module__ attributes is important for:
@@ -98,5 +124,8 @@
fixup_module_metadata(hazmat.__name__, hazmat.__dict__)
fixup_module_metadata(socket.__name__, socket.__dict__)
fixup_module_metadata(abc.__name__, abc.__dict__)
-fixup_module_metadata(ssl.__name__, ssl.__dict__)
+fixup_module_metadata(__name__ + ".ssl", _deprecated_ssl_reexports.__dict__)
+fixup_module_metadata(
+ __name__ + ".subprocess", _deprecated_subprocess_reexports.__dict__
+)
del fixup_module_metadata
diff --git a/trio/_abc.py b/trio/_abc.py
index 704622cf50..c9957f1c5c 100644
--- a/trio/_abc.py
+++ b/trio/_abc.py
@@ -241,7 +241,7 @@ async def aclose(self):
connection. This requires sending a "goodbye" message; but if the peer
has become non-responsive, then our attempt to send this message might
block forever, and eventually time out and be cancelled. In this case
- the :meth:`aclose` method on :class:`~trio.ssl.SSLStream` will
+ the :meth:`aclose` method on :class:`~trio.SSLStream` will
immediately close the underlying transport stream using
:func:`trio.aclose_forcefully` before raising :exc:`~trio.Cancelled`.
@@ -463,7 +463,7 @@ async def send_eof(self):
* On an SSL/TLS-encrypted connection, the protocol doesn't provide any
way to do a unidirectional shutdown without closing the connection
- entirely, so :class:`~trio.ssl.SSLStream` implements
+ entirely, so :class:`~trio.SSLStream` implements
:class:`Stream`, not :class:`HalfCloseableStream`.
If an EOF has already been sent, then this method should silently
diff --git a/trio/ssl.py b/trio/_deprecated_ssl_reexports.py
similarity index 100%
rename from trio/ssl.py
rename to trio/_deprecated_ssl_reexports.py
diff --git a/trio/subprocess.py b/trio/_deprecated_subprocess_reexports.py
similarity index 100%
rename from trio/subprocess.py
rename to trio/_deprecated_subprocess_reexports.py
diff --git a/trio/_highlevel_generic.py b/trio/_highlevel_generic.py
index 3a0aa51814..05a03043fa 100644
--- a/trio/_highlevel_generic.py
+++ b/trio/_highlevel_generic.py
@@ -19,7 +19,7 @@ async def aclose_forcefully(resource):
Most users won't need this, but it may be useful on cleanup paths where
you can't afford to block, or if you want to close a resource and don't
care about handling it gracefully. For example, if
- :class:`~trio.ssl.SSLStream` encounters an error and cannot perform its
+ :class:`~trio.SSLStream` encounters an error and cannot perform its
own graceful close, then there's no point in waiting to gracefully shut
down the underlying transport either, so it calls ``await
aclose_forcefully(self.transport_stream)``.
diff --git a/trio/_highlevel_ssl_helpers.py b/trio/_highlevel_ssl_helpers.py
index 1d7b80d708..ce78832087 100644
--- a/trio/_highlevel_ssl_helpers.py
+++ b/trio/_highlevel_ssl_helpers.py
@@ -1,4 +1,5 @@
import trio
+import ssl
from ._highlevel_open_tcp_stream import DEFAULT_DELAY
@@ -33,10 +34,10 @@ async def open_ssl_over_tcp_stream(
"""Make a TLS-encrypted Connection to the given host and port over TCP.
This is a convenience wrapper that calls :func:`open_tcp_stream` and
- wraps the result in an :class:`~trio.ssl.SSLStream`.
+ wraps the result in an :class:`~trio.SSLStream`.
This function does not perform the TLS handshake; you can do it
- manually by calling :meth:`~trio.ssl.SSLStream.do_handshake`, or else
+ manually by calling :meth:`~trio.SSLStream.do_handshake`, or else
it will be performed automatically the first time you send or receive
data.
@@ -45,7 +46,7 @@ async def open_ssl_over_tcp_stream(
to have a TLS certificate valid for this hostname.
port (int): The port to connect to.
https_compatible (bool): Set this to True if you're connecting to a web
- server. See :class:`~trio.ssl.SSLStream` for details. Default:
+ server. See :class:`~trio.SSLStream` for details. Default:
False.
ssl_context (:class:`~ssl.SSLContext` or None): The SSL context to
use. If None (the default), :func:`ssl.create_default_context`
@@ -53,7 +54,7 @@ async def open_ssl_over_tcp_stream(
happy_eyeballs_delay (float): See :func:`open_tcp_stream`.
Returns:
- trio.ssl.SSLStream: the encrypted connection to the server.
+ trio.SSLStream: the encrypted connection to the server.
"""
tcp_stream = await trio.open_tcp_stream(
@@ -62,8 +63,8 @@ async def open_ssl_over_tcp_stream(
happy_eyeballs_delay=happy_eyeballs_delay,
)
if ssl_context is None:
- ssl_context = trio.ssl.create_default_context()
- return trio.ssl.SSLStream(
+ ssl_context = ssl.create_default_context()
+ return trio.SSLStream(
tcp_stream,
ssl_context,
server_hostname=host,
@@ -82,15 +83,15 @@ async def open_ssl_over_tcp_listeners(
connections.
host (str, bytes, or None): The address to bind to; use ``None`` to bind
to the wildcard address. See :func:`open_tcp_listeners`.
- https_compatible (bool): See :class:`~trio.ssl.SSLStream` for details.
- backlog (int or None): See :class:`~trio.ssl.SSLStream` for details.
+ https_compatible (bool): See :class:`~trio.SSLStream` for details.
+ backlog (int or None): See :class:`~trio.SSLStream` for details.
"""
tcp_listeners = await trio.open_tcp_listeners(
port, host=host, backlog=backlog
)
ssl_listeners = [
- trio.ssl.SSLListener(
+ trio.SSLListener(
tcp_listener,
ssl_context,
https_compatible=https_compatible,
@@ -144,9 +145,9 @@ async def serve_ssl_over_tcp(
:func:`open_tcp_listeners`.
https_compatible (bool): Set this to True if you want to use
- "HTTPS-style" TLS. See :class:`~trio.ssl.SSLStream` for details.
+ "HTTPS-style" TLS. See :class:`~trio.SSLStream` for details.
- backlog (int or None): See :class:`~trio.ssl.SSLStream` for details.
+ backlog (int or None): See :class:`~trio.SSLStream` for details.
handler_nursery: The nursery to start handlers in, or None to use an
internal nursery. Passed to :func:`serve_listeners`.
diff --git a/trio/_ssl.py b/trio/_ssl.py
index a8cdcb1983..2a3204bd3a 100644
--- a/trio/_ssl.py
+++ b/trio/_ssl.py
@@ -221,8 +221,7 @@ class SSLStream(Stream):
ssl_context (~ssl.SSLContext): The :class:`~ssl.SSLContext` used for
this connection. Required. Usually created by calling
- :func:`trio.ssl.create_default_context()
- `.
+ :func:`ssl.create_default_context`.
server_hostname (str or None): The name of the server being connected
to. Used for `SNI
@@ -294,7 +293,7 @@ class SSLStream(Stream):
:meth:`~ssl.SSLSocket.cipher` or
:meth:`~ssl.SSLSocket.selected_alpn_protocol`. If you call them before the
handshake, when they can't possibly return useful data, then
- :class:`ssl.SSLObject` returns None, but :class:`trio.ssl.SSLStream`
+ :class:`ssl.SSLObject` returns None, but :class:`trio.SSLStream`
raises :exc:`NeedHandshakeError`.
This also means that if you register a SNI callback using
diff --git a/trio/_subprocess.py b/trio/_subprocess.py
index 7259228189..41e93dcfe7 100644
--- a/trio/_subprocess.py
+++ b/trio/_subprocess.py
@@ -111,7 +111,7 @@ def __init__(
):
if options.get(key):
raise TypeError(
- "trio.subprocess.Process only supports communicating over "
+ "trio.Process only supports communicating over "
"unbuffered byte streams; the '{}' option is not supported"
.format(key)
)
diff --git a/trio/_sync.py b/trio/_sync.py
index ab475b9471..fc6b76e928 100644
--- a/trio/_sync.py
+++ b/trio/_sync.py
@@ -617,7 +617,7 @@ class StrictFIFOLock(Lock):
lock in strict first-come-first-served order.
An example of when this is useful is if you're implementing something like
- :class:`trio.ssl.SSLStream` or an HTTP/2 server using `h2
+ :class:`trio.SSLStream` or an HTTP/2 server using `h2
`__, where you have multiple concurrent
tasks that are interacting with a shared state machine, and at
unpredictable moments the state machine requests that a chunk of data be
diff --git a/trio/tests/test_highlevel_ssl_helpers.py b/trio/tests/test_highlevel_ssl_helpers.py
index 41cdb2dc25..31d69ab77d 100644
--- a/trio/tests/test_highlevel_ssl_helpers.py
+++ b/trio/tests/test_highlevel_ssl_helpers.py
@@ -77,7 +77,7 @@ async def test_open_ssl_over_tcp_stream_and_everything_else():
80,
ssl_context=CLIENT_CTX,
)
- assert isinstance(stream, trio.ssl.SSLStream)
+ assert isinstance(stream, trio.SSLStream)
assert stream.server_hostname == "trio-test-1.example.org"
await stream.send_all(b"x")
assert await stream.receive_some(1) == b"x"
@@ -104,7 +104,7 @@ async def test_open_ssl_over_tcp_listeners():
0, SERVER_CTX, host="127.0.0.1"
)
async with listener:
- assert isinstance(listener, trio.ssl.SSLListener)
+ assert isinstance(listener, trio.SSLListener)
tl = listener.transport_listener
assert isinstance(tl, trio.SocketListener)
assert tl.socket.getsockname()[0] == "127.0.0.1"
diff --git a/trio/tests/test_ssl.py b/trio/tests/test_ssl.py
index e193691510..55ac8fea36 100644
--- a/trio/tests/test_ssl.py
+++ b/trio/tests/test_ssl.py
@@ -2,7 +2,7 @@
import threading
import socket as stdlib_socket
-import ssl as stdlib_ssl
+import ssl
from contextlib import contextmanager
from functools import partial
@@ -16,8 +16,8 @@
from .._highlevel_generic import aclose_forcefully
from .._core import ClosedResourceError, BrokenResourceError
from .._highlevel_open_tcp_stream import open_tcp_stream
-from .. import ssl as tssl
from .. import socket as tsocket
+from .._ssl import SSLStream, SSLListener, NeedHandshakeError
from .._util import ConflictDetector
from .._core.tests.tutil import slow
@@ -51,10 +51,10 @@
TRIO_TEST_CA = trustme.CA()
TRIO_TEST_1_CERT = TRIO_TEST_CA.issue_server_cert("trio-test-1.example.org")
-SERVER_CTX = stdlib_ssl.create_default_context(stdlib_ssl.Purpose.CLIENT_AUTH)
+SERVER_CTX = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
TRIO_TEST_1_CERT.configure_cert(SERVER_CTX)
-CLIENT_CTX = stdlib_ssl.create_default_context()
+CLIENT_CTX = ssl.create_default_context()
TRIO_TEST_CA.configure_trust(CLIENT_CTX)
@@ -75,7 +75,7 @@ def ssl_echo_serve_sync(sock, *, expect_fail=False):
# Under unclear conditions, CPython sometimes raises
# SSLWantWriteError here. This is a bug (bpo-32219), but it's
# not our bug, so ignore it.
- exceptions += (stdlib_ssl.SSLWantWriteError,)
+ exceptions += (ssl.SSLWantWriteError,)
try:
wrapped.unwrap()
except exceptions:
@@ -119,7 +119,7 @@ async def ssl_echo_server_raw(**kwargs):
async def ssl_echo_server(**kwargs):
async with ssl_echo_server_raw(**kwargs) as sock:
await yield_(
- tssl.SSLStream(
+ SSLStream(
sock, CLIENT_CTX, server_hostname="trio-test-1.example.org"
)
)
@@ -303,7 +303,7 @@ async def test_PyOpenSSLEchoStream_gives_resource_busy_errors():
@contextmanager
def virtual_ssl_echo_server(**kwargs):
fakesock = PyOpenSSLEchoStream(**kwargs)
- yield tssl.SSLStream(
+ yield SSLStream(
fakesock, CLIENT_CTX, server_hostname="trio-test-1.example.org"
)
@@ -311,13 +311,13 @@ def virtual_ssl_echo_server(**kwargs):
def ssl_wrap_pair(
client_transport, server_transport, *, client_kwargs={}, server_kwargs={}
):
- client_ssl = tssl.SSLStream(
+ client_ssl = SSLStream(
client_transport,
CLIENT_CTX,
server_hostname="trio-test-1.example.org",
**client_kwargs
)
- server_ssl = tssl.SSLStream(
+ server_ssl = SSLStream(
server_transport, SERVER_CTX, server_side=True, **server_kwargs
)
return client_ssl, server_ssl
@@ -333,18 +333,6 @@ def ssl_lockstep_stream_pair(**kwargs):
return ssl_wrap_pair(client_transport, server_transport, **kwargs)
-def test_exports():
- # Just a quick check to make sure _reexport isn't totally broken
- assert hasattr(tssl, "SSLError")
- assert "SSLError" in tssl.__dict__.keys()
-
- assert hasattr(tssl, "Purpose")
- assert "Purpose" in tssl.__dict__.keys()
-
- # Intentionally omitted
- assert not hasattr(tssl, "SSLContext")
-
-
# Simple smoke test for handshake/send/receive/shutdown talking to a
# synchronous server, plus make sure that we do the bare minimum of
# certificate checking (even though this is really Python's responsibility)
@@ -358,31 +346,31 @@ async def test_ssl_client_basics():
# Didn't configure the CA file, should fail
async with ssl_echo_server_raw(expect_fail=True) as sock:
- client_ctx = stdlib_ssl.create_default_context()
- s = tssl.SSLStream(
+ client_ctx = ssl.create_default_context()
+ s = SSLStream(
sock, client_ctx, server_hostname="trio-test-1.example.org"
)
assert not s.server_side
with pytest.raises(BrokenResourceError) as excinfo:
await s.send_all(b"x")
- assert isinstance(excinfo.value.__cause__, tssl.SSLError)
+ assert isinstance(excinfo.value.__cause__, ssl.SSLError)
# Trusted CA, but wrong host name
async with ssl_echo_server_raw(expect_fail=True) as sock:
- s = tssl.SSLStream(
+ s = SSLStream(
sock, CLIENT_CTX, server_hostname="trio-test-2.example.org"
)
assert not s.server_side
with pytest.raises(BrokenResourceError) as excinfo:
await s.send_all(b"x")
- assert isinstance(excinfo.value.__cause__, tssl.CertificateError)
+ assert isinstance(excinfo.value.__cause__, ssl.CertificateError)
async def test_ssl_server_basics():
a, b = stdlib_socket.socketpair()
with a, b:
server_sock = tsocket.from_stdlib_socket(b)
- server_transport = tssl.SSLStream(
+ server_transport = SSLStream(
SocketStream(server_sock), SERVER_CTX, server_side=True
)
assert server_transport.server_side
@@ -411,8 +399,8 @@ def client():
async def test_attributes():
async with ssl_echo_server_raw(expect_fail=True) as sock:
good_ctx = CLIENT_CTX
- bad_ctx = stdlib_ssl.create_default_context()
- s = tssl.SSLStream(
+ bad_ctx = ssl.create_default_context()
+ s = SSLStream(
sock, good_ctx, server_hostname="trio-test-1.example.org"
)
@@ -444,7 +432,7 @@ async def test_attributes():
assert s.context is bad_ctx
with pytest.raises(BrokenResourceError) as excinfo:
await s.do_handshake()
- assert isinstance(excinfo.value.__cause__, tssl.SSLError)
+ assert isinstance(excinfo.value.__cause__, ssl.SSLError)
# Note: this test fails horribly if we force TLS 1.2 and trigger a
@@ -699,8 +687,8 @@ class NotAStream:
async def wait_send_all_might_not_block(self):
record.append("ok")
- ctx = stdlib_ssl.create_default_context()
- s = tssl.SSLStream(NotAStream(), ctx, server_hostname="x")
+ ctx = ssl.create_default_context()
+ s = SSLStream(NotAStream(), ctx, server_hostname="x")
await s.wait_send_all_might_not_block()
assert record == ["ok"]
@@ -928,15 +916,15 @@ def close_hook():
async def test_ssl_over_ssl():
client_0, server_0 = memory_stream_pair()
- client_1 = tssl.SSLStream(
+ client_1 = SSLStream(
client_0, CLIENT_CTX, server_hostname="trio-test-1.example.org"
)
- server_1 = tssl.SSLStream(server_0, SERVER_CTX, server_side=True)
+ server_1 = SSLStream(server_0, SERVER_CTX, server_side=True)
- client_2 = tssl.SSLStream(
+ client_2 = SSLStream(
client_1, CLIENT_CTX, server_hostname="trio-test-1.example.org"
)
- server_2 = tssl.SSLStream(server_1, SERVER_CTX, server_side=True)
+ server_2 = SSLStream(server_1, SERVER_CTX, server_side=True)
async def client():
await client_2.send_all(b"hi")
@@ -994,8 +982,8 @@ async def test_ssl_handshake_failure_during_aclose():
# the underlying transport.
async with ssl_echo_server_raw(expect_fail=True) as sock:
# Don't configure trust correctly
- client_ctx = stdlib_ssl.create_default_context()
- s = tssl.SSLStream(
+ client_ctx = ssl.create_default_context()
+ s = SSLStream(
sock, client_ctx, server_hostname="trio-test-1.example.org"
)
# It's a little unclear here whether aclose should swallow the error
@@ -1048,7 +1036,7 @@ async def test_ssl_https_compatibility_disagreement():
async def receive_and_expect_error():
with pytest.raises(BrokenResourceError) as excinfo:
await server.receive_some(10)
- assert isinstance(excinfo.value.__cause__, tssl.SSLEOFError)
+ assert isinstance(excinfo.value.__cause__, ssl.SSLEOFError)
async with _core.open_nursery() as nursery:
nursery.start_soon(client.aclose)
@@ -1112,10 +1100,10 @@ async def client_side(cancel_scope):
async def test_selected_alpn_protocol_before_handshake():
client, server = ssl_memory_stream_pair()
- with pytest.raises(tssl.NeedHandshakeError):
+ with pytest.raises(NeedHandshakeError):
client.selected_alpn_protocol()
- with pytest.raises(tssl.NeedHandshakeError):
+ with pytest.raises(NeedHandshakeError):
server.selected_alpn_protocol()
@@ -1138,10 +1126,10 @@ async def test_selected_alpn_protocol_when_not_set():
async def test_selected_npn_protocol_before_handshake():
client, server = ssl_memory_stream_pair()
- with pytest.raises(tssl.NeedHandshakeError):
+ with pytest.raises(NeedHandshakeError):
client.selected_npn_protocol()
- with pytest.raises(tssl.NeedHandshakeError):
+ with pytest.raises(NeedHandshakeError):
server.selected_npn_protocol()
@@ -1164,10 +1152,10 @@ async def test_selected_npn_protocol_when_not_set():
async def test_get_channel_binding_before_handshake():
client, server = ssl_memory_stream_pair()
- with pytest.raises(tssl.NeedHandshakeError):
+ with pytest.raises(NeedHandshakeError):
client.get_channel_binding()
- with pytest.raises(tssl.NeedHandshakeError):
+ with pytest.raises(NeedHandshakeError):
server.get_channel_binding()
@@ -1207,10 +1195,10 @@ async def setup(**kwargs):
await listen_sock.bind(("127.0.0.1", 0))
listen_sock.listen(1)
socket_listener = SocketListener(listen_sock)
- ssl_listener = tssl.SSLListener(socket_listener, SERVER_CTX, **kwargs)
+ ssl_listener = SSLListener(socket_listener, SERVER_CTX, **kwargs)
transport_client = await open_tcp_stream(*listen_sock.getsockname())
- ssl_client = tssl.SSLStream(
+ ssl_client = SSLStream(
transport_client,
CLIENT_CTX,
server_hostname="trio-test-1.example.org"
diff --git a/trio/tests/test_subprocess.py b/trio/tests/test_subprocess.py
index e0bd0857ed..9a5880336c 100644
--- a/trio/tests/test_subprocess.py
+++ b/trio/tests/test_subprocess.py
@@ -2,11 +2,12 @@
import os
import random
import signal
+import subprocess
import sys
import pytest
from .. import (
- _core, move_on_after, fail_after, sleep, sleep_forever, subprocess
+ _core, move_on_after, fail_after, sleep, sleep_forever, Process
)
from .._core.tests.tutil import slow
from ..testing import wait_all_tasks_blocked
@@ -39,14 +40,14 @@ def got_signal(proc, sig):
async def test_basic():
- async with subprocess.Process(EXIT_TRUE) as proc:
+ async with Process(EXIT_TRUE) as proc:
assert proc.returncode is None
assert proc.returncode == 0
async def test_kill_when_context_cancelled():
with move_on_after(0) as scope:
- async with subprocess.Process(SLEEP(10)) as proc:
+ async with Process(SLEEP(10)) as proc:
assert proc.poll() is None
# Process context entry is synchronous, so this is the
# only checkpoint:
@@ -63,7 +64,7 @@ async def test_kill_when_context_cancelled():
async def test_pipes():
- async with subprocess.Process(
+ async with Process(
COPY_STDIN_TO_STDOUT_AND_BACKWARD_TO_STDERR,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
@@ -107,7 +108,7 @@ async def test_interactive():
# out: EOF
# err: EOF
- async with subprocess.Process(
+ async with Process(
python(
"idx = 0\n"
"while True:\n"
@@ -166,7 +167,7 @@ async def drain_one(stream, count, digit):
async def test_stderr_stdout():
- async with subprocess.Process(
+ async with Process(
COPY_STDIN_TO_STDOUT_AND_BACKWARD_TO_STDERR,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
@@ -188,7 +189,7 @@ async def test_stderr_stdout():
# this one hits the branch where stderr=STDOUT but stdout
# is not redirected
- async with subprocess.Process(
+ async with Process(
CAT, stdin=subprocess.PIPE, stderr=subprocess.STDOUT
) as proc:
assert proc.stdout is None
@@ -200,7 +201,7 @@ async def test_stderr_stdout():
try:
r, w = os.pipe()
- async with subprocess.Process(
+ async with Process(
COPY_STDIN_TO_STDOUT_AND_BACKWARD_TO_STDERR,
stdin=subprocess.PIPE,
stdout=w,
@@ -220,7 +221,7 @@ async def test_stderr_stdout():
async def test_errors():
with pytest.raises(TypeError) as excinfo:
- subprocess.Process(["ls"], encoding="utf-8")
+ Process(["ls"], encoding="utf-8")
assert "unbuffered byte streams" in str(excinfo.value)
assert "the 'encoding' option is not supported" in str(excinfo.value)
@@ -228,7 +229,7 @@ async def test_errors():
async def test_signals():
async def test_one_signal(send_it, signum):
with move_on_after(1.0) as scope:
- async with subprocess.Process(SLEEP(3600)) as proc:
+ async with Process(SLEEP(3600)) as proc:
send_it(proc)
assert not scope.cancelled_caught
if posix:
@@ -236,8 +237,8 @@ async def test_one_signal(send_it, signum):
else:
assert proc.returncode != 0
- await test_one_signal(subprocess.Process.kill, SIGKILL)
- await test_one_signal(subprocess.Process.terminate, SIGTERM)
+ await test_one_signal(Process.kill, SIGKILL)
+ await test_one_signal(Process.terminate, SIGTERM)
if posix:
await test_one_signal(lambda proc: proc.send_signal(SIGINT), SIGINT)
@@ -249,7 +250,7 @@ async def test_wait_reapable_fails():
# With SIGCHLD disabled, the wait() syscall will wait for the
# process to exit but then fail with ECHILD. Make sure we
# support this case as the stdlib subprocess module does.
- async with subprocess.Process(SLEEP(3600)) as proc:
+ async with Process(SLEEP(3600)) as proc:
async with _core.open_nursery() as nursery:
nursery.start_soon(proc.wait)
await wait_all_tasks_blocked()
@@ -269,10 +270,9 @@ def test_waitid_eintr():
if not wait_child_exiting.__module__.endswith("waitid"):
pytest.skip("waitid only")
from .._subprocess_platform.waitid import sync_wait_reapable
- import subprocess as stdlib_subprocess
got_alarm = False
- sleeper = stdlib_subprocess.Popen(["sleep", "3600"])
+ sleeper = subprocess.Popen(["sleep", "3600"])
def on_alarm(sig, frame):
nonlocal got_alarm
@@ -291,13 +291,3 @@ def on_alarm(sig, frame):
sleeper.kill()
sleeper.wait()
signal.signal(signal.SIGALRM, old_sigalrm)
-
-
-def test_all_constants_reexported():
- trio_subprocess_exports = set(dir(subprocess))
- import subprocess as stdlib_subprocess
-
- for name in dir(stdlib_subprocess):
- if name.isupper() and name[0] != "_":
- stdlib_constant = name
- assert stdlib_constant in trio_subprocess_exports
diff --git a/trio/tests/test_util.py b/trio/tests/test_util.py
index 06bf86b66b..87475bbaad 100644
--- a/trio/tests/test_util.py
+++ b/trio/tests/test_util.py
@@ -70,14 +70,13 @@ def test_module_metadata_is_fixed_up():
import trio
assert trio.Cancelled.__module__ == "trio"
assert trio.open_cancel_scope.__module__ == "trio"
- assert trio.ssl.SSLStream.__module__ == "trio.ssl"
assert trio.abc.Stream.__module__ == "trio.abc"
assert trio.hazmat.wait_task_rescheduled.__module__ == "trio.hazmat"
import trio.testing
assert trio.testing.trio_test.__module__ == "trio.testing"
# Also check methods
- assert trio.ssl.SSLStream.__init__.__module__ == "trio.ssl"
+ assert trio.hazmat.ParkingLot.__init__.__module__ == "trio.hazmat"
assert trio.abc.Stream.send_all.__module__ == "trio.abc"