Skip to content
Merged
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
11 changes: 6 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
mkdir -p dist/
echo "${VERSION}" > dist/VERSION

- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dist
path: dist/
Expand All @@ -55,7 +55,7 @@ jobs:
fetch-depth: 50
submodules: true

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

Expand All @@ -64,7 +64,7 @@ jobs:
python -m pip install --upgrade setuptools wheel pip
python setup.py sdist

- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dist
path: dist/*.tar.*
Expand All @@ -84,6 +84,7 @@ jobs:
- "cp312-*"
- "cp313-*"
- "cp314-*"
- "cp314t-*"
cibw_arch: ["x86_64", "aarch64", "universal2"]
exclude:
- os: ubuntu-latest
Expand Down Expand Up @@ -115,14 +116,14 @@ jobs:
run: |
brew install gnu-sed libtool autoconf automake

- uses: pypa/cibuildwheel@7940a4c0e76eb2030e473a5f864f291f63ee879b # v2.21.3
- uses: pypa/cibuildwheel@7c619efba910c04005a835b110b057fc28fd6e93 # v3.2.0
env:
CIBW_BUILD_VERBOSITY: 1
CIBW_BUILD: ${{ matrix.cibw_python }}
CIBW_ARCHS: ${{ matrix.cibw_arch }}
CIBW_TEST_SKIP: "*universal2:arm64"

- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dist
path: wheelhouse/*.whl
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
- "3.12"
- "3.13"
- "3.14"
- "3.14t"
os: [ubuntu-latest, macos-latest]

env:
Expand All @@ -45,7 +46,7 @@ jobs:
__version__\s*=\s*(?:['"])([[:PEP440:]])(?:['"])

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
if: steps.release.outputs.version == 0
with:
python-version: ${{ matrix.python-version }}
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ test = [
'flake8~=6.1',
'psutil',
'pycodestyle~=2.11.0',
'pyOpenSSL~=23.0.0',
'pyOpenSSL~=25.3.0',
'mypy>=0.800',
]
dev = [
Expand All @@ -58,7 +58,7 @@ docs = [
requires = [
"setuptools>=60",
"wheel",
"Cython~=3.0",
"Cython~=3.1",
]
build-backend = "setuptools.build_meta"

Expand Down
64 changes: 64 additions & 0 deletions tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import random
import sys
import subprocess
import threading
import time
import uvloop
Expand Down Expand Up @@ -735,6 +736,69 @@ def scheduler():
thread.join()
self.assertEqual(counter[0], ITERATIONS)

def test_freethreading(self):
if not hasattr(sys, "_is_gil_enabled"):
raise unittest.SkipTest("No sys._is_gil_enabled()")
if os.cpu_count() < 2:
raise unittest.SkipTest("Flaky on single CPU machines")
prog = """\
import asyncio
import os
import sys
import threading
import time


counter = 0


def job(barrier):
global counter
barrier.wait()
start_time = time.monotonic()
rv = 0
while time.monotonic() - start_time < 1:
for _i in range(10**4):
counter += 1
rv += 1
return rv


async def main():
if sys._is_gil_enabled():
print("{impl} turned on GIL")
return False
loop = asyncio.get_running_loop()
n_jobs = os.cpu_count()
barrier = threading.Barrier(n_jobs)
fs = [loop.run_in_executor(None, job, barrier) for _ in range(n_jobs)]
result = sum(await asyncio.gather(*fs))
if counter == result:
print("Expected race condition did not happen")
return False
return True


if __name__ == "__main__":
if sys._is_gil_enabled():
print("Not running with GIL disabled")
sys.exit(2)

import {impl}

if not {impl}.run(main()):
sys.exit(1)
"""
result = subprocess.run(
[sys.executable, '-c', prog.format(impl=self.implementation)],
stdout=subprocess.PIPE,
text=True,
)
if result.returncode == 2:
raise unittest.SkipTest(result.stdout.strip())
elif result.returncode != 0:
self.fail(result.stdout.strip())


class TestBaseUV(_TestBase, UVTestCase):

Expand Down
2 changes: 2 additions & 0 deletions tests/test_tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,8 @@ async def client(addr):
self.assertEqual(await reader.readexactly(2), b'OK')

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

Expand Down
2 changes: 1 addition & 1 deletion uvloop/loop.pyx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# cython: language_level=3, embedsignature=True
# cython: language_level=3, embedsignature=True, freethreading_compatible=True

import asyncio
cimport cython
Expand Down