-
-
Notifications
You must be signed in to change notification settings - Fork 352
Unix client socket support. See: #279 #401
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
Conversation
Codecov Report
@@ Coverage Diff @@
## master #401 +/- ##
========================================
- Coverage 99.29% 99.2% -0.1%
========================================
Files 87 89 +2
Lines 10256 10330 +74
Branches 712 718 +6
========================================
+ Hits 10184 10248 +64
- Misses 56 63 +7
- Partials 16 19 +3
Continue to review full report at Codecov.
|
Hello, and thank you for the pull request! I'm not part of the team, but just trying to help here. You have formatting changes because trio currently uses yapf 0.19.0 but you followed the documentation and used the latest version, 0.20.1. It's not easy to notice: it turns out yapf 0.19.0 is happy with the changes made by yapf 0.20.1. Anyway, since google/yapf#484 is now fixed, it would make sense to upgrade to yapf 0.20.1, but maybe not as part of this pull request? Hope that helps! |
Pff, if you're going to go reviewing pull requests then you're part of the team :-). Check your inbox for an invite. @SunDwarf
Yeah, sorry about this – as @pquentin mentioned, we've had some trouble with yapf bugs recently and the contributor docs are a little out of sync there. I think we can leave it be in this case, given the weird details. (Specifically it looks like 0.20.1 has fixed the misformatting bugs we were seeing, and also fixed a bug where older versions of yapf were simply skipping over some I'll do a proper review in a second. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks pretty good! A few comments.
trio/_highlevel_open_unix_stream.py
Outdated
|
||
async def open_unix_socket(filename,): | ||
"""Opens a connection to the specified | ||
`Unix domain socket <https://en.wikipedia.org/wiki/Unix_domain_socket>`_. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird ReST nitpick: it's better to get in the habit of using a double-underscore for ReST links, like
`Unix domain socket <https://en.wikipedia.org/wiki/Unix_domain_socket>`__
Double-underscore gives you the regular link semantics that everyone expects. Single underscore is subtly different, and can cause problems in weird cases (e.g. if you have two links in the same document with the same link text but different link targets, then with single underscores that's an error, for some reason).
Not a big deal, but trivial to fix so probably worth fixing just for style consistency.
trio/_socket.py
Outdated
# unwrap path-likes | ||
if hasattr(address, "__fspath__"): | ||
return address.__fsp 10000 ath__() | ||
return address |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, excellent catch.
At first I was going to suggest using os.fspath
, but then I remembered that that's only added in 3.6. We could skip this check on 3.5, but... we probably want to support trio.Path
objects even on 3.5. And then I looked again at trio's async file I/O code, and we actually have a second copy of this os.fspath
emulation there.
Would you be up to refactoring this into a trio._util.fspath
helper? Ideally based on the sample code here? (It turns out that calling address.__fspath__()
directly is subtly wrong, because python's magic method lookup is weird.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also filed bpo-32562.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I'll update it when I get home today.
serv_sock.listen(1) | ||
|
||
# for some reason the server socket can accept the connection AFTER it has | ||
# been opened, so use that to test here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, that's the point of the listen(1)
:-). It means "allow at least 1 connection to accepted, and hold onto it in the kernel, before I call accept
".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I didn't know that. Been a long time since I've used raw sockets.
|
||
# for some reason the server socket can accept the connection AFTER it has | ||
# been opened, so use that to test here | ||
unix_socket = await open_unix_socket(name.__fspath__()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also test with passing the Path
object directly to open_unix_socket
? (On 3.5 you can use a trio.Path
to make sure it has an __fspath__
method.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do later today.
RuntimeError: If AF_UNIX sockets are not supported. | ||
""" | ||
if not has_unix: | ||
raise RuntimeError("Unix sockets are not supported on this platform") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, how to handle this is an interesting question.
One tradition says, unsupported operations should just be missing, so you can do hasattr(trio, "open_unix_stream")
to check for whether it's there. The other approach is to do this. On the one hand, the missing approach is probably more traditional in Python, and it's what we do for OS-specific operations in trio.hazmat
. OTOH, it might make it harder to get trio.__all__
set up correctly and in a way that doesn't confuse static analysis tools, and we might need to switch how we handle OS-specific operations anyway to support pluggable backends. Hmm.
I'm going to hit post on this review so you can see the other comments, while I think about this a little more :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't come to any real conclusions here, but given the problems that autocompleters have when some functions are only conditionally defined (#314), and that this way callers get a better error message than AttributeError: open_unix_stream
, I'm going to say let's leave this as is for now for now and we can revisit it later if we change our mind.
Changes requested have been made. There was a few places where the fspath util could be added, but I figured they were out of scope for the PR so I didn't touch them. |
The build is failing because yapf is cranky -- maybe we found a place where 0.19 and 0.20.1 disagree after all. If you could do a quick
Then it should get the test suite running again. |
No clue why the build failed there. The tests just seemed to not run? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the tests were acting weird because Travis had an outage yesterday -- it seems to be done now, so I restarted them.
A few small comments below, plus:
-
Can you add a newsfragment for this in
newsfragments/
? There's a README in that directory with instructions -
Can you add
open_unix_stream
to the docs? The stream docs are a bit disorganized right now, but a.. autofunction:: open_unix_stream
near the current docs foropen_tcp_stream
will at least make it findable :-)
# mktemp is marked as insecure, but that's okay, we don't want the file to | ||
# exist | ||
name = os.path.join(tempfile.gettempdir(), tempfile.mktemp()) | ||
await open_unix_socket(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe xfail
is supposed to mark tests that we want to pass, but that are currently failing -- like an executable bug report. If the goal is to test that this raises an exception, the best way to do that is
with pytest.assert_raises(OSError): # or whatever the appropriate type is
await open_unix_socket(name)
trio/_util.py
Outdated
|
||
|
||
if sys.version_info[0:2] >= (3, 6): | ||
fspath = os.fspath |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make this something like:
if hasattr(os, "fspath"):
fspath = os.fspath
It's generally a good habit to check directly for the thing we need instead of hard-coding version numbers, when we can. For example, it's possible PyPy will add os.fspath
before they finish implementing the rest of 3.6's new features.
trio/_util.py
Outdated
"not " + type(path).__name__) | ||
|
||
raise TypeError("expected str, bytes or os.PathLike object, not " | ||
+ path_type.__name__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unsurprisingly, codecov is complaining about missing coverage in this function, because we don't have tests for the error branches. It'd be good to fix this at some point just in case, but I'm not going to hold up merging just for that...
RuntimeError: If AF_UNIX sockets are not supported. | ||
""" | ||
if not has_unix: | ||
raise RuntimeError("Unix sockets are not supported on this platform") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't come to any real conclusions here, but given the problems that autocompleters have when some functions are only conditionally defined (#314), and that this way callers get a better error message than AttributeError: open_unix_stream
, I'm going to say let's leave this as is for now for now and we can revisit it later if we change our mind.
Meh, I started that review before you did the reformatting and it seems to have confused github a bit. Github is hiding some of my comments; please click "Show outdated" to see them, because they aren't actually outdated :-) |
Okay, that should be everything done. |
Thanks! Unfortunately you have a new yapf issue: https://travis-ci.org/python-trio/trio/jobs/33032 F5D3 0293 |
Looking good! I think the |
Done! I'll send your Github invite in a moment. |
A month later, I finally found the motivation to implement this.
Implementation was relatively simple; I reused SocketStream and wrote a very basic connector function (for client connections, I don't think there's any more that could be done).
Note:
socket.socket
to emulate a UDS server - not sure if that's the right thing to do.