Skip to content

Releases: simplejson/simplejson

v4.1.1

24 Apr 18:53
639b2ee

Choose a tag to compare

What's Changed

  • Add Python 2.7 wheel builds for Windows platforms by @etrepum in #378

Full Changelog: v4.1.0...v4.1.1

v4.1.0

22 Apr 19:55
0fd3185

Choose a tag to compare

What's Changed

  • Accelerate indented encoding in the C extension; release 4.1.0 by @etrepum in #376

Full Changelog: v4.0.1...v4.1.0

v4.0.1

18 Apr 22:16
19b5f94

Choose a tag to compare

What's Changed

  • Exclude Pyodide wheels from PyPI uploads by @etrepum in #375

Full Changelog: v4.0.0...v4.0.1

v4.0.0

18 Apr 18:40
1608c05

Choose a tag to compare

What's Changed

Version 4.0.0 released 2026-04-18

  • simplejson 4 requires Python 2.7 or Python 3.8+. Older Python
    versions (2.5, 2.6, 3.0-3.7) are no longer supported. pip will
    not install simplejson 4 on unsupported versions.

  • The C extension now uses heap types and per-module state instead of
    static types and global state. This is required for free-threading
    support and sub-interpreter isolation. The Python-level API is
    unchanged.

  • Full support for Python 3.13+ free-threading (PEP 703). The C
    extension is now safe to use with the GIL disabled (python3.14t):

    • Converted all static types to heap types with per-module state
    • Added per-object critical sections to scanner and encoder
    • Added free-threading-safe dict operations for Python 3.13+
    • Unified per-module state management and templated parser
      #363
      #364
      #365
      #367
      #369
  • Numerous C extension memory safety fixes:

    • Fix use-after-free and leak in encoder ident handling
    • Fix NULL dereferences on OOM in module init and static string init
    • Fix reference leaks in dict encoder (skipkeys item, variable shadowing)
    • Fix member table copy-paste, exception clobbering, missing Py_VISIT
    • Fix error-as-truthy bugs in maybe_quote_bigint and is_raw_json
    • Fix iterable_as_array swallowing MemoryError and KeyboardInterrupt
    • Fix for_json and _asdict swallowing MemoryError, KeyboardInterrupt,
      and other non-AttributeError exceptions raised by user getattr
      #355
      #356
      #357
      #358
      #359
      #360
      #373
  • C/Python parity fixes:

    • Fix C scanstring off-by-one bounds checks that caused truncated
      or boundary \uXXXX escapes to raise "Invalid \uXXXX escape
      sequence" instead of "Unterminated string", and report error
      position at the 'u' instead of the leading backslash. The C and
      Python decoders now agree on exception class, message, and
      position across all tested edge cases.
    • Align the Python encoder's dispatch order with the C encoder for
      objects that define _asdict(). Previously a list/tuple/dict
      subclass with an _asdict() method encoded as its container type
      under the Python encoder and as the _asdict() return value under
      the C encoder; both now check _asdict() before list/tuple/dict.
      for_json() continues to outrank _asdict() in both.
    • Fix C scanstring raising a plain ValueError ("end is out of
      bounds") instead of JSONDecodeError for out-of-range end indices.
      User code with except JSONDecodeError: now catches both the
      C and pure-Python paths consistently.
      #372
  • C extension performance and correctness improvements:

    • Add PyDict_Next fast path for unsorted exact-dict encoding,
      avoiding intermediate items list and N tuple allocations
    • Add indexed fast path for exact list/tuple encoding, avoiding
      iterator allocation and per-item PyIter_Next overhead
    • Use PyUnicodeWriter as JSON_Accu backend on Python 3.14+,
      eliminating intermediate string objects and ''.join calls
    • Fix integer overflow in ascii_escape output_size calculation
      that could cause buffer overwrite on pathologically large strings
    • Fix list encoder separator counter overflow (int to Py_ssize_t)
    • Dead code cleanup (unreachable NULL checks, do-while wrappers)
      #370
  • Added Python 3.14 support and updated to cibuildwheel 3.2.1. CI now
    tests free-threaded (3.14t) and debug builds with -Werror, refcount
    leak detection, and GIL-disabled mode.
    #343

  • Added a ThreadSanitizer (TSan) stress test CI job. Builds a
    TSan-instrumented free-threaded CPython (cached between runs) and
    runs a concurrent stress test script against the C extension to
    catch data races under free-threading.
    #373

  • Replace deprecated license classifiers with SPDX license expression
    #347

  • Documented RawJSON usage with examples and caveats
    #346

  • Added pyproject.toml for PEP 517 build support. setup.py is retained
    for Python 2.7 wheel builds and backwards compatibility.

  • Migrated build_ext import from distutils to setuptools in setup.py.
    The distutils.errors imports are kept since setuptools vendors
    distutils on Python 3.12+ where stdlib distutils was removed.

  • CI now tests PEP 517 builds (pyproject.toml) alongside the existing
    setup.py-based builds.

  • Added Pyodide (wasm32) wheel builds with C speedups via cibuildwheel.
    Previously Pyodide users fell back to the pure-Python wheel; now they
    get the compiled C extension cross-compiled to WebAssembly. Thread
    and subprocess tests are skipped on Emscripten where those APIs are
    unavailable.

  • Test suite now fails (instead of skipping) when C speedups are missing
    during cibuildwheel runs, catching broken extension builds early.

  • New array_hook parameter for loads(), load(), and
    JSONDecoder. Called with each decoded JSON array (as a list),
    its return value replaces the list. Analogous to object_hook
    for dicts. Works with both the Python decoder and C scanner.
    (Matches CPython 3.15 json module.)

  • Trailing comma detection: the decoder now raises JSONDecodeError
    with "Illegal trailing comma before end of object/array" for inputs
    like [1,] and {"a": 1,} instead of generic error messages.
    Both the Python decoder and C scanner are updated.
    (Matches CPython 3.13+ json module.)

  • frozendict encoding support: when frozendict is available
    (CPython 3.15+ PEP 814), it is encoded as a JSON object just like
    dict. No effect on older Python versions.

  • Serialization errors now include add_note() context on Python
    3.11+ (PEP 678), annotating exceptions with the path to the error,
    e.g. "when serializing list item 1" / "when serializing dict item
    'key'". Only applies to the Python encoder.

  • New C fast path for encode_basestring (ensure_ascii=False).
    Previously the non-ASCII string encoder fell back to pure Python;
    now it has a C implementation matching the existing
    encode_basestring_ascii fast path.
    #207

  • The Python decoder now rejects non-ASCII digits (e.g. fullwidth
    \uff10) in JSON numbers, matching the C scanner behavior.
    The NUMBER_RE regex was changed from \d to [0-9].

  • Removed dead single-phase init code for Python 3.3/3.4 from the
    C extension (these versions are no longer supported).

New Contributors

Full Changelog: v3.20.2...v4.0.0

v3.20.2

26 Sep 15:33
10e5aaf

Choose a tag to compare

What's Changed

  • Add a test for the min and max floats by @etrepum in #337
  • Disable speedups on GraalPy same as on PyPy by @timfel in #339
  • Update changelog and version for v3.20.2 by @etrepum in #340

New Contributors

Full Changelog: v3.20.1...v3.20.2

v3.20.1

15 Feb 04:23
390e633

Choose a tag to compare

Version 3.20.1 released 2025-02-14

  • Do not memoize keys before they are coerced to string
    #329

Full Changelog: v3.19.3...v3.20.1

v3.20.0

15 Feb 01:37
d08eeaf

Choose a tag to compare

Version 3.20.0 released 2025-02-14

  • Do not memoize keys before they are coerced to string
    #329

Full Changelog: v3.19.3...v3.20.0

v3.19.3

14 Aug 14:27
6932004

Choose a tag to compare

Version 3.19.3 released 2024-08-14

  • Updated test & build matrix to include Python 3.13.
    Dropped wheel support for Python 2.7 on macOS.
    #326

v3.19.2

05 Oct 23:39
532f41f

Choose a tag to compare

Version 3.19.2 released 2023-10-05

  • Updated test & build matrix to include Python 3.12 and use
    GitHub Actions as a Trusted Publisher (OIDC)
    #317

v3.19.1

06 Apr 19:02

Choose a tag to compare

Version 3.19.1 released 2023-04-06

  • This release contains security hardening measures based on recommendations
    by a security audit sponsored by OSTIF and conducted by X41 D-Sec GmbH.
    Several of these measures include changing defaults to be more strict,
    by default simplejson will now only consume and produce compliant JSON,
    but the flags still exist for any backwards compatibility needs.
    No high priority issues were discovered, the reference count
    leak is thought to be unreachable since the digits of the float are
    checked before PyOS_string_to_double is called.
    A link to the public version of this report will be included in a
    future release of simplejson. The following fixes were implemented in
    one PR: #313
  • Fix invalid handling of unicode escape sequences in the pure Python
    implementation of the decoder (SJ-PT-23-01)
  • Fix missing reference count decrease if PyOS_string_to_double raises
    an exception in Python 2.x; was probably unreachable (SJ-PT-23-02)
  • Backport the integer string length limitation from Python 3.11 to
    limit quadratic number parsing (SJ-PT-23-03)
  • Fix inconsistencies with error messages between the C and Python
    implementations (SJ-PT-23-100)
  • Remove unused unichr import from encoder (SJ-PT-23-101)
  • Remove unused namedtuple_as_object and tuple_as_array arguments from
    simplejson.load (SJ-PT-23-102)
  • Remove vestigial _one_shot code from iterencode (SJ-PT-23-103)
  • Change default of allow_nan from True to False and add allow_nan
    to decoder (SJ-PT-23-107)