Skip to content

Commit 67df3b4

Browse files
authored
Merge branch 'master' into resolve-broadcast-hostname
2 parents 2061cfb + 79d5dcd commit 67df3b4

File tree

25 files changed

+204
-87
lines changed

25 files changed

+204
-87
lines changed

.github/workflows/release.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,13 @@ jobs:
7676
fail-fast: false
7777
matrix:
7878
os: [ubuntu-latest, macos-latest]
79-
cibw_python: ["cp38-*", "cp39-*", "cp310-*", "cp311-*", "cp312-*"]
79+
cibw_python:
80+
- "cp38-*"
81+
- "cp39-*"
82+
- "cp310-*"
83+
- "cp311-*"
84+
- "cp312-*"
85+
- "cp313-*"
8086
cibw_arch: ["x86_64", "aarch64", "universal2"]
8187
exclude:
8288
- os: ubuntu-latest
@@ -108,7 +114,7 @@ jobs:
108114
run: |
109115
brew install gnu-sed libtool autoconf automake
110116
111-
- uses: pypa/cibuildwheel@fff9ec32ed25a9c576750c91e06b410ed0c15db7 # v2.16.2
117+
- uses: pypa/cibuildwheel@bd033a44476646b606efccdd5eed92d5ea1d77ad # v2.20.0
112118
env:
113119
CIBW_BUILD_VERBOSITY: 1
114120
CIBW_BUILD: ${{ matrix.cibw_python }}

.github/workflows/tests.yml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,15 @@ jobs:
1313
test:
1414
runs-on: ${{ matrix.os }}
1515
strategy:
16+
fail-fast: false
1617
matrix:
17-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
18+
python-version:
19+
- "3.8"
20+
- "3.9"
21+
- "3.10"
22+
- "3.11"
23+
- "3.12"
24+
- "3.13"
1825
os: [ubuntu-latest, macos-latest]
1926

2027
env:
@@ -41,6 +48,7 @@ jobs:
4148
if: steps.release.outputs.version == 0
4249
with:
4350
python-version: ${{ matrix.python-version }}
51+
allow-prereleases: true
4452

4553
- name: Install macOS deps
4654
if: matrix.os == 'macos-latest' && steps.release.outputs.version == 0
@@ -49,17 +57,18 @@ jobs:
4957
5058
- name: Install Python Deps
5159
if: steps.release.outputs.version == 0
60+
env:
61+
PIP_PRE: ${{ matrix.python-version == '3.13' && '1' || '0' }}
5262
run: |
53-
pip install -e .[test]
63+
pip install -e .[test,dev]
5464
5565
- name: Test
5666
if: steps.release.outputs.version == 0
5767
run: |
5868
make test
5969
6070
- name: Test (debug build)
61-
# XXX Re-enable 3.12 once we migrate to Cython 3
62-
if: steps.release.outputs.version == 0 && matrix.python-version != '3.12'
71+
if: steps.release.outputs.version == 0
6372
run: |
6473
make distclean && make debug && make test
6574

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ _default: compile
99

1010

1111
clean:
12-
rm -fr dist/ doc/_build/ *.egg-info uvloop/loop.*.pyd
12+
rm -fr dist/ doc/_build/ *.egg-info uvloop/loop.*.pyd uvloop/loop_d.*.pyd
1313
rm -fr uvloop/*.c uvloop/*.html uvloop/*.so
1414
rm -fr uvloop/handles/*.html uvloop/includes/*.html
1515
find . -name '__pycache__' | xargs rm -rf

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ To build uvloop, you'll need Python 3.8 or greater:
109109

110110
.. code::
111111
112-
$ python3.7 -m venv uvloop-dev
112+
$ python3 -m venv uvloop-dev
113113
$ source uvloop-dev/bin/activate
114114
115115
3. Install development dependencies:

pyproject.toml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ classifiers = [
2424
"Programming Language :: Python :: 3.10",
2525
"Programming Language :: Python :: 3.11",
2626
"Programming Language :: Python :: 3.12",
27+
"Programming Language :: Python :: 3.13",
2728
"Programming Language :: Python :: Implementation :: CPython",
2829
"Topic :: System :: Networking",
2930
]
@@ -36,14 +37,16 @@ test = [
3637
# pycodestyle is a dependency of flake8, but it must be frozen because
3738
# their combination breaks too often
3839
# (example breakage: https://gitlab.com/pycqa/flake8/issues/427)
39-
'aiohttp>=3.8.1; python_version < "3.12"',
40-
'aiohttp==3.9.0b0; python_version >= "3.12"',
40+
'aiohttp>=3.10.5',
4141
'flake8~=5.0',
4242
'psutil',
4343
'pycodestyle~=2.9.0',
4444
'pyOpenSSL~=23.0.0',
4545
'mypy>=0.800',
46-
'Cython(>=0.29.36,<0.30.0)',
46+
]
47+
dev = [
48+
'setuptools>=60',
49+
'Cython~=3.0',
4750
]
4851
docs = [
4952
'Sphinx~=4.1.2',
@@ -55,7 +58,7 @@ docs = [
5558
requires = [
5659
"setuptools>=60",
5760
"wheel",
58-
"Cython(>=0.29.36,<0.30.0)",
61+
"Cython~=3.0",
5962
]
6063
build-backend = "setuptools.build_meta"
6164

setup.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from setuptools.command.sdist import sdist
2222

2323

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

142142
directives[k] = v
143+
self.cython_directives = directives
143144

144145
self.distribution.ext_modules[:] = cythonize(
145146
self.distribution.ext_modules,
146147
compiler_directives=directives,
147-
annotate=self.cython_annotate)
148+
annotate=self.cython_annotate,
149+
compile_time_env=dict(DEFAULT_FREELIST_SIZE=250),
150+
emit_linenums=self.debug)
148151

149152
super().finalize_options()
150153

@@ -176,7 +179,11 @@ def build_libuv(self):
176179
cmd,
177180
cwd=LIBUV_BUILD_DIR, env=env, check=True)
178181

179-
j_flag = '-j{}'.format(os.cpu_count() or 1)
182+
try:
183+
njobs = len(os.sched_getaffinity(0))
184+
except AttributeError:
185+
njobs = os.cpu_count()
186+
j_flag = '-j{}'.format(njobs or 1)
180187
c_flag = "CFLAGS={}".format(env['CFLAGS'])
181188
subprocess.run(
182189
['make', j_flag, c_flag],

tests/test_tcp.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,17 +1631,22 @@ async def client(addr):
16311631
self.fail("unexpected call to connection_made()")
16321632

16331633
def test_ssl_connect_accepted_socket(self):
1634-
if hasattr(ssl, 'PROTOCOL_TLS'):
1635-
proto = ssl.PROTOCOL_TLS
1634+
if hasattr(ssl, 'PROTOCOL_TLS_SERVER'):
1635+
server_proto = ssl.PROTOCOL_TLS_SERVER
1636+
client_proto = ssl.PROTOCOL_TLS_CLIENT
16361637
else:
1637-
proto = ssl.PROTOCOL_SSLv23
1638-
server_context = ssl.SSLContext(proto)
1638+
if hasattr(ssl, 'PROTOCOL_TLS'):
1639+
client_proto = server_proto = ssl.PROTOCOL_TLS
1640+
else:
1641+
client_proto = server_proto = ssl.PROTOCOL_SSLv23
1642+
1643+
server_context = ssl.SSLContext(server_proto)
16391644
server_context.load_cert_chain(self.ONLYCERT, self.ONLYKEY)
16401645
if hasattr(server_context, 'check_hostname'):
16411646
server_context.check_hostname = False
16421647
server_context.verify_mode = ssl.CERT_NONE
16431648

1644-
client_context = ssl.SSLContext(proto)
1649+
client_context = ssl.SSLContext(client_proto)
16451650
if hasattr(server_context, 'check_hostname'):
16461651
client_context.check_hostname = False
16471652
client_context.verify_mode = ssl.CERT_NONE
@@ -2234,8 +2239,7 @@ def test_renegotiation(self):
22342239
sslctx.use_privatekey_file(self.ONLYKEY)
22352240
sslctx.use_certificate_chain_file(self.ONLYCERT)
22362241
client_sslctx = self._create_client_ssl_context()
2237-
if hasattr(ssl, 'OP_NO_TLSv1_3'):
2238-
client_sslctx.options |= ssl.OP_NO_TLSv1_3
2242+
client_sslctx.maximum_version = ssl.TLSVersion.TLSv1_2
22392243

22402244
def server(sock):
22412245
conn = openssl_ssl.Connection(sslctx, sock)
@@ -2593,8 +2597,7 @@ def test_flush_before_shutdown(self):
25932597
sslctx_openssl.use_privatekey_file(self.ONLYKEY)
25942598
sslctx_openssl.use_certificate_chain_file(self.ONLYCERT)
25952599
client_sslctx = self._create_client_ssl_context()
2596-
if hasattr(ssl, 'OP_NO_TLSv1_3'):
2597-
client_sslctx.options |= ssl.OP_NO_TLSv1_3
2600+
client_sslctx.maximum_version = ssl.TLSVersion.TLSv1_2
25982601

25992602
future = None
26002603

tests/test_unix.py

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,18 @@ async def start_server():
9696

9797
self.assertFalse(srv.is_serving())
9898

99-
# asyncio doesn't cleanup the sock file
100-
self.assertTrue(os.path.exists(sock_name))
99+
if sys.version_info < (3, 13):
100+
# asyncio doesn't cleanup the sock file under Python 3.13
101+
self.assertTrue(os.path.exists(sock_name))
102+
else:
103+
self.assertFalse(os.path.exists(sock_name))
104+
105+
async def start_server_sock(start_server, is_unix_api=True):
106+
# is_unix_api indicates whether `start_server` is calling
107+
# `loop.create_unix_server()` or `loop.create_server()`,
108+
# because asyncio `loop.create_server()` doesn't cleanup
109+
# the socket file even if it's a UNIX socket.
101110

102-
async def start_server_sock(start_server):
103111
nonlocal CNT
104112
CNT = 0
105113

@@ -140,8 +148,11 @@ async def start_server_sock(start_server):
140148

141149
self.assertFalse(srv.is_serving())
142150

143-
# asyncio doesn't cleanup the sock file
144-
self.assertTrue(os.path.exists(sock_name))
151+
if sys.version_info < (3, 13) or not is_unix_api:
152+
# asyncio doesn't cleanup the sock file under Python 3.13
153+
self.assertTrue(os.path.exists(sock_name))
154+
else:
155+
self.assertFalse(os.path.exists(sock_name))
145156

146157
with self.subTest(func='start_unix_server(host, port)'):
147158
self.loop.run_until_complete(start_server())
@@ -160,7 +171,7 @@ async def start_server_sock(start_server):
160171
lambda sock: asyncio.start_server(
161172
handle_client,
162173
None, None,
163-
sock=sock)))
174+
sock=sock), is_unix_api=False))
164175
self.assertEqual(CNT, TOTAL_CNT)
165176

166177
def test_create_unix_server_2(self):
@@ -455,16 +466,13 @@ def test_create_unix_server_path_stream_bittype(self):
455466
socket.AF_UNIX, socket.SOCK_STREAM | socket.SOCK_NONBLOCK)
456467
with tempfile.NamedTemporaryFile() as file:
457468
fn = file.name
458-
try:
459-
with sock:
460-
sock.bind(fn)
461-
coro = self.loop.create_unix_server(lambda: None, path=None,
462-
sock=sock)
463-
srv = self.loop.run_until_complete(coro)
464-
srv.close()
465-
self.loop.run_until_complete(srv.wait_closed())
466-
finally:
467-
os.unlink(fn)
469+
with sock:
470+
sock.bind(fn)
471+
coro = self.loop.create_unix_server(lambda: None, path=None,
472+
sock=sock, cleanup_socket=True)
473+
srv = self.loop.run_until_complete(coro)
474+
srv.close()
475+
self.loop.run_until_complete(srv.wait_closed())
468476

469477
@unittest.skipUnless(sys.platform.startswith('linux'), 'requires epoll')
470478
def test_epollhup(self):

uvloop/_testbase.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,9 @@ def find_free_port(start_from=50000):
269269
class SSLTestCase:
270270

271271
def _create_server_ssl_context(self, certfile, keyfile=None):
272-
if hasattr(ssl, 'PROTOCOL_TLS'):
272+
if hasattr(ssl, 'PROTOCOL_TLS_SERVER'):
273+
sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
274+
elif hasattr(ssl, 'PROTOCOL_TLS'):
273275
sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS)
274276
else:
275277
sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23)

uvloop/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010
# supported platforms, publish the packages on PyPI, merge the PR
1111
# to the target branch, create a Git tag pointing to the commit.
1212

13-
__version__ = '0.19.0'
13+
__version__ = '0.21.0beta1'

0 commit comments

Comments
 (0)