Skip to content

Commit 286b370

Browse files
add free-threading support (#693)
--------- Co-authored-by: Fantix King <[email protected]>
1 parent 46456b6 commit 286b370

File tree

6 files changed

+77
-9
lines changed

6 files changed

+77
-9
lines changed

.github/workflows/release.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
mkdir -p dist/
3838
echo "${VERSION}" > dist/VERSION
3939
40-
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
40+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
4141
with:
4242
name: dist
4343
path: dist/
@@ -55,7 +55,7 @@ jobs:
5555
fetch-depth: 50
5656
submodules: true
5757

58-
- uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
58+
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
5959
with:
6060
python-version: 3.x
6161

@@ -64,7 +64,7 @@ jobs:
6464
python -m pip install --upgrade setuptools wheel pip
6565
python setup.py sdist
6666
67-
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
67+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
6868
with:
6969
name: dist
7070
path: dist/*.tar.*
@@ -84,6 +84,7 @@ jobs:
8484
- "cp312-*"
8585
- "cp313-*"
8686
- "cp314-*"
87+
- "cp314t-*"
8788
cibw_arch: ["x86_64", "aarch64", "universal2"]
8889
exclude:
8990
- os: ubuntu-latest
@@ -115,14 +116,14 @@ jobs:
115116
run: |
116117
brew install gnu-sed libtool autoconf automake
117118
118-
- uses: pypa/cibuildwheel@7940a4c0e76eb2030e473a5f864f291f63ee879b # v2.21.3
119+
- uses: pypa/cibuildwheel@7c619efba910c04005a835b110b057fc28fd6e93 # v3.2.0
119120
env:
120121
CIBW_BUILD_VERBOSITY: 1
121122
CIBW_BUILD: ${{ matrix.cibw_python }}
122123
CIBW_ARCHS: ${{ matrix.cibw_arch }}
123124
CIBW_TEST_SKIP: "*universal2:arm64"
124125

125-
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
126+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
126127
with:
127128
name: dist
128129
path: wheelhouse/*.whl

.github/workflows/tests.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ jobs:
2323
- "3.12"
2424
- "3.13"
2525
- "3.14"
26+
- "3.14t"
2627
os: [ubuntu-latest, macos-latest]
2728

2829
env:
@@ -45,7 +46,7 @@ jobs:
4546
__version__\s*=\s*(?:['"])([[:PEP440:]])(?:['"])
4647
4748
- name: Set up Python ${{ matrix.python-version }}
48-
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
49+
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
4950
if: steps.release.outputs.version == 0
5051
with:
5152
python-version: ${{ matrix.python-version }}

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ test = [
4141
'flake8~=6.1',
4242
'psutil',
4343
'pycodestyle~=2.11.0',
44-
'pyOpenSSL~=23.0.0',
44+
'pyOpenSSL~=25.3.0',
4545
'mypy>=0.800',
4646
]
4747
dev = [
@@ -58,7 +58,7 @@ docs = [
5858
requires = [
5959
"setuptools>=60",
6060
"wheel",
61-
"Cython~=3.0",
61+
"Cython~=3.1",
6262
]
6363
build-backend = "setuptools.build_meta"
6464

tests/test_base.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55
import random
66
import sys
7+
import subprocess
78
import threading
89
import time
910
import uvloop
@@ -735,6 +736,69 @@ def scheduler():
735736
thread.join()
736737
self.assertEqual(counter[0], ITERATIONS)
737738

739+
def test_freethreading(self):
740+
if not hasattr(sys, "_is_gil_enabled"):
741+
raise unittest.SkipTest("No sys._is_gil_enabled()")
742+
if os.cpu_count() < 2:
743+
raise unittest.SkipTest("Flaky on single CPU machines")
744+
prog = """\
745+
import asyncio
746+
import os
747+
import sys
748+
import threading
749+
import time
750+
751+
752+
counter = 0
753+
754+
755+
def job(barrier):
756+
global counter
757+
barrier.wait()
758+
start_time = time.monotonic()
759+
rv = 0
760+
while time.monotonic() - start_time < 1:
761+
for _i in range(10**4):
762+
counter += 1
763+
rv += 1
764+
return rv
765+
766+
767+
async def main():
768+
if sys._is_gil_enabled():
769+
print("{impl} turned on GIL")
770+
return False
771+
loop = asyncio.get_running_loop()
772+
n_jobs = os.cpu_count()
773+
barrier = threading.Barrier(n_jobs)
774+
fs = [loop.run_in_executor(None, job, barrier) for _ in range(n_jobs)]
775+
result = sum(await asyncio.gather(*fs))
776+
if counter == result:
777+
print("Expected race condition did not happen")
778+
return False
779+
return True
780+
781+
782+
if __name__ == "__main__":
783+
if sys._is_gil_enabled():
784+
print("Not running with GIL disabled")
785+
sys.exit(2)
786+
787+
import {impl}
788+
789+
if not {impl}.run(main()):
790+
sys.exit(1)
791+
"""
792+
result = subprocess.run(
793+
[sys.executable, '-c', prog.format(impl=self.implementation)],
794+
stdout=subprocess.PIPE,
795+
text=True,
796+
)
797+
if result.returncode == 2:
798+
raise unittest.SkipTest(result.stdout.strip())
799+
elif result.returncode != 0:
800+
self.fail(result.stdout.strip())
801+
738802

739803
class TestBaseUV(_TestBase, UVTestCase):
740804

tests/test_tcp.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,8 @@ async def client(addr):
405405
self.assertEqual(await reader.readexactly(2), b'OK')
406406

407407
re = r'(a bytes-like object)|(must be byte-ish)'
408+
if sys.version_info >= (3, 14):
409+
re += r'|(must be a bytes, bytearray, or memoryview object)'
408410
with self.assertRaisesRegex(TypeError, re):
409411
writer.write('AAAA')
410412

uvloop/loop.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# cython: language_level=3, embedsignature=True
1+
# cython: language_level=3, embedsignature=True, freethreading_compatible=True
22

33
import asyncio
44
cimport cython

0 commit comments

Comments
 (0)