Skip to content

Commit

Permalink
Merge pull request #316 from njsmith/issue-314
Browse files Browse the repository at this point in the history
Make our exports more visible to static analysis
  • Loading branch information
njsmith authored Sep 9, 2017
2 parents 8692bfc + ffdb562 commit 739c332
Show file tree
Hide file tree
Showing 17 changed files with 115 additions and 84 deletions.
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

0 comments on commit 739c332

Please sign in to comment.