Skip to main content

PyPersistent

A high-performance collection of persistent (immutable) data structures for Python, written in C++.

Features

  • Immutable: All operations return new collections, leaving originals unchanged
  • Structural Sharing: New versions share most structure (O(log n) changes instead of O(n) copies)
  • Fast: 3-5x faster than pyrsistent, with merge operations up to 176x faster
  • Thread-Safe: Immutability makes concurrent access safe without locks
  • Python 3.13+ Free-Threading Ready: Lock-free design with atomic reference counting for true parallelism
  • Memory Efficient: Structural sharing minimizes memory overhead
  • Dual Interface: Both functional (Clojure-style) and Pythonic APIs
  • Pickle Support: Native serialization for all data structures

Data Structures

PyPersistent provides five core persistent data structures:

PersistentDict

Unordered key-value map based on Hash Array Mapped Trie (HAMT).

  • Use for: General-purpose dictionary needs with immutability
  • Time complexity: O(log₃₂ n) ≈ 6 steps for 1M elements
  • Features: Fast lookups, structural sharing, bulk merge operations
  • Example:
    from pypersistent import PersistentDict
    
    m = PersistentDict.create(name='Alice', age=30)
    m2 = m.set('city', 'NYC')
    m3 = m | {'role': 'developer'}  # Merge
    

PersistentSortedDict

Sorted key-value map based on Left-Leaning Red-Black Tree.

  • Use for: Ordered data, range queries, min/max operations
  • Time complexity: O(log₂ n) for all operations
  • Features: Sorted iteration, range queries (subseq/rsubseq), first/last
  • Example:
    from pypersistent import PersistentSortedDict
    
    m = PersistentSortedDict.from_dict({3: 'c', 1: 'a', 2: 'b'})
    list(m.keys())  # [1, 2, 3] - always sorted
    
    # Range queries [start, end) - start inclusive, end exclusive
    sub = m.subseq(1, 3)  # or m[1:3]
    list(sub.keys())  # [1, 2]
    
    # Min/max
    m.first()  # (1, 'a')
    m.last()   # (3, 'c')
    

PersistentList

Indexed sequence based on bit-partitioned vector trie (RRB-Tree variant).

  • Use for: Ordered sequences with efficient random access and append
  • Time complexity: O(log₃₂ n) for get/set, O(1) for append
  • Features: Fast indexed access, efficient append, slicing
  • Example:
    from pypersistent import PersistentList
    
    v = PersistentList.create(1, 2, 3)
    v2 = v.conj(4)  # Append
    v3 = v2.assoc(0, 10)  # Update index 0
    v[1]  # 2 - indexed access
    

PersistentSet

Unordered set based on HAMT (same as PersistentDict).

  • Use for: Unique collection of items, set operations
  • Time complexity: O(log₃₂ n) for add/remove/contains
  • Features: Fast membership testing, set operations (union, intersection, difference)
  • Example:
    from pypersistent import PersistentSet
    
    s = PersistentSet.create(1, 2, 3)
    s2 = s.conj(4)  # Add
    s3 = s.disj(2)  # Remove
    2 in s  # True
    

PersistentArrayMap

Small map optimization using array of key-value pairs.

  • Use for: Maps with < 8 entries (automatic optimization)
  • Time complexity: O(n) linear scan, but faster than HAMT for tiny maps
  • Features: Lower memory overhead, faster for very small maps
  • Note: Typically used internally; PersistentDict automatically uses this for small maps

Choosing the Right Data Structure

Need Use Why
General key-value storage PersistentDict Fastest for unordered data
Sorted keys / range queries PersistentSortedDict Maintains sort order, supports ranges
Indexed sequence PersistentList Fast random access and append
Unique items / set operations PersistentSet Membership testing, set algebra
Very small dicts (< 8 items) PersistentArrayMap Lower overhead for tiny dicts

Performance

Why Use Persistent Data Structures?

The key advantage of persistent data structures is structural sharing: when you create a modified version, the new and old versions share most of their internal structure rather than duplicating everything.

Example:

# Python dict - must copy everything
d1 = {i: f'val{i}' for i in range(10000)}
d2 = d1.copy()  # Copies all 10,000 entries
d2['new_key'] = 'new_value'

# PersistentDict - shares structure
from pypersistent import PersistentDict
m1 = PersistentDict.from_dict({i: f'val{i}' for i in range(10000)})
m2 = m1.set('new_key', 'new_value')  # Shares 99.99% of structure with m1

When to Use pypersistent

✅ Use pypersistent when:

  • Creating multiple versions - Undo/redo, snapshots, version history
  • Concurrent access - Multiple threads safely reading shared data without locks
  • Functional programming - Immutable data flow, pure functions
  • Building up collections incrementally - Each addition shares structure with previous version

❌ Use standard Python dict/list when:

  • You only need one mutable version
  • Maximum raw construction speed is critical
  • Extremely memory-constrained environments

Performance vs Python Standard Library

PersistentDict vs dict

Operation pypersistent Python dict Speedup
Structural Sharing (100 variants of 10K dict) 74µs 1.79ms 24x faster 🚀
Structural Sharing (100 variants of 1M dict) 158µs 517ms 3271x faster 🚀
Single lookup 776µs (1K ops) 427µs 1.8x slower
Construction (1M elements) 2.74s 299ms 9x slower

Key insight: Creating multiple versions through structural sharing is 24-3271x faster than copying dicts, with the advantage growing dramatically for larger collections.

PersistentList vs list

Operation pypersistent Python list Speedup
Structural Sharing (100 variants of 10K list) 74µs 1.79ms 24x faster 🚀
Append 100 elements 42µs 2.3µs 18x slower
Random access (100 ops) 13µs 2.7µs 5x slower

Key insight: If you need multiple versions (undo, history), PersistentList is dramatically faster.

Performance vs pyrsistent

pyrsistent is a mature pure-Python library with similar persistent data structures. pypersistent offers better performance through its C++ implementation, but with a smaller feature set.

PersistentDict Performance Comparison

Size Operation pypersistent (C++) pyrsistent (Python) Speedup
100K Merge (50K+50K) 563µs 98.9ms 176x faster 🚀
10K Merge (5K+5K) 155µs 9.12ms 59x faster 🚀
10K Lookup (1K ops) 157µs 476µs 3.0x faster
10K Update (100 ops) 64µs 287µs 4.5x faster
10K Construction 811µs 1.95ms 2.4x faster
10K Iteration 1.27ms 732µs 1.7x slower

Why the difference? pypersistent's C++ implementation provides:

  • Optimized tree traversal and node allocation
  • Cache-friendly memory layout
  • Specialized bulk merge algorithms
  • Direct memory manipulation without Python object overhead

Feature Comparison

Feature pypersistent pyrsistent
PersistentDict (pmap) ✅ ✅
PersistentList (pvector) ✅ ✅
PersistentSet (pset) ✅ ✅
PersistentSortedDict ✅ ✅ (pbag)
PersistentArrayMap (small dicts) ✅ ❌
PersistentBag (multiset) ❌ ✅
PersistentDeque ❌ ✅
PersistentRecord/Class ❌ ✅
Evolvers (transient mutations) ❌ ✅
Freeze/thaw (deep conversion) ❌ ✅
Type checking integration ❌ ✅

Summary: Choose pypersistent for performance-critical applications with the core data structures. Choose pyrsistent for a richer feature set and pure-Python portability.

Performance by Map Size

Size Construction Lookup (1K ops) Sharing (100 variants)
100 73µs 19µs 77µs
1K 765µs 205µs 95µs
10K 9.7ms 228µs 108µs
100K 110ms 255µs 133µs
1M 2.74s 776ms 158µs

Fast Iteration Methods

For complete iteration over small-medium dicts, use materialized list methods:

m = PersistentDict.from_dict({...})

# Fast methods (1.7-3x faster for dicts < 100K)
items = m.items_list()   # Returns list of (key, value) tuples
keys = m.keys_list()     # Returns list of keys
values = m.values_list() # Returns list of values

# Lazy iterators (better for very large dicts or early exit)
for k, v in m.items():   # Generator, O(log n) memory
    ...

Performance:

  • Dicts ≤ 10K: 3x faster with items_list()
  • Dicts ≤ 100K: 1.7x faster with items_list()
  • Dicts > 100K: Use iterator (lazy, memory-efficient)

Technical Details

Implementation: C++ HAMT (Hash Array Mapped Trie) with:

  • Bottom-up bulk construction for from_dict()
  • Arena allocator for fast node allocation
  • Structural tree merging for merge()
  • COW semantics for collision nodes
  • Fast iteration with pre-allocated lists

Time Complexity: O(log₃₂ n) ≈ 6 steps for 1M elements Space Complexity: O(n) with structural sharing across versions

For detailed performance analysis and benchmarking methodology, see docs/.

Installation

pip install pypersistent

Or build from source:

git clone https://github.com/cmarschner/pypersistent.git
cd pypersistent
python setup.py install

Use Cases

Use persistent data structures when:

  • Creating multiple versions of data (undo/redo, time-travel, version history)
  • Sharing data across threads without locks or defensive copying
  • Functional programming patterns (immutability, pure functions)
  • Creating modified copies is frequent (structural sharing makes this fast)
  • Python 3.13+ free-threading for true parallelism

Use mutable collections when:

  • Single mutable instance is sufficient
  • Maximum raw construction speed is critical
  • Memory per entry is highly constrained

Specific use cases:

  • Config management: Share base config, each thread creates customized version
  • Event sourcing: Maintain history of all states efficiently
  • Reactive programming: Pass immutable state between components
  • Concurrent caching: Multiple threads read/update cache without locks
  • Functional data pipelines: Transform data through pipeline stages

How It Works

PyPersistent implements multiple classic persistent data structures:

PersistentDict - Hash Array Mapped Trie (HAMT)

Based on the HAMT data structure used by Clojure, Scala, and Haskell:

  • 32-way branching tree indexed by hash bits
  • Path copying for immutability
  • Structural sharing between versions
  • std::shared_ptr for entry sharing (44x fewer INCREF/DECREF)
  • Inline storage with std::variant for cache-friendly access

PersistentSortedDict - Left-Leaning Red-Black Tree

Self-balancing binary search tree with:

  • Path copying for immutability
  • Sorted order maintenance (O(log₂ n))
  • Atomic reference counting for node sharing
  • Range query support via tree traversal

PersistentList - Bit-Partitioned Trie

32-way branching tree for indexed access:

  • Path copying for updates
  • Tail optimization for fast append
  • O(log₃₂ n) random access (~6 steps for 1M elements)
  • Efficient slicing via structural sharing

PersistentSet - HAMT-based Set

Uses PersistentDict internally with:

  • Keys as set elements
  • Same O(log₃₂ n) complexity
  • Set algebra operations

PersistentArrayMap - Simple Array

Linear array for tiny dicts (< 8 entries):

  • Lower overhead than HAMT for small sizes
  • O(n) operations but faster than tree for n < 8
  • Automatically used by PersistentDict when beneficial

Technical Details

Complexity:

  • PersistentDict/HashSet: O(log₃₂ n) ≈ 6 steps for 1M elements
  • PersistentSortedDict: O(log₂ n) for all operations
  • PersistentList: O(log₃₂ n) get/set, O(1) append
  • PersistentArrayMap: O(n) but fast for n < 8

Implementation:

  • C++ with pybind11 bindings
  • Atomic reference counting (std::atomic<int>)
  • Structural sharing for memory efficiency
  • Thread-safe reads (fully immutable)

Python 3.13+ Free-Threading Support

PyPersistent is fully compatible with Python 3.13's experimental free-threading mode (nogil), making it ideal for parallel workloads:

Why It Works

  1. Lock-Free Reads: Immutable data structure allows concurrent reads without synchronization
  2. Atomic Reference Counting: Internal C++ reference counting uses std::atomic operations
  3. Thread-Safe Entry Storage: Uses std::shared_ptr with built-in thread-safe reference counting
  4. Independent Updates: Each thread can create new versions without blocking others

Usage with Free-Threading

# Python 3.13+ with --disable-gil or PYTHON_GIL=0
import threading
from pypersistent import PersistentDict

# Shared base dict
base_config = PersistentDict.create(
    api_url='https://api.example.com',
    timeout=30,
    retries=3
)

def process_request(thread_id, data):
    # Each thread creates its own version - no locks needed!
    my_config = base_config.set('thread_id', thread_id)
    my_config = my_config.set('request_data', data)

    # Concurrent reads are completely lock-free
    url = my_config['api_url']
    timeout = my_config['timeout']

    # Do work...
    return my_config

# Spawn threads - true parallelism without GIL!
threads = []
for i in range(100):
    t = threading.Thread(target=process_request, args=(i, f'data_{i}'))
    threads.append(t)
    t.start()

for t in threads:
    t.join()

Performance Benefits

Without the GIL:

  • Parallel reads: Multiple threads read simultaneously without contention
  • Parallel updates: Each thread creates new versions independently
  • No lock overhead: Zero synchronization cost for immutable operations
  • Structural sharing shines: Creating 100 thread-local variants is 3000x faster than copying dicts

Enable Free-Threading

# Python 3.13+
python3.13 --disable-gil your_script.py

# Or set environment variable
export PYTHON_GIL=0
python3.13 your_script.py

Note: Free-threading is experimental in Python 3.13. Some packages may not be compatible yet.

Development

# Install development dependencies
pip install pytest pybind11

# Build extension
python setup.py build_ext --inplace

# Run all tests
pytest -v

# Run specific data structure tests
pytest test_persistent_dict.py -v
pytest test_persistent_sorted_dict.py -v
pytest test_persistent_list.py -v
pytest test_persistent_set.py -v

# Run performance benchmarks
python performance_test.py
python performance_vector.py

License

MIT License - see LICENSE file for details

Credits

Inspired by Clojure's persistent data structures and the HAMT paper by Bagwell (2001).

Implementation by Clemens Marschner.

Metadata

Release files for pypersistent 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pypersistent 2.0.0
File Size Uploaded Provenance Actions
pypersistent-2.0.0.tar.gz 66.2 kB With provenance Details for pypersistent-2.0.0.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for pypersistent 2.0.0
File Actions
pypersistent-2.0.0-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details for pypersistent-2.0.0-cp312-cp312-win_amd64.whl
pypersistent-2.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details for pypersistent-2.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
pypersistent-2.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ ARM64, Linux glibc 2.27+ ARM64 Details for pypersistent-2.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
pypersistent-2.0.0-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details for pypersistent-2.0.0-cp312-cp312-macosx_11_0_arm64.whl
pypersistent-2.0.0-cp312-cp312-macosx_10_9_x86_64.whl CPython 3.12 CPython 3.12 macOS 10.9+ x86-64 Details for pypersistent-2.0.0-cp312-cp312-macosx_10_9_x86_64.whl
pypersistent-2.0.0-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details for pypersistent-2.0.0-cp311-cp311-win_amd64.whl
pypersistent-2.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details for pypersistent-2.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
pypersistent-2.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl CPython 3.11 CPython 3.11 Linux glibc 2.27+ ARM64, Linux glibc 2.28+ ARM64 Details for pypersistent-2.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
pypersistent-2.0.0-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details for pypersistent-2.0.0-cp311-cp311-macosx_11_0_arm64.whl
pypersistent-2.0.0-cp311-cp311-macosx_10_9_x86_64.whl CPython 3.11 CPython 3.11 macOS 10.9+ x86-64 Details for pypersistent-2.0.0-cp311-cp311-macosx_10_9_x86_64.whl
pypersistent-2.0.0-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details for pypersistent-2.0.0-cp310-cp310-win_amd64.whl
pypersistent-2.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details for pypersistent-2.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
pypersistent-2.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl CPython 3.10 CPython 3.10 Linux glibc 2.27+ ARM64, Linux glibc 2.28+ ARM64 Details for pypersistent-2.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
pypersistent-2.0.0-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details for pypersistent-2.0.0-cp310-cp310-macosx_11_0_arm64.whl
pypersistent-2.0.0-cp310-cp310-macosx_10_9_x86_64.whl CPython 3.10 CPython 3.10 macOS 10.9+ x86-64 Details for pypersistent-2.0.0-cp310-cp310-macosx_10_9_x86_64.whl

Total release size: 3.8 MB

Release files / pypersistent-2.0.0.tar.gz

Download URL pypersistent-2.0.0.tar.gz
Size 66.2 kB
Tags Source
SHA-256 checksum
How to use checksums
960625885606d6bb0cca0d5787c24e1e6ebfccec2ee77f1122bf2ffef0595bf7
BLAKE2b-256 checksum
How to use checksums
93127da2f8d611027467da21c1d22be1d87a957a5aaef4d50abc9ae283e29d0a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp312-cp312-win_amd64.whl

Download URL pypersistent-2.0.0-cp312-cp312-win_amd64.whl
Size 181.5 kB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
2e36c833d61a462121ccdb86bd53592d8acd6a7032c302cf99d9e76569ef63eb
BLAKE2b-256 checksum
How to use checksums
1f6d2b53715b97db60f1e01d3ccb73f93ffa21f6cb21c871dba6b1421a2cdf0e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL pypersistent-2.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 285.8 kB
Tags CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
59308f8d4e3f264834b357c8f29a845a65a4bcdc4c9482783c52a5ccb5e3b80d
BLAKE2b-256 checksum
How to use checksums
6c241919f3d55cb0f56bf53bab7b3fcd1b68f3ba72bbf07878fdbb00b6c267a0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

Download URL pypersistent-2.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Size 263.4 kB
Tags CPython 3.12 Linux glibc 2.27+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
adeeb2f135e3a8f259c5ded28e36430ba8a7a1a89309dadd854a327d09c53711
BLAKE2b-256 checksum
How to use checksums
7612a89947cb0c747198ec95a9ff1422d47f058a5388c112391b3ae423c3e01a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp312-cp312-macosx_11_0_arm64.whl

Download URL pypersistent-2.0.0-cp312-cp312-macosx_11_0_arm64.whl
Size 249.8 kB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c048e6694129f713ac7e6bf25b3d64836afefeba0d5190e22a98a98ddd7d54ae
BLAKE2b-256 checksum
How to use checksums
deb20b40971f349af3de36d7c0fa345e58872d0317cbf277a1e7da81c501d72b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp312-cp312-macosx_10_9_x86_64.whl

Download URL pypersistent-2.0.0-cp312-cp312-macosx_10_9_x86_64.whl
Size 260.3 kB
Tags CPython 3.12 macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
736f1ea4406fd7a30ae03ccc808c9a5b487a17a81255249d8b7dfaff158a400d
BLAKE2b-256 checksum
How to use checksums
c086bed3d86a202c8874dceb7c3c1a9ad7c5c2a3238225725ab71e3726a63c0e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp311-cp311-win_amd64.whl

Download URL pypersistent-2.0.0-cp311-cp311-win_amd64.whl
Size 181.2 kB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
ccafe204da4290175df221a0756bfea051f2c07bd413cc1ad835e7a932c7e1a9
BLAKE2b-256 checksum
How to use checksums
387fb30fdd5c0be5162198d9d96dc9c96a2c29a3c8c432defecdda6a65ead482
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL pypersistent-2.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 288.1 kB
Tags CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
6478a04de8731a7939accb9f184ad787e215f9b95529f78d8ebf6901385294f4
BLAKE2b-256 checksum
How to use checksums
864f3e3483ebddfe0f82f2e1f76537538944bc295ecd64f6571450681d037c6d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

Download URL pypersistent-2.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Size 267.8 kB
Tags CPython 3.11 Linux glibc 2.27+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
253706cded60e484a7a6f34d001b8a4a5599e8c810d41d2b3760673c8c424c41
BLAKE2b-256 checksum
How to use checksums
41d6aea19f7385a7fc145a29f44b43546c8a42e2524c7da6f2ff0babf82c2c60
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp311-cp311-macosx_11_0_arm64.whl

Download URL pypersistent-2.0.0-cp311-cp311-macosx_11_0_arm64.whl
Size 248.7 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
b71e446cdc1aa59cab0883f2d411b78a0a1ce20d80e9787ecf480e478dfdb0c0
BLAKE2b-256 checksum
How to use checksums
6265372862d31512e70e3ecda52ca4dcf7f3c71abcc35f431eb003f4a5cf07a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp311-cp311-macosx_10_9_x86_64.whl

Download URL pypersistent-2.0.0-cp311-cp311-macosx_10_9_x86_64.whl
Size 256.3 kB
Tags CPython 3.11 macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
f81ce84fd1134e852d9346c81990ccb0972a2f3dd10900e77f64eaab958b72aa
BLAKE2b-256 checksum
How to use checksums
0ed0253ad298ba034d55e9fdb39f61e8e54a84bfc5f6136558bebb9822d3b9b3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp310-cp310-win_amd64.whl

Download URL pypersistent-2.0.0-cp310-cp310-win_amd64.whl
Size 180.7 kB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
8955d4da367488d3c544c1657d92eef7b03fbe4c17df58c27976e86a6fb30f39
BLAKE2b-256 checksum
How to use checksums
8aeb0b48b6ec1001a5e755a5462df4815b20a4b036bbc5e87c7b09c64fcc6e6c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL pypersistent-2.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 286.1 kB
Tags CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
b80562fea665cb55986852296dc24b4df6b6704dee1c33a20d494b611896e23c
BLAKE2b-256 checksum
How to use checksums
37f37d6cd4a8adf96a949cbaa73bb2632045fcda45818931037c5a6d809451bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl

Download URL pypersistent-2.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Size 265.0 kB
Tags CPython 3.10 Linux glibc 2.27+ ARM64 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
ffb8abd20362a6c5eb995445c99d6fa6c853de03522e9a20cdeee09a9a1b26b6
BLAKE2b-256 checksum
How to use checksums
90108f73e495703f3bc2066c07aa592e5ef9018a99d318b4d3a69a76183129a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp310-cp310-macosx_11_0_arm64.whl

Download URL pypersistent-2.0.0-cp310-cp310-macosx_11_0_arm64.whl
Size 248.1 kB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
14d651ed97272993a7c1702993d992de9cf6790ca3150f4fec2c309ef6d50be9
BLAKE2b-256 checksum
How to use checksums
ef42ebecfdb432f8d9e3c1fa124160465c40395beec838f46e54f6d12a9d46cc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Release files / pypersistent-2.0.0-cp310-cp310-macosx_10_9_x86_64.whl

Download URL pypersistent-2.0.0-cp310-cp310-macosx_10_9_x86_64.whl
Size 255.2 kB
Tags CPython 3.10 macOS 10.9+ x86-64
SHA-256 checksum
How to use checksums
589490918d76551bd7b6701be69911b1ac89bc92e39154d57ecd89d6735b731b
BLAKE2b-256 checksum
How to use checksums
6660d5b6badca43ba641e3b0d9d2b4e7f2c7c852a164b9b6ec0bcf91df155a04
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

Security for pypersistent 2.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 16 files in this release have been uploaded with provenance metadata.

Select from 16 files

Attestation for pypersistent-2.0.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 16, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page