Skip to main content

High-performance persistent (immutable) hash map for Python

Project description

PyPersistent

A high-performance persistent (immutable) hash map implementation for Python, written in C++.

Features

  • Immutable: All operations return new maps, leaving originals unchanged
  • Structural Sharing: New versions share most structure with old versions (O(log n) copies instead of O(n))
  • Fast: 38% faster than pure Python implementation for insertions, ~10x slower than mutable dict
  • 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

Performance

Quick Summary

pypersistent provides 6-8% faster bulk operations compared to baseline and is 3-150x faster than pure Python pyrsistent for most operations. The real value is structural sharing: creating variants is 3000x faster than copying dicts.

Benchmark Results

vs Python dict (1M elements)

Operation pypersistent dict Notes
Construction 2.74s 299ms 9x slower (immutability cost)
Lookup (1K ops) 776ms 427ms 1.8x slower
Update (single) 147µs ~80ns Comparable for single ops
Structural Sharing (100 variants) 0.48ms 1.57s 3000x FASTER

Key insight: For creating multiple versions, pypersistent is orders of magnitude faster.

vs pyrsistent (pure Python) - Apples-to-Apples

Size Operation pypersistent pyrsistent Speedup
1M Merge (500K+500K) 11.5ms 1.60s 139x faster
1M Construction 185ms 813ms 4.4x faster
1M Lookup (1M ops) 726ms 796ms 1.1x faster
1M Iteration 452ms 167ms 2.7x slower
1K Merge (500+500) 8.7µs 1.22ms 141x faster
1K Construction 76µs 192µs 2.5x faster
100 Merge (50+50) 17.8µs 120µs 6.7x faster
100 Construction 30µs 18.5µs 1.6x slower

Iteration note: Using items_list() instead of items() makes iteration 1.7-3x faster for maps < 100K

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 maps, use materialized list methods:

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

# Fast methods (1.7-3x faster for maps < 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 maps or early exit)
for k, v in m.items():   # Generator, O(log n) memory
    ...

Performance:

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

When to Use pypersistent

Use pypersistent when:

  • Creating multiple versions of data (undo/redo, time-travel)
  • Concurrent access across threads (lock-free reads)
  • Functional programming patterns
  • Merging large maps frequently

Use dict when:

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

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

Usage

Functional Style (Clojure-inspired)

from pypersistent import PersistentMap

# Create empty map
m = PersistentMap()

# Add entries (returns new map)
m2 = m.assoc('name', 'Alice').assoc('age', 30)

# Remove entries
m3 = m2.dissoc('age')

# Get values
name = m2.get('name')  # 'Alice'
age = m2.get('age', 0)  # 30

# Check membership
'name' in m2  # True

# Original unchanged
len(m)   # 0
len(m2)  # 2

Pythonic Style

from pypersistent import PersistentMap

# Create from dict or kwargs
m = PersistentMap.create(name='Alice', age=30)
m = PersistentMap.from_dict({'name': 'Alice', 'age': 30})

# Dict-like operations (but returns new map!)
m2 = m.set('city', 'NYC')
m3 = m.delete('age')
m4 = m.update({'height': 165, 'weight': 60})
m5 = m | {'extra': 'data'}  # Merge operator

# Access like dict
name = m['name']  # Raises KeyError if not found
name = m.get('name', 'default')  # With default

# Iterate
for key in m:
    print(key, m[key])

for key, value in m.items():
    print(key, value)

Complete API

Core operations (functional style):

  • assoc(key, val) - Add/update key
  • dissoc(key) - Remove key
  • get(key, default=None) - Get value
  • contains(key) - Check membership

Pythonic aliases:

  • set(key, val) - Alias for assoc
  • delete(key) - Alias for dissoc
  • update(mapping) - Bulk merge
  • merge(mapping) - Alias for update
  • m1 | m2 - Merge operator
  • clear() - Empty map
  • copy() - Returns self (immutable)

Standard dict protocol:

  • m[key] - Get item (raises KeyError)
  • key in m - Membership test
  • len(m) - Size
  • for k in m - Iterate keys
  • keys(), values(), items() - Iterators
  • ==, != - Equality

Use Cases

PersistentMap is ideal when you need:

  • Multiple versions of data: Undo/redo, time-travel debugging, version history
  • Concurrent access: Share data across threads without locks or defensive copying
  • Functional programming: Natural fit for immutable data structures
  • Copy-on-write semantics: When creating modified copies is common

Use regular dict when:

  • You only need one mutable map
  • Maximum raw performance is critical
  • Memory per entry is a constraint

How It Works

PyPersistent implements a Hash Array Mapped Trie (HAMT), the data structure used by:

  • Clojure's persistent maps
  • Scala's immutable maps
  • Haskell's Data.HashMap

Key innovations in this implementation:

  1. Entry sharing with shared_ptr: Entries are shared between map versions using shared pointers, reducing INCREF/DECREF operations by 44x
  2. Inline storage with std::variant: Entries stored by value in node arrays for cache-friendly access
  3. O(log n) memory iteration: Tree-walking iterator uses O(log n) stack space instead of materializing all entries

Technical Details

  • Time Complexity: O(log₃₂ n) for all operations (~6 steps for 1M elements)
  • Space Complexity: O(n) with structural sharing across versions
  • Implementation: C++ with pybind11 bindings
  • Thread Safety: Fully thread-safe for reading (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 PersistentMap

# Shared base map
base_config = PersistentMap.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 tests
pytest test_pypersistent.py -v

# Run performance benchmarks
python performance_test.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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pypersistent-1.0.0.tar.gz (31.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pypersistent-1.0.0-cp312-cp312-win_amd64.whl (117.6 kB view details)

Uploaded CPython 3.12Windows x86-64

pypersistent-1.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (159.1 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pypersistent-1.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (150.3 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

pypersistent-1.0.0-cp312-cp312-macosx_11_0_arm64.whl (133.9 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

pypersistent-1.0.0-cp312-cp312-macosx_10_9_x86_64.whl (141.0 kB view details)

Uploaded CPython 3.12macOS 10.9+ x86-64

pypersistent-1.0.0-cp311-cp311-win_amd64.whl (116.9 kB view details)

Uploaded CPython 3.11Windows x86-64

pypersistent-1.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (158.2 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pypersistent-1.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (149.6 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

pypersistent-1.0.0-cp311-cp311-macosx_11_0_arm64.whl (132.9 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

pypersistent-1.0.0-cp311-cp311-macosx_10_9_x86_64.whl (138.9 kB view details)

Uploaded CPython 3.11macOS 10.9+ x86-64

pypersistent-1.0.0-cp310-cp310-win_amd64.whl (116.1 kB view details)

Uploaded CPython 3.10Windows x86-64

pypersistent-1.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (156.9 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

pypersistent-1.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl (147.5 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ ARM64manylinux: glibc 2.28+ ARM64

pypersistent-1.0.0-cp310-cp310-macosx_11_0_arm64.whl (131.6 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

pypersistent-1.0.0-cp310-cp310-macosx_10_9_x86_64.whl (137.3 kB view details)

Uploaded CPython 3.10macOS 10.9+ x86-64

File details

Details for the file pypersistent-1.0.0.tar.gz.

File metadata

  • Download URL: pypersistent-1.0.0.tar.gz
  • Upload date:
  • Size: 31.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pypersistent-1.0.0.tar.gz
Algorithm Hash digest
SHA256 afc2e9643ba7edc536236becdefa468e03539684d293182928a91ed3745b5b91
MD5 77ae6df0c677f2990f0b17b78f4e2fd6
BLAKE2b-256 823d90b9a499baa5cff158be01f63ef19eb5a8b7f7aa43393893c960c00dd59a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0.tar.gz:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 6fdfdd63794d75a345cb74fd9c95855949ff0890eac7d400d709d9ae9ac74638
MD5 3483cb4f7deb3c250a64e746b755a72c
BLAKE2b-256 0a494193fbf506ec3eb824ce73e5fdde7505b254fefc03e72e844265f996ff2e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp312-cp312-win_amd64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 eb37cc261cdeb3595c35b8dc626303fbb94191beb5e5e2733de5915ff5295603
MD5 add0b717a34ba1086f6da13c480a7052
BLAKE2b-256 f57e637cee4abf992d15d683c7fe0f3b62bee2643a53336207bcb029e0d66528

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 403f9f55dbe6816de9218e770205d285b86f99bb21de7139ba97cf88bf8a74cd
MD5 2302e77a5f8f06526e1348385ac91c8c
BLAKE2b-256 e55d1565cf200285359a2f8c3fb97891eee8b8dbbbcb4e26ab2952b0e1390917

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 74db1e537e9de1626af1b9f22cff1b6c181193907b8c136cdc36ef84be5bdb55
MD5 974002e9f58742d5cb6234af2cd7c21d
BLAKE2b-256 522fe967b04411c463fbd87fb9db9e2800e41570f966e487e930dbc3b181ee26

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp312-cp312-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp312-cp312-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 ef3ca1aa658bc2cfd88d878f03e58f26299efe06936d198eacdba98242177116
MD5 118856606b44bb3685a2002a80f81b53
BLAKE2b-256 c577bb890062726903b79c738b0f821a014690f14e7be6cf62be3004b9ac4d81

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp312-cp312-macosx_10_9_x86_64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 d7d128e98e1cf7251daeabf2bfc6cb50ea50dbafe33e17890c4bbf58e9bdf5f2
MD5 c504eb5b37954abb58baf08a82a03df9
BLAKE2b-256 cb427e7b532f447bed212c75707efee91fe910bba1227abe28c8561828a6024b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp311-cp311-win_amd64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c3a61ecd2c34b1de9f7785ba692d6557bf14d861396e7b8da750855191e4240f
MD5 a5e8898624c06572b92185fc6c61a0a5
BLAKE2b-256 a07fec0f215f1c55ce028f5a13ca988eeb52ba880fbe59e6366eccc5e2ff41c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 dd977b5bad015308a308e08e728c06e167e38cc2072146a914ee023ac37b67b2
MD5 9cef3fbee58d5c2df7d414e57b9a4485
BLAKE2b-256 e5466ed047aeb67bc8a1a205eeac5742e0e12a6fd5e643987095a12f9a88193d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fb2248835610f60bef13e2861bf9c8cbcce1e10f6facb1c505a9e9b2620b4dc9
MD5 6ec1814e0646d6422db861bfbf9c05bb
BLAKE2b-256 2d22b16f77827383447acdfc49464f27e67838b3377f9fd0420075cd19db8dc5

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 c390d28b0348a703f1ac1e9c58583d533fe101744f65d42d5ec227db4f531097
MD5 a0775987853f697e3fba98993a89844d
BLAKE2b-256 cdfd0d1abc933343ef089ac4ba3154a21146a977248a3e2d14d54b21352870d5

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp311-cp311-macosx_10_9_x86_64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 e333c63418fe91eb36872e22ad910b4fc9b011ccd39d36a90a13923d53f17237
MD5 256ceca0ba0815310d04085c1d3c3fbb
BLAKE2b-256 0134f6d64ce4466aada4493be135024f8d9a7e591f8fb1ae992538060889c9be

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp310-cp310-win_amd64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 85f022bb54aeb26ac06c075614b19fee211748e591856c9966df0aeefbb50acb
MD5 0c974c22fbd2c3c65820644a7063e1b2
BLAKE2b-256 d01c7612574509c96b7efe5e3e85b634396256c5a84143dd7a07c7b6d5c0d3fb

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c491357afa89e34eefa5a1800e253681796bfafcfb3f0d5ffafea41e601f9325
MD5 4768ddf3a36ed36f95a49ac4a95ba2b5
BLAKE2b-256 d98e4bef6ed9735cba73406ccd10223099aadf3c8604a5cb3945f6158bb18d90

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 df36a1036945d33e42307c386cc943bcbf0de8ed51d2cf507c78ff67a77311ac
MD5 35f620fa7853ebeaf4091d47f6aa0c06
BLAKE2b-256 45e11042e8797fd5eb19d01a12324c112546c16eeea5d4747277202ea85f84cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pypersistent-1.0.0-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for pypersistent-1.0.0-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 a15ee0fd8e8a9b43a250fd4034b22a178f36b5c0fcbbf8bf21baa5904e1da0aa
MD5 ff4c5d6560257eafcc4bee558ab109ae
BLAKE2b-256 0c57b8c9a7753c59b679046cd936d97c87b7e4c4986f4f9efe35b239d5cd632b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypersistent-1.0.0-cp310-cp310-macosx_10_9_x86_64.whl:

Publisher: build-wheels.yml on cmarschner/pypersistent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page