Skip to content
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

Make our exports more visible to static analysis #316

Merged
merged 6 commits into from
Sep 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions docs/source/design.rst
Original file line number Diff line number Diff line change
Expand Up @@ -437,10 +437,9 @@ implementation of the core scheduling/cancellation/IO handling logic,
and then the other ``trio.*`` modules are implemented in terms of the
API it exposes. (If you want to see what this API looks like, then
``import trio; print(trio._core.__all__)``). Everything exported from
``trio._core`` is *also* exported as part of either the ``trio`` or
``trio.hazmat`` namespaces. (This is managed through the use of a
``@_hazmat`` decorator that marks which items in
``trio._core.__all__`` should go into ``trio.hazmat``.)
``trio._core`` is *also* exported as part of the ``trio``,
``trio.hazmat``, or ``trio.testing`` namespaces. (See their respective
``__init__.py`` files for details; there's a test to enforce this.)

Rationale: currently, trio is a new project in a novel part of the
design space, so we don't make any stability guarantees. But the goal
Expand Down
6 changes: 6 additions & 0 deletions docs/source/history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ task.parent_nursery

Fix ``sock.accept()`` for IPv6 sockets (https://github.com/python-trio/trio/issues/164)

PyCharm (and hopefully other IDEs) offer better completions for
the :mod:`trio` and :mod:`trio.hazmat` modules
https://github.com/python-trio/trio/issues/314


* ``trio.socket.SocketType`` will no longer be exposed publically in
0.3.0. Since it had no public constructor, the only thing you could
Expand All @@ -99,6 +103,8 @@ Fix ``sock.accept()`` for IPv6 sockets (https://github.com/python-trio/trio/issu

deprecate most of the task and nursery APIs

make our exports visible to PyCharm (314)

Renames from https://github.com/python-trio/trio/issues/157

Note that pypy needs 5.9+ to support deprecations properly
Expand Down
25 changes: 6 additions & 19 deletions trio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,20 @@
#
# trio/_core/... is the self-contained core library. It does various
# shenanigans to export a consistent "core API", but parts of the core API are
# too low-level to be recommended for regular use. These are marked by having
# a _hazmat=True attribute.
# too low-level to be recommended for regular use.
#
# trio/*.py define a set of more usable tools on top of this. They import from
# trio._core and from each other.
#
# This file pulls together the friendly public API, by re-exporting the more
# innocuous bits of the _core API + the the tools from trio/*.py. No-one
# imports it internally; it's only for public consumption. When re-exporting
# _core here, we check for the _hazmat=True attribute and shunt things into
# either our namespace or the hazmat namespace accordingly.

__all__ = []
# innocuous bits of the _core API + the higher-level tools from trio/*.py.

from ._version import __version__

from . import hazmat
__all__ = []

from . import _core
for _symbol in _core.__all__:
_value = getattr(_core, _symbol)
if getattr(_value, "_hazmat", False):
setattr(hazmat, _symbol, _value)
hazmat.__all__.append(_symbol)
else:
globals()[_symbol] = _value
__all__.append(_symbol)
del _symbol, _value
from ._toplevel_core_reexports import *
__all__ += _toplevel_core_reexports.__all__

from ._timeouts import *
__all__ += _timeouts.__all__
Expand Down Expand Up @@ -71,6 +57,7 @@
__all__ += _deprecate.__all__

# Imported by default
from . import hazmat
from . import socket
from . import abc
from . import ssl
Expand Down
13 changes: 1 addition & 12 deletions trio/_core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Need to be defined early so they can be imported:
# Needs to be defined early so it can be imported:
def _public(fn):
# Used to mark methods on _Runner and on IOManager implementations that
# should be wrapped as global context-sensitive functions (see the bottom
Expand All @@ -7,15 +7,6 @@ def _public(fn):
return fn


def _hazmat(fn):
# Everything exported by this module gets re-exported as either part of
# the trio.* namespace or else the trio.hazmat.* namespace. By default,
# thing go into trio.*. But functions marked with this decorator go into
# trio.hazmat.* instead. See trio/__init__.py for details.
fn._hazmat = True
return fn


__all__ = []

from ._exceptions import *
Expand Down Expand Up @@ -48,13 +39,11 @@ def _hazmat(fn):
if hasattr(_run, "wait_readable"):
import socket as _stdlib_socket

@_hazmat
async def wait_socket_readable(sock):
if type(sock) != _stdlib_socket.socket:
raise TypeError("need a socket")
await wait_readable(sock)

@_hazmat
async def wait_socket_writable(sock):
if type(sock) != _stdlib_socket.socket:
raise TypeError("need a socket")
Expand Down
4 changes: 1 addition & 3 deletions trio/_core/_io_epoll.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import attr

from .. import _core
from . import _public, _hazmat
from . import _public


@attr.s(frozen=True)
Expand Down Expand Up @@ -116,11 +116,9 @@ def abort(_):
await _core.wait_task_rescheduled(abort)

@_public
@_hazmat
async def wait_readable(self, fd):
await self._epoll_wait(fd, "read_task")

@_public
@_hazmat
async def wait_writable(self, fd):
await self._epoll_wait(fd, "write_task")
7 changes: 1 addition & 6 deletions trio/_core/_io_kqueue.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import attr

from .. import _core
from . import _public, _hazmat
from . import _public


@attr.s(frozen=True)
Expand Down Expand Up @@ -72,12 +72,10 @@ def handle_io(self, timeout):
# be more ergonomic...

@_public
@_hazmat
def current_kqueue(self):
return self._kqueue

@_public
@_hazmat
@contextmanager
def monitor_kevent(self, ident, filter):
key = (ident, filter)
Expand All @@ -94,7 +92,6 @@ def monitor_kevent(self, ident, filter):
del self._registered[key]

@_public
@_hazmat
async def wait_kevent(self, ident, filter, abort_func):
key = (ident, filter)
if key in self._registered:
Expand Down Expand Up @@ -128,11 +125,9 @@ def abort(_):
await self.wait_kevent(fd, filter, abort)

@_public
@_hazmat
async def wait_readable(self, fd):
await self._wait_common(fd, select.KQ_FILTER_READ)

@_public
@_hazmat
async def wait_writable(self, fd):
await self._wait_common(fd, select.KQ_FILTER_WRITE)
9 changes: 1 addition & 8 deletions trio/_core/_io_windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import attr

from .. import _core
from . import _public, _hazmat
from . import _public
from ._wakeup_socketpair import WakeupSocketpair

from ._windows_cffi import (
Expand Down Expand Up @@ -293,19 +293,16 @@ def _iocp_thread_fn(self):
self._main_thread_waker.wakeup_thread_and_signal_safe()

@_public
@_hazmat
def current_iocp(self):
return int(ffi.cast("uintptr_t", self._iocp))

@_public
@_hazmat
def register_with_iocp(self, handle):
handle = _handle(obj)
# https://msdn.microsoft.com/en-us/library/windows/desktop/aa363862(v=vs.85).aspx
_check(kernel32.CreateIoCompletionPort(handle, self._iocp, 0, 0))

@_public
@_hazmat
async def wait_overlapped(self, handle, lpOverlapped):
handle = _handle(obj)
if isinstance(lpOverlapped, int):
Expand Down Expand Up @@ -337,7 +334,6 @@ def abort(raise_cancel_):
raise_winerror(lpOverlapped.Internal)

@_public
@_hazmat
@contextmanager
def monitor_completion_key(self):
key = next(self._completion_key_counter)
Expand Down Expand Up @@ -376,20 +372,17 @@ def abort(_):
await _core.wait_task_rescheduled(abort)

@_public
@_hazmat
async def wait_socket_readable(self, sock):
await self._wait_socket("read", sock)

@_public
@_hazmat
async def wait_socket_writable(self, sock):
await self._wait_socket("write", sock)

# This has cffi-isms in it and is untested... but it demonstrates the
# logic we'll want when we start actually using overlapped I/O.
#
# @_public
# @_hazmat
# async def perform_overlapped(self, handle, submit_fn):
# # submit_fn(lpOverlapped) submits some I/O
# # it may raise an OSError with ERROR_IO_PENDING
Expand Down
5 changes: 0 additions & 5 deletions trio/_core/_ki.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import attr
import async_generator

from . import _hazmat

__all__ = [
"enable_ki_protection",
"disable_ki_protection",
Expand Down Expand Up @@ -96,7 +94,6 @@ def ki_protection_enabled(frame):
return False


@_hazmat
def currently_ki_protected():
"""Check whether the calling code has :exc:`KeyboardInterrupt` protection
enabled.
Expand Down Expand Up @@ -172,11 +169,9 @@ def wrapper(*args, **kwargs):

enable_ki_protection = _ki_protection_decorator(True)
enable_ki_protection.__name__ = "enable_ki_protection"
_hazmat(enable_ki_protection)

disable_ki_protection = _ki_protection_decorator(False)
disable_ki_protection.__name__ = "disable_ki_protection"
_hazmat(disable_ki_protection)


@contextmanager
Expand Down
3 changes: 1 addition & 2 deletions trio/_core/_local.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Task- and Run-local storage

from . import _hazmat, _run
from . import _run

__all__ = ["TaskLocal", "RunLocal"]

Expand Down Expand Up @@ -110,7 +110,6 @@ async def main():
_locals_key = "task"


@_hazmat
class RunLocal(_LocalBase):
"""Run-local storage.

Expand Down
2 changes: 0 additions & 2 deletions trio/_core/_parking_lot.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@
from collections import OrderedDict

from .. import _core
from . import _hazmat

__all__ = ["ParkingLot"]

Expand All @@ -87,7 +86,6 @@ class _ParkingLotStatistics:
tasks_waiting = attr.ib()


@_hazmat
@attr.s(slots=True, cmp=False, hash=False)
class ParkingLot:
"""A fair wait queue with cancellation and requeueing.
Expand Down
5 changes: 0 additions & 5 deletions trio/_core/_result.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import abc
import attr

from . import _hazmat

__all__ = ["Result", "Value", "Error"]


@_hazmat
@attr.s(slots=True, frozen=True)
class Result(metaclass=abc.ABCMeta):
"""An abstract class representing the result of a Python computation.
Expand Down Expand Up @@ -84,7 +81,6 @@ async def asend(self, agen):
"""


@_hazmat
@attr.s(slots=True, frozen=True, repr=False)
class Value(Result):
"""Concrete :class:`Result` subclass representing a regular value.
Expand All @@ -107,7 +103,6 @@ async def asend(self, agen):
return await agen.asend(self.value)


@_hazmat
@attr.s(slots=True, frozen=True, repr=False)
class Error(Result):
"""Concrete :class:`Result` subclass representing a raised exception.
Expand Down
Loading