Skip to content

Commit af45640

Browse files
authored
cython: freethreading_compatible (#654)
``` $ v3/bin/python -VV Python 3.14.0 free-threading build (main, Oct 7 2025, 15:35:12) [Clang 20.1.4 ] $ v3/bin/python -c 'import sys,msgpack; print(sys._is_gil_enabled())' False ```
1 parent c2546ea commit af45640

File tree

4 files changed

+20
-6
lines changed

4 files changed

+20
-6
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
strategy:
1111
matrix:
1212
os: ["ubuntu-latest", "windows-latest", "windows-11-arm", "macos-latest"]
13-
py: ["3.14-dev", "3.13", "3.12", "3.11", "3.10", "3.9"]
13+
py: ["3.14", "3.14t", "3.13", "3.12", "3.11", "3.10", "3.9"]
1414
exclude:
1515
- os: windows-11-arm
1616
py: "3.9"

msgpack/_cmsgpack.pyx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
# coding: utf-8
21
#cython: embedsignature=True, c_string_encoding=ascii, language_level=3
2+
#cython: freethreading_compatible = True
3+
import cython
34
from cpython.datetime cimport import_datetime, datetime_new
45
import_datetime()
56

msgpack/_packer.pyx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# coding: utf-8
2-
31
from cpython cimport *
42
from cpython.bytearray cimport PyByteArray_Check, PyByteArray_CheckExact
53
from cpython.datetime cimport (
@@ -129,6 +127,7 @@ cdef class Packer:
129127
if self.exports > 0:
130128
raise BufferError("Existing exports of data: Packer cannot be changed")
131129

130+
@cython.critical_section
132131
def __init__(self, *, default=None,
133132
bint use_single_float=False, bint autoreset=True, bint use_bin_type=True,
134133
bint strict_types=False, bint datetime=False, unicode_errors=None,
@@ -269,6 +268,7 @@ cdef class Packer:
269268
return ret
270269
return self._pack_inner(o, 0, nest_limit)
271270

271+
@cython.critical_section
272272
def pack(self, object obj):
273273
cdef int ret
274274
self._check_exports()
@@ -284,13 +284,15 @@ cdef class Packer:
284284
self.pk.length = 0
285285
return buf
286286

287+
@cython.critical_section
287288
def pack_ext_type(self, typecode, data):
288289
self._check_exports()
289290
if len(data) > ITEM_LIMIT:
290291
raise ValueError("ext data too large")
291292
msgpack_pack_ext(&self.pk, typecode, len(data))
292293
msgpack_pack_raw_body(&self.pk, data, len(data))
293294

295+
@cython.critical_section
294296
def pack_array_header(self, long long size):
295297
self._check_exports()
296298
if size > ITEM_LIMIT:
@@ -301,6 +303,7 @@ cdef class Packer:
301303
self.pk.length = 0
302304
return buf
303305

306+
@cython.critical_section
304307
def pack_map_header(self, long long size):
305308
self._check_exports()
306309
if size > ITEM_LIMIT:
@@ -311,6 +314,7 @@ cdef class Packer:
311314
self.pk.length = 0
312315
return buf
313316

317+
@cython.critical_section
314318
def pack_map_pairs(self, object pairs):
315319
"""
316320
Pack *pairs* as msgpack map type.
@@ -331,6 +335,7 @@ cdef class Packer:
331335
self.pk.length = 0
332336
return buf
333337

338+
@cython.critical_section
334339
def reset(self):
335340
"""Reset internal buffer.
336341
@@ -339,6 +344,7 @@ cdef class Packer:
339344
self._check_exports()
340345
self.pk.length = 0
341346

347+
@cython.critical_section
342348
def bytes(self):
343349
"""Return internal buffer contents as bytes object"""
344350
return PyBytes_FromStringAndSize(self.pk.buf, self.pk.length)

msgpack/_unpacker.pyx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# coding: utf-8
2-
31
from cpython cimport *
42
cdef extern from "Python.h":
53
ctypedef struct PyObject
@@ -324,6 +322,7 @@ cdef class Unpacker:
324322
PyMem_Free(self.buf)
325323
self.buf = NULL
326324

325+
@cython.critical_section
327326
def __init__(self, file_like=None, *, Py_ssize_t read_size=0,
328327
bint use_list=True, bint raw=False, int timestamp=0, bint strict_map_key=True,
329328
object object_hook=None, object object_pairs_hook=None, object list_hook=None,
@@ -384,6 +383,7 @@ cdef class Unpacker:
384383
max_str_len, max_bin_len, max_array_len,
385384
max_map_len, max_ext_len)
386385

386+
@cython.critical_section
387387
def feed(self, object next_bytes):
388388
"""Append `next_bytes` to internal buffer."""
389389
cdef Py_buffer pybuff
@@ -484,6 +484,7 @@ cdef class Unpacker:
484484
else:
485485
raise ValueError("Unpack failed: error = %d" % (ret,))
486486

487+
@cython.critical_section
487488
def read_bytes(self, Py_ssize_t nbytes):
488489
"""Read a specified number of raw bytes from the stream"""
489490
cdef Py_ssize_t nread
@@ -496,20 +497,23 @@ cdef class Unpacker:
496497
self.stream_offset += nread
497498
return ret
498499

500+
@cython.critical_section
499501
def unpack(self):
500502
"""Unpack one object
501503
502504
Raises `OutOfData` when there are no more bytes to unpack.
503505
"""
504506
return self._unpack(unpack_construct)
505507

508+
@cython.critical_section
506509
def skip(self):
507510
"""Read and ignore one object, returning None
508511
509512
Raises `OutOfData` when there are no more bytes to unpack.
510513
"""
511514
return self._unpack(unpack_skip)
512515

516+
@cython.critical_section
513517
def read_array_header(self):
514518
"""assuming the next object is an array, return its size n, such that
515519
the next n unpack() calls will iterate over its contents.
@@ -518,6 +522,7 @@ cdef class Unpacker:
518522
"""
519523
return self._unpack(read_array_header)
520524

525+
@cython.critical_section
521526
def read_map_header(self):
522527
"""assuming the next object is a map, return its size n, such that the
523528
next n * 2 unpack() calls will iterate over its key-value pairs.
@@ -526,6 +531,7 @@ cdef class Unpacker:
526531
"""
527532
return self._unpack(read_map_header)
528533

534+
@cython.critical_section
529535
def tell(self):
530536
"""Returns the current position of the Unpacker in bytes, i.e., the
531537
number of bytes that were read from the input, also the starting
@@ -536,6 +542,7 @@ cdef class Unpacker:
536542
def __iter__(self):
537543
return self
538544

545+
@cython.critical_section
539546
def __next__(self):
540547
return self._unpack(unpack_construct, 1)
541548

0 commit comments

Comments
 (0)