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

Simplify sockets #670

Merged
merged 51 commits into from
Sep 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
e404d40
switched to dynamic importing
jmfrank63 Sep 16, 2018
3fcd475
Added AF_APPLETALK manually to see the effect
jmfrank63 Sep 16, 2018
711e7b4
Removed AF_APPLETALK again as tests failed
jmfrank63 Sep 16, 2018
8ea86ab
imported _socket directly as socket
jmfrank63 Sep 16, 2018
268cc33
Added print for better understanding (temporarly)
jmfrank63 Sep 16, 2018
b9ee0d7
Reverted to import of socket
jmfrank63 Sep 16, 2018
7bbb52b
Dynamic updates are simply not picked up by static analysis tools
jmfrank63 Sep 16, 2018
1b50f2a
trio/socket.py : Moved to static import of names and emoved __all__
jmfrank63 Sep 19, 2018
fc666c2
Fixed import error of some constants not found on some platforms
jmfrank63 Sep 19, 2018
9217753
Finding the offending symbols 1
jmfrank63 Sep 19, 2018
1f01599
Added new name IPPROTO_SCTP to import
jmfrank63 Sep 19, 2018
b764a97
Moved new name IPPROTO_SCTP to try except block
jmfrank63 Sep 19, 2018
7118f9b
Moved new name TCP_KEEPINTVL to try except block
jmfrank63 Sep 19, 2018
6c93661
Moved new name TCP_KEEPCNT to try except block
jmfrank63 Sep 19, 2018
37afde1
Moved new name TCP_FASTOPEN to try except block
jmfrank63 Sep 19, 2018
1e438e3
Moved new name AF_LINK to try except block
jmfrank63 Sep 19, 2018
305db2d
Moved new name sethostname to try except block
jmfrank63 Sep 19, 2018
f7fe91b
Moved new name PF_SYSTEM to try except block
jmfrank63 Sep 19, 2018
fc30951
Moved new name AF_SYSTEM to try except block
jmfrank63 Sep 19, 2018
97bc5a8
Moved new name SO_USELOOPBACK to try except block
jmfrank63 Sep 19, 2018
ecdcdf2
Put all namespaces in a try except block and pull out the once that a…
jmfrank63 Sep 19, 2018
638ab9a
Pull out SOCK_STREAM
jmfrank63 Sep 19, 2018
94042ce
Fixed typo in IPPROTO_IPV6 name
jmfrank63 Sep 19, 2018
583570d
Fixed missing import on non win platforms of IPPROTO_IPV6
jmfrank63 Sep 19, 2018
6ad0d73
Fixed formatting and missing IPPROTO_SCTP on python 3.8
jmfrank63 Sep 19, 2018
c7d1391
Reverted to star import
jmfrank63 Sep 19, 2018
7fa93e8
Removed try except wrap on SO_REUSEADDR
jmfrank63 Sep 19, 2018
0c27ae2
Fixed yapf formatting
jmfrank63 Sep 19, 2018
f8ce585
moved star import to socket.py
jmfrank63 Sep 19, 2018
762cd8d
preparation for dynamic import
jmfrank63 Sep 19, 2018
bc53484
Added minimal set of socket constants
jmfrank63 Sep 20, 2018
ef2309b
static import of functions, dynamic of constants
jmfrank63 Sep 20, 2018
ca86946
static import of functions, dynamic of constants, fix test failure fo…
jmfrank63 Sep 21, 2018
8f066c1
static import of functions, dynamic of constants, fix test failure fo…
jmfrank63 Sep 21, 2018
0e690f8
static import of functions, dynamic of constants, fix test failure fo…
jmfrank63 Sep 21, 2018
66f5330
fixed typo
jmfrank63 Sep 21, 2018
9ac6d34
Moved upper case names import to socket.py and undid prior comment
jmfrank63 Sep 23, 2018
bd9a952
Merge branch 'master' into simplify_sockets
jmfrank63 Sep 24, 2018
7f142f9
added newsfragment
jmfrank63 Sep 25, 2018
39a84f7
Increased pickleshare version to 0.7.5
jmfrank63 Sep 25, 2018
2453587
Dummy to trigger CI again
jmfrank63 Sep 26, 2018
f1d45a7
10 minutes too early try again now
jmfrank63 Sep 26, 2018
2ce378d
Do not import TCP_NOTSENT_LOWAT on windows
jmfrank63 Sep 26, 2018
caead79
unnecessary code removed and definitions moved to from _socket.py to …
jmfrank63 Sep 26, 2018
ad2e09f
Merge branch 'master' into simplify_sockets
jmfrank63 Sep 27, 2018
c43ced7
removed pragma comment
jmfrank63 Sep 27, 2018
70c9fd9
Merge branch 'master' into simplify_sockets
jmfrank63 Sep 28, 2018
3b7cb99
New yapf version should fix formatting issues
jmfrank63 Sep 28, 2018
9b8dc48
Manually adjusted trio/_signals.py formatting
jmfrank63 Sep 28, 2018
4cf0c77
Merged newsfragments under a single file
jmfrank63 Sep 28, 2018
59a899d
added backticks to module names
jmfrank63 Sep 28, 2018
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
2 changes: 1 addition & 1 deletion newsfragments/542.feature.rst
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* Reworked :mod:`trio` namespace construction, making it more understandable by static analysis tools. This should improve tab completion in editors, reduce false positives from pylint, and is a first step towards providing type hints.
Reworked :mod:`trio`, :mod:`trio.testing`, and :mod:`trio.socket` namespace construction, making them more understandable by static analysis tools. This should improve tab completion in editors, reduce false positives from pylint, and is a first step towards providing type hints.
117 changes: 25 additions & 92 deletions trio/_socket.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os as _os
import socket as _stdlib_socket
import sys as _sys
import socket as _stdlib_socket
from functools import wraps as _wraps

import idna as _idna
Expand All @@ -9,22 +9,6 @@
from ._threads import run_sync_in_worker_thread
from ._util import fspath

__all__ = []

################################################################
# misc utilities
################################################################


def _reexport(name):
globals()[name] = getattr(_stdlib_socket, name)
__all__.append(name)


def _add_to_all(obj):
__all__.append(obj.__name__)
return obj


# Usage:
#
Expand Down Expand Up @@ -62,54 +46,13 @@ async def __aexit__(self, etype, value, tb):
# CONSTANTS
################################################################

# Hopefully will show up in 3.7:
# https://github.com/python/cpython/pull/477
if not hasattr(_stdlib_socket, "TCP_NOTSENT_LOWAT"): # pragma: no branch
if _sys.platform == "darwin":
TCP_NOTSENT_LOWAT = 0x201
__all__.append("TCP_NOTSENT_LOWAT")
elif _sys.platform == "linux":
TCP_NOTSENT_LOWAT = 25
__all__.append("TCP_NOTSENT_LOWAT")

for _name in _stdlib_socket.__dict__.keys():
if _name == _name.upper():
_reexport(_name)

if _sys.platform == "win32":
# See https://github.com/python-trio/trio/issues/39
# (you can still get it from stdlib socket, of course, if you want it)
globals().pop("SO_REUSEADDR", None)
__all__.remove("SO_REUSEADDR")

try:
from socket import IPPROTO_IPV6
except ImportError:
# As of at least 3.6, python on Windows is missing IPPROTO_IPV6
# https://bugs.python.org/issue29515
if not hasattr(_stdlib_socket, "IPPROTO_IPV6"): # pragma: no branch
if _sys.platform == "win32":
IPPROTO_IPV6 = 41
__all__.append("IPPROTO_IPV6")

################################################################
# Simple re-exports
################################################################

for _name in [
"gaierror",
"herror",
"gethostname",
"ntohs",
"htonl",
"htons",
"inet_aton",
"inet_ntoa",
"inet_pton",
"inet_ntop",
"sethostname",
"if_nameindex",
"if_nametoindex",
"if_indextoname",
]:
if hasattr(_stdlib_socket, _name):
_reexport(_name)

################################################################
# Overrides
Expand All @@ -119,7 +62,6 @@ async def __aexit__(self, etype, value, tb):
_socket_factory = _core.RunVar("socket_factory")


@_add_to_all
def set_custom_hostname_resolver(hostname_resolver):
"""Set a custom hostname resolver.

Expand Down Expand Up @@ -152,7 +94,6 @@ def set_custom_hostname_resolver(hostname_resolver):
return old


@_add_to_all
def set_custom_socket_factory(socket_factory):
"""Set a custom socket object factory.

Expand Down Expand Up @@ -187,7 +128,6 @@ def set_custom_socket_factory(socket_factory):
_NUMERIC_ONLY = _stdlib_socket.AI_NUMERICHOST | _stdlib_socket.AI_NUMERICSERV


@_add_to_all
async def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
"""Look up a numeric address given a name.

Expand Down Expand Up @@ -249,7 +189,6 @@ def numeric_only_failure(exc):
)


@_add_to_all
async def getnameinfo(sockaddr, flags):
"""Look up a name given a numeric address.

Expand All @@ -269,7 +208,6 @@ async def getnameinfo(sockaddr, flags):
)


@_add_to_all
async def getprotobyname(name):
"""Look up a protocol number by name. (Rarely used.)

Expand All @@ -289,7 +227,6 @@ async def getprotobyname(name):
################################################################


@_add_to_all
def from_stdlib_socket(sock):
"""Convert a standard library :func:`socket.socket` object into a trio
socket object.
Expand All @@ -299,7 +236,6 @@ def from_stdlib_socket(sock):


@_wraps(_stdlib_socket.fromfd, assigned=(), updated=())
@_add_to_all
def fromfd(*args, **kwargs):
"""Like :func:`socket.fromfd`, but returns a trio socket object.

Expand All @@ -310,13 +246,11 @@ def fromfd(*args, **kwargs):
if hasattr(_stdlib_socket, "fromshare"):

@_wraps(_stdlib_socket.fromshare, assigned=(), updated=())
@_add_to_all
def fromshare(*args, **kwargs):
return from_stdlib_socket(_stdlib_socket.fromshare(*args, **kwargs))


@_wraps(_stdlib_socket.socketpair, assigned=(), updated=())
@_add_to_all
def socketpair(*args, **kwargs):
"""Like :func:`socket.socketpair`, but returns a pair of trio socket
objects.
Expand All @@ -327,7 +261,6 @@ def socketpair(*args, **kwargs):


@_wraps(_stdlib_socket.socket, assigned=(), updated=())
@_add_to_all
def socket(
family=_stdlib_socket.AF_INET,
type=_stdlib_socket.SOCK_STREAM,
Expand Down Expand Up @@ -374,7 +307,26 @@ def real_socket_type(type_num):
return type_num & _SOCK_TYPE_MASK


@_add_to_all
def _make_simple_sock_method_wrapper(methname, wait_fn, maybe_avail=False):
fn = getattr(_stdlib_socket.socket, methname)

@_wraps(fn, assigned=("__name__",), updated=())
async def wrapper(self, *args, **kwargs):
return await self._nonblocking_helper(fn, args, kwargs, wait_fn)

wrapper.__doc__ = (
"""Like :meth:`socket.socket.{}`, but async.

""".format(methname)
)
if maybe_avail:
wrapper.__doc__ += (
"Only available on platforms where :meth:`socket.socket.{}` "
"is available.".format(methname)
)
return wrapper


class SocketType:
def __init__(self):
raise TypeError(
Expand Down Expand Up @@ -603,25 +555,6 @@ async def _nonblocking_helper(self, fn, args, kwargs, wait_fn):
except BlockingIOError:
pass

def _make_simple_sock_method_wrapper(methname, wait_fn, maybe_avail=False):
fn = getattr(_stdlib_socket.socket, methname)

@_wraps(fn, assigned=("__name__",), updated=())
async def wrapper(self, *args, **kwargs):
return await self._nonblocking_helper(fn, args, kwargs, wait_fn)

wrapper.__doc__ = (
"""Like :meth:`socket.socket.{}`, but async.

""".format(methname)
)
if maybe_avail:
wrapper.__doc__ += (
"Only available on platforms where :meth:`socket.socket.{}` "
"is available.".format(methname)
)
return wrapper

################################################################
# accept
################################################################
Expand Down
71 changes: 69 additions & 2 deletions trio/socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,72 @@
# temporaries, imports, etc. when implementing the module. So we put the
# implementation in an underscored module, and then re-export the public parts
# here.
from ._socket import *
from ._socket import __all__
# We still have some underscore names though but only a few.

from . import _socket
import sys as _sys

# import the overwrites
from ._socket import (
fromfd, from_stdlib_socket, getprotobyname, socketpair, getnameinfo,
socket, getaddrinfo, set_custom_hostname_resolver,
set_custom_socket_factory, SocketType
)
pquentin marked this conversation as resolved.
Show resolved Hide resolved

# not always available so expose only if
try:
from ._socket import fromshare
except ImportError:
pass

# expose these functions to trio.socket
from socket import (
gaierror,
herror,
gethostname,
ntohs,
htonl,
htons,
inet_aton,
inet_ntoa,
inet_pton,
inet_ntop,
)

# not always available so expose only if
try:
from socket import (
sethostname, if_nameindex, if_nametoindex, if_indextoname
)
except ImportError:
pass

# expose all uppercase names from standardlib socket to trio.socket
import socket as _stdlib_socket

globals().update(
{
_name: getattr(_stdlib_socket, _name)
for _name in _stdlib_socket.__dict__ if _name.isupper()
}
)

if _sys.platform == 'win32':
# See https://github.com/python-trio/trio/issues/39
# Do not import for windows platform
# (you can still get it from stdlib socket, of course, if you want it)
del SO_REUSEADDR

# get names used by trio that we define on our own
from ._socket import IPPROTO_IPV6

# Not defined in all python versions and platforms but sometimes needed
try:
TCP_NOTSENT_LOWAT
except NameError:
# Hopefully will show up in 3.7:
# https://github.com/python/cpython/pull/477
if _sys.platform == "darwin":
TCP_NOTSENT_LOWAT = 0x201
elif _sys.platform == "linux":
TCP_NOTSENT_LOWAT = 25