Skip to content

Commit

Permalink
Merge branch 'master' into resolve-broadcast-hostname
Browse files Browse the repository at this point in the history
  • Loading branch information
fantix authored Sep 7, 2024
2 parents 2061cfb + 79d5dcd commit 67df3b4
Show file tree
Hide file tree
Showing 25 changed files with 204 additions and 87 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,13 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
cibw_python: ["cp38-*", "cp39-*", "cp310-*", "cp311-*", "cp312-*"]
cibw_python:
- "cp38-*"
- "cp39-*"
- "cp310-*"
- "cp311-*"
- "cp312-*"
- "cp313-*"
cibw_arch: ["x86_64", "aarch64", "universal2"]
exclude:
- os: ubuntu-latest
Expand Down Expand Up @@ -108,7 +114,7 @@ jobs:
run: |
brew install gnu-sed libtool autoconf automake
- uses: pypa/cibuildwheel@fff9ec32ed25a9c576750c91e06b410ed0c15db7 # v2.16.2
- uses: pypa/cibuildwheel@bd033a44476646b606efccdd5eed92d5ea1d77ad # v2.20.0
env:
CIBW_BUILD_VERBOSITY: 1
CIBW_BUILD: ${{ matrix.cibw_python }}
Expand Down
17 changes: 13 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,15 @@ jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
os: [ubuntu-latest, macos-latest]

env:
Expand All @@ -41,6 +48,7 @@ jobs:
if: steps.release.outputs.version == 0
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Install macOS deps
if: matrix.os == 'macos-latest' && steps.release.outputs.version == 0
Expand All @@ -49,17 +57,18 @@ jobs:
- name: Install Python Deps
if: steps.release.outputs.version == 0
env:
PIP_PRE: ${{ matrix.python-version == '3.13' && '1' || '0' }}
run: |
pip install -e .[test]
pip install -e .[test,dev]
- name: Test
if: steps.release.outputs.version == 0
run: |
make test
- name: Test (debug build)
# XXX Re-enable 3.12 once we migrate to Cython 3
if: steps.release.outputs.version == 0 && matrix.python-version != '3.12'
if: steps.release.outputs.version == 0
run: |
make distclean && make debug && make test
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ _default: compile


clean:
rm -fr dist/ doc/_build/ *.egg-info uvloop/loop.*.pyd
rm -fr dist/ doc/_build/ *.egg-info uvloop/loop.*.pyd uvloop/loop_d.*.pyd
rm -fr uvloop/*.c uvloop/*.html uvloop/*.so
rm -fr uvloop/handles/*.html uvloop/includes/*.html
find . -name '__pycache__' | xargs rm -rf
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ To build uvloop, you'll need Python 3.8 or greater:

.. code::
$ python3.7 -m venv uvloop-dev
$ python3 -m venv uvloop-dev
$ source uvloop-dev/bin/activate
3. Install development dependencies:
Expand Down
11 changes: 7 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: Implementation :: CPython",
"Topic :: System :: Networking",
]
Expand All @@ -36,14 +37,16 @@ test = [
# pycodestyle is a dependency of flake8, but it must be frozen because
# their combination breaks too often
# (example breakage: https://gitlab.com/pycqa/flake8/issues/427)
'aiohttp>=3.8.1; python_version < "3.12"',
'aiohttp==3.9.0b0; python_version >= "3.12"',
'aiohttp>=3.10.5',
'flake8~=5.0',
'psutil',
'pycodestyle~=2.9.0',
'pyOpenSSL~=23.0.0',
'mypy>=0.800',
'Cython(>=0.29.36,<0.30.0)',
]
dev = [
'setuptools>=60',
'Cython~=3.0',
]
docs = [
'Sphinx~=4.1.2',
Expand All @@ -55,7 +58,7 @@ docs = [
requires = [
"setuptools>=60",
"wheel",
"Cython(>=0.29.36,<0.30.0)",
"Cython~=3.0",
]
build-backend = "setuptools.build_meta"

Expand Down
13 changes: 10 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from setuptools.command.sdist import sdist


CYTHON_DEPENDENCY = 'Cython(>=0.29.36,<0.30.0)'
CYTHON_DEPENDENCY = 'Cython~=3.0'
MACHINE = platform.machine()
MODULES_CFLAGS = [os.getenv('UVLOOP_OPT_CFLAGS', '-O2')]
_ROOT = pathlib.Path(__file__).parent
Expand Down Expand Up @@ -140,11 +140,14 @@ def finalize_options(self):
v = True

directives[k] = v
self.cython_directives = directives

self.distribution.ext_modules[:] = cythonize(
self.distribution.ext_modules,
compiler_directives=directives,
annotate=self.cython_annotate)
annotate=self.cython_annotate,
compile_time_env=dict(DEFAULT_FREELIST_SIZE=250),
emit_linenums=self.debug)

super().finalize_options()

Expand Down Expand Up @@ -176,7 +179,11 @@ def build_libuv(self):
cmd,
cwd=LIBUV_BUILD_DIR, env=env, check=True)

j_flag = '-j{}'.format(os.cpu_count() or 1)
try:
njobs = len(os.sched_getaffinity(0))
except AttributeError:
njobs = os.cpu_count()
j_flag = '-j{}'.format(njobs or 1)
c_flag = "CFLAGS={}".format(env['CFLAGS'])
subprocess.run(
['make', j_flag, c_flag],
Expand Down
21 changes: 12 additions & 9 deletions tests/test_tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1631,17 +1631,22 @@ async def client(addr):
self.fail("unexpected call to connection_made()")

def test_ssl_connect_accepted_socket(self):
if hasattr(ssl, 'PROTOCOL_TLS'):
proto = ssl.PROTOCOL_TLS
if hasattr(ssl, 'PROTOCOL_TLS_SERVER'):
server_proto = ssl.PROTOCOL_TLS_SERVER
client_proto = ssl.PROTOCOL_TLS_CLIENT
else:
proto = ssl.PROTOCOL_SSLv23
server_context = ssl.SSLContext(proto)
if hasattr(ssl, 'PROTOCOL_TLS'):
client_proto = server_proto = ssl.PROTOCOL_TLS
else:
client_proto = server_proto = ssl.PROTOCOL_SSLv23

server_context = ssl.SSLContext(server_proto)
server_context.load_cert_chain(self.ONLYCERT, self.ONLYKEY)
if hasattr(server_context, 'check_hostname'):
server_context.check_hostname = False
server_context.verify_mode = ssl.CERT_NONE

client_context = ssl.SSLContext(proto)
client_context = ssl.SSLContext(client_proto)
if hasattr(server_context, 'check_hostname'):
client_context.check_hostname = False
client_context.verify_mode = ssl.CERT_NONE
Expand Down Expand Up @@ -2234,8 +2239,7 @@ def test_renegotiation(self):
sslctx.use_privatekey_file(self.ONLYKEY)
sslctx.use_certificate_chain_file(self.ONLYCERT)
client_sslctx = self._create_client_ssl_context()
if hasattr(ssl, 'OP_NO_TLSv1_3'):
client_sslctx.options |= ssl.OP_NO_TLSv1_3
client_sslctx.maximum_version = ssl.TLSVersion.TLSv1_2

def server(sock):
conn = openssl_ssl.Connection(sslctx, sock)
Expand Down Expand Up @@ -2593,8 +2597,7 @@ def test_flush_before_shutdown(self):
sslctx_openssl.use_privatekey_file(self.ONLYKEY)
sslctx_openssl.use_certificate_chain_file(self.ONLYCERT)
client_sslctx = self._create_client_ssl_context()
if hasattr(ssl, 'OP_NO_TLSv1_3'):
client_sslctx.options |= ssl.OP_NO_TLSv1_3
client_sslctx.maximum_version = ssl.TLSVersion.TLSv1_2

future = None

Expand Down
40 changes: 24 additions & 16 deletions tests/test_unix.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,18 @@ async def start_server():

self.assertFalse(srv.is_serving())

# asyncio doesn't cleanup the sock file
self.assertTrue(os.path.exists(sock_name))
if sys.version_info < (3, 13):
# asyncio doesn't cleanup the sock file under Python 3.13
self.assertTrue(os.path.exists(sock_name))
else:
self.assertFalse(os.path.exists(sock_name))

async def start_server_sock(start_server, is_unix_api=True):
# is_unix_api indicates whether `start_server` is calling
# `loop.create_unix_server()` or `loop.create_server()`,
# because asyncio `loop.create_server()` doesn't cleanup
# the socket file even if it's a UNIX socket.

async def start_server_sock(start_server):
nonlocal CNT
CNT = 0

Expand Down Expand Up @@ -140,8 +148,11 @@ async def start_server_sock(start_server):

self.assertFalse(srv.is_serving())

# asyncio doesn't cleanup the sock file
self.assertTrue(os.path.exists(sock_name))
if sys.version_info < (3, 13) or not is_unix_api:
# asyncio doesn't cleanup the sock file under Python 3.13
self.assertTrue(os.path.exists(sock_name))
else:
self.assertFalse(os.path.exists(sock_name))

with self.subTest(func='start_unix_server(host, port)'):
self.loop.run_until_complete(start_server())
Expand All @@ -160,7 +171,7 @@ async def start_server_sock(start_server):
lambda sock: asyncio.start_server(
handle_client,
None, None,
sock=sock)))
sock=sock), is_unix_api=False))
self.assertEqual(CNT, TOTAL_CNT)

def test_create_unix_server_2(self):
Expand Down Expand Up @@ -455,16 +466,13 @@ def test_create_unix_server_path_stream_bittype(self):
socket.AF_UNIX, socket.SOCK_STREAM | socket.SOCK_NONBLOCK)
with tempfile.NamedTemporaryFile() as file:
fn = file.name
try:
with sock:
sock.bind(fn)
coro = self.loop.create_unix_server(lambda: None, path=None,
sock=sock)
srv = self.loop.run_until_complete(coro)
srv.close()
self.loop.run_until_complete(srv.wait_closed())
finally:
os.unlink(fn)
with sock:
sock.bind(fn)
coro = self.loop.create_unix_server(lambda: None, path=None,
sock=sock, cleanup_socket=True)
srv = self.loop.run_until_complete(coro)
srv.close()
self.loop.run_until_complete(srv.wait_closed())

@unittest.skipUnless(sys.platform.startswith('linux'), 'requires epoll')
def test_epollhup(self):
Expand Down
4 changes: 3 additions & 1 deletion uvloop/_testbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,9 @@ def find_free_port(start_from=50000):
class SSLTestCase:

def _create_server_ssl_context(self, certfile, keyfile=None):
if hasattr(ssl, 'PROTOCOL_TLS'):
if hasattr(ssl, 'PROTOCOL_TLS_SERVER'):
sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
elif hasattr(ssl, 'PROTOCOL_TLS'):
sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS)
else:
sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Expand Down
2 changes: 1 addition & 1 deletion uvloop/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
# supported platforms, publish the packages on PyPI, merge the PR
# to the target branch, create a Git tag pointing to the commit.

__version__ = '0.19.0'
__version__ = '0.21.0beta1'
2 changes: 1 addition & 1 deletion uvloop/dns.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ cdef class AddrInfo:
uv.uv_freeaddrinfo(self.data) # returns void
self.data = NULL

cdef void set_data(self, system.addrinfo *data):
cdef void set_data(self, system.addrinfo *data) noexcept:
self.data = data

cdef unpack(self):
Expand Down
2 changes: 1 addition & 1 deletion uvloop/handles/handle.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ cdef void __uv_close_handle_cb(uv.uv_handle_t* handle) noexcept with gil:
Py_DECREF(h) # Was INCREFed in UVHandle._close


cdef void __close_all_handles(Loop loop):
cdef void __close_all_handles(Loop loop) noexcept:
uv.uv_walk(loop.uvloop,
__uv_walk_close_all_handles_cb,
<void*>loop) # void
Expand Down
23 changes: 22 additions & 1 deletion uvloop/handles/pipe.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ cdef __pipe_init_uv_handle(UVStream handle, Loop loop):
cdef __pipe_open(UVStream handle, int fd):
cdef int err
err = uv.uv_pipe_open(<uv.uv_pipe_t *>handle._handle,
<uv.uv_file>fd)
<uv.uv_os_fd_t>fd)
if err < 0:
exc = convert_error(err)
raise exc
Expand Down Expand Up @@ -80,6 +80,27 @@ cdef class UnixServer(UVStreamServer):
context)
return <UVStream>tr

cdef _close(self):
sock = self._fileobj
if sock is not None and sock in self._loop._unix_server_sockets:
path = sock.getsockname()
else:
path = None

UVStreamServer._close(self)

if path is not None:
prev_ino = self._loop._unix_server_sockets[sock]
del self._loop._unix_server_sockets[sock]
try:
if os_stat(path).st_ino == prev_ino:
os_unlink(path)
except FileNotFoundError:
pass
except OSError as err:
aio_logger.error('Unable to clean up listening UNIX socket '
'%r: %r', path, err)


@cython.no_gc_clear
cdef class UnixTransport(UVStream):
Expand Down
2 changes: 1 addition & 1 deletion uvloop/handles/poll.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ cdef class UVPoll(UVHandle):
cdef inline _poll_start(self, int flags)
cdef inline _poll_stop(self)

cdef int is_active(self)
cdef int is_active(self) noexcept

cdef is_reading(self)
cdef is_writing(self)
Expand Down
2 changes: 1 addition & 1 deletion uvloop/handles/poll.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ cdef class UVPoll(UVHandle):
handle._init(loop, fd)
return handle

cdef int is_active(self):
cdef int is_active(self) noexcept:
return (self.reading_handle is not None or
self.writing_handle is not None)

Expand Down
6 changes: 5 additions & 1 deletion uvloop/handles/stream.pyx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
DEF __PREALLOCED_BUFS = 4
cdef extern from *:
'''
enum {__PREALLOCED_BUFS = 4};
'''
const bint __PREALLOCED_BUFS


@cython.no_gc_clear
Expand Down
Loading

0 comments on commit 67df3b4

Please sign in to comment.