mirror of
https://github.com/msgpack/msgpack-python.git
synced 2025-11-10 22:41:03 +00:00
Add no-GIL interpreter support
Add `pytest-run-parallel` as dependency, test no-GIL interpreters in CI, and mark Cython module as safe for freethreaded interpreters.
This commit is contained in:
parent
42f056f3cf
commit
6ced817616
7 changed files with 59 additions and 7 deletions
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
|
|
@ -10,7 +10,7 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
os: ["ubuntu-latest", "windows-latest", "macos-latest"]
|
||||
py: ["3.14-dev", "3.13", "3.12", "3.11", "3.10", "3.9", "3.8"]
|
||||
py: ["3.14", "3.14t", "3.13", "3.13t", "3.12", "3.11", "3.10", "3.9", "3.8"]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
name: Run test with Python ${{ matrix.py }} on ${{ matrix.os }}
|
||||
|
|
@ -41,12 +41,12 @@ jobs:
|
|||
- name: Test (C extension)
|
||||
shell: bash
|
||||
run: |
|
||||
pytest -v test
|
||||
PYTHON_GIL=0 pytest -v test
|
||||
|
||||
- name: Test (pure Python fallback)
|
||||
shell: bash
|
||||
run: |
|
||||
MSGPACK_PUREPYTHON=1 pytest -v test
|
||||
PYTHON_GIL=0 MSGPACK_PUREPYTHON=1 pytest -v test
|
||||
|
||||
- name: build packages
|
||||
shell: bash
|
||||
|
|
|
|||
3
.github/workflows/wheel.yml
vendored
3
.github/workflows/wheel.yml
vendored
|
|
@ -32,8 +32,9 @@ jobs:
|
|||
uses: pypa/cibuildwheel@v2.23.3
|
||||
env:
|
||||
CIBW_TEST_REQUIRES: "pytest"
|
||||
CIBW_TEST_COMMAND: "pytest {package}/test"
|
||||
CIBW_TEST_COMMAND: "PYTHON_GIL=0 pytest {package}/test"
|
||||
CIBW_SKIP: "pp* cp38-macosx_*"
|
||||
CIBW_ENABLE: cpython-freerelease
|
||||
|
||||
- name: Build sdist
|
||||
if: runner.os == 'Linux' && runner.arch == 'X64'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# coding: utf-8
|
||||
#cython: embedsignature=True, c_string_encoding=ascii, language_level=3
|
||||
#cython: embedsignature=True, c_string_encoding=ascii, language_level=3, freethreading_compatible=True
|
||||
from cpython.datetime cimport import_datetime, datetime_new
|
||||
import_datetime()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# coding: utf-8
|
||||
|
||||
# cython: freethreading_compatible = True
|
||||
from cpython cimport *
|
||||
from cpython.bytearray cimport PyByteArray_Check, PyByteArray_CheckExact
|
||||
from cpython.datetime cimport (
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# coding: utf-8
|
||||
|
||||
# cython: freethreading_compatible = True
|
||||
from cpython cimport *
|
||||
cdef extern from "Python.h":
|
||||
ctypedef struct PyObject
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
Cython~=3.1.1
|
||||
pytest-run-parallel[psutil]
|
||||
|
|
|
|||
50
test/test_multithreading.py
Normal file
50
test/test_multithreading.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env python3
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from msgpack import Packer
|
||||
import threading
|
||||
|
||||
|
||||
def run_threaded(
|
||||
func,
|
||||
num_threads=8,
|
||||
pass_count=False,
|
||||
pass_barrier=False,
|
||||
outer_iterations=1,
|
||||
prepare_args=None,
|
||||
):
|
||||
"""Runs a function many times in parallel"""
|
||||
for _ in range(outer_iterations):
|
||||
with ThreadPoolExecutor(max_workers=num_threads) as tpe:
|
||||
if prepare_args is None:
|
||||
args = []
|
||||
else:
|
||||
args = prepare_args()
|
||||
if pass_barrier:
|
||||
barrier = threading.Barrier(num_threads)
|
||||
args.append(barrier)
|
||||
if pass_count:
|
||||
all_args = [(func, i, *args) for i in range(num_threads)]
|
||||
else:
|
||||
all_args = [(func, *args) for i in range(num_threads)]
|
||||
try:
|
||||
futures = []
|
||||
for arg in all_args:
|
||||
futures.append(tpe.submit(*arg))
|
||||
finally:
|
||||
if len(futures) < num_threads and pass_barrier:
|
||||
barrier.abort()
|
||||
for f in futures:
|
||||
f.result()
|
||||
|
||||
|
||||
def test_multithread_packing():
|
||||
output = []
|
||||
test_data = "abcd" * 10_000_000
|
||||
packer = Packer()
|
||||
|
||||
def closure(b):
|
||||
data = packer.pack(test_data)
|
||||
output.append(data)
|
||||
b.wait()
|
||||
|
||||
run_threaded(closure, num_threads=10, pass_barrier=True, pass_count=False)
|
||||
Loading…
Add table
Add a link
Reference in a new issue