Skip to content
This repository was archived by the owner on Nov 23, 2017. It is now read-only.

Fix create_unix_server to support Path-like objects (PEP 519) #462

Closed
wants to merge 1 commit into from
Closed
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
8 changes: 8 additions & 0 deletions asyncio/unix_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ def _sighandler_noop(signum, frame):
pass


try:
_fspath = os.fspath
except AttributeError:
# Python 3.5 or earlier
_fspath = lambda path: path

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe support pathlib.Path for Python 3.5 also?
It could be implemented by isinstance() check.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's a good idea, PEP 519 is 3.6 only.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the key point is that unless a library implementing a path-representing object restricts itself to 3.6 or newer, it could be useful in 3.5 code. But I wouldn't use isinstance() as that's too restrictive if you want to bother supporting __fspath__. All you really need to be good enough for a os.fspath() fall-back is:

def _fspath(path):
  if hasattr(path, '__fspath__'):
    return path.__class__.__fspath__(path)
  else:
    return path

os.fspath() does more checks to verify that only str and bytes are returned, but that's the gist of it. Otherwise just do what Yury did.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok



class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
"""Unix event loop.

Expand Down Expand Up @@ -256,6 +263,7 @@ def create_unix_server(self, protocol_factory, path=None, *,
raise ValueError(
'path and sock can not be specified at the same time')

path = _fspath(path)
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

# Check for abstract socket. `str` and `bytes` paths are supported.
Expand Down
10 changes: 10 additions & 0 deletions tests/test_unix_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import errno
import io
import os
import pathlib
import signal
import socket
import stat
Expand Down Expand Up @@ -251,6 +252,15 @@ def test_create_unix_server_existing_path_sock(self):
srv.close()
self.loop.run_until_complete(srv.wait_closed())

@unittest.skipUnless(hasattr(os, 'fspath'), 'no os.fspath')
def test_create_unix_server_pathlib(self):
with test_utils.unix_socket_path() as path:
path = pathlib.Path(path)
srv_coro = self.loop.create_unix_server(lambda: None, path)
srv = self.loop.run_until_complete(srv_coro)
srv.close()
self.loop.run_until_complete(srv.wait_closed())

def test_create_unix_server_existing_path_nonsock(self):
with tempfile.NamedTemporaryFile() as file:
coro = self.loop.create_unix_server(lambda: None, file.name)
Expand Down