Skip to main content

atomics2

This is a maintained fork of doodspav/atomics (unmaintained since its 1.0.3 release), published on PyPI as atomics2. It updates the wrapped C library to patomic v1.1.0, fixes several bugs, adds a test suite, and supports Python 3.11 - 3.14. The Python API is unchanged apart from the import name.

This library implements a wrapper around the lower level patomic C library (which is provided as part of this library through the build_patomic command in setup.py).

It exposes hardware level lock-free (and address-free) atomic operations on a memory buffer, either internally allocated or externally provided, via a set of atomic classes.

The operations in these classes are both thread-safe and process-safe, meaning that they can be used on a shared memory buffer for interprocess communication (including with other languages such as C/C++).

Table of Contents

Installing

Linux/MacOS:

$ python3 -m pip install atomics2

Windows:

$ py -m pip install atomics2

This library requires Python3.11+, and has a dependency on the cffi library. While the code here has no dependency on any implementation specific features, the cffi library functions used are likely to not work outside of CPython and PyPy.

Binaries are provided for the following platforms:

  • Windows [x86, amd64, arm64]
  • MacOSX [x86_64, arm64, universal2]
  • Linux [i686, x86_64, aarch64, ppc64le, s390x] [manylinux2014, musllinux_1_2]
  • Linux [i686, x86_64] [manylinux1]

If you are on one of these platforms and pip tries to build from source or fails to install, make sure that you have the latest version of pip installed. This can be done like so:

Linux/MacOS:

$ python3 -m pip install --upgrade pip

Windows:

$ py -m pip install --upgrade pip

If you need to build from source, check out the Building section as there are additional requirements for that.

Examples

Incorrect

The following example has a data race (ais modified from multiple threads). The program is not correct, and a's value will not equal total at the end.

from threading import Thread


a = 0


def fn(n: int) -> None:
    global a
    for _ in range(n):
        a += 1


if __name__ == "__main__":
    # setup
    total = 10_000_000
    # run threads to completion
    t1 = Thread(target=fn, args=(total // 2,))
    t2 = Thread(target=fn, args=(total // 2,))
    t1.start(), t2.start()
    t1.join(), t2.join()
    # print results
    print(f"a[{a}] != total[{total}]")

Multi-Threading

This example implements the previous example but a is now an AtomicInt which can be safely modified from multiple threads (as opposed to int which can't). The program is correct, and a will equal total at the end.

import atomics2
from threading import Thread


def fn(ai: atomics2.INTEGRAL, n: int) -> None:
    for _ in range(n):
        ai.inc()


if __name__ == "__main__":
    # setup
    a = atomics2.atomic(width=4, atype=atomics2.INT)
    total = 10_000
    # run threads to completion
    t1 = Thread(target=fn, args=(a, total // 2))
    t2 = Thread(target=fn, args=(a, total // 2))
    t1.start(), t2.start()
    t1.join(), t2.join()
    # print results
    print(f"a[{a.load()}] == total[{total}]")

Multi-Processing

This example is the counterpart to the above correct code, but using processes to demonstrate that atomic operations are also safe across processes. This program is also correct, and a will equal total at the end. It is also how one might communicate with processes written in other languages such as C/C++.

import atomics2
from multiprocessing import Process, shared_memory


def fn(shmem_name: str, width: int, n: int) -> None:
    shmem = shared_memory.SharedMemory(name=shmem_name)
    buf = shmem.buf[:width]
    with atomics2.atomicview(buffer=buf, atype=atomics2.INT) as a:
        for _ in range(n):
            a.inc()
    del buf
    shmem.close()


if __name__ == "__main__":
    # setup
    width = 4
    shmem = shared_memory.SharedMemory(create=True, size=width)
    buf = shmem.buf[:width]
    total = 10_000
    # run processes to completion
    p1 = Process(target=fn, args=(shmem.name, width, total // 2))
    p2 = Process(target=fn, args=(shmem.name, width, total // 2))
    p1.start(), p2.start()
    p1.join(), p2.join()
    # print results and cleanup
    with atomics2.atomicview(buffer=buf, atype=atomics2.INT) as a:
        print(f"a[{a.load()}] == total[{total}]")
    del buf
    shmem.close()
    shmem.unlink()

NOTE: Although shared_memory is showcased here, atomicview accepts any type that supports the buffer protocol as its buffer argument, so other sources of shared memory such as mmap could be used instead.

Docs

Types

The following helper (abstract-ish base) types are available in atomics2:

  • [ANY, INTEGRAL, BYTES, INT, UINT]

This library provides the following Atomic classes in atomics2.base:

  • Atomic --- ANY
  • AtomicIntegral --- INTEGRAL
  • AtomicBytes --- BYTES
  • AtomicInt --- INT
  • AtomicUint --- UINT

These Atomic classes are constructable on their own, but it is strongly suggested using the atomic() function to construct them. Each class corresponds to one of the above helper types (as indicated).

This library also provides Atomic*View (in atomics2.view) and Atomic*ViewContext (in atomics2.ctx) counterparts to the Atomic* classes, corresponding to the same helper types.

The latter of the two sets of classes can be constructed manually, although it is strongly suggested using the atomicview() function to construct them. The former set of classes cannot be constructed manually with the available types, and should only be obtained by called .__enter__() on a corresponding Atomic*ViewContext object.

Even though you should never need to directly use these classes (apart from the helper types), they are provided to be used in type hinting. The inheritance hierarchies are detailed in the ARCHITECTURE.md file (available on GitHub).

Construction

This library provides the functions atomic and atomicview, along with the types BYTES, INT, and UINT (as well as ANY and INTEGRAL) to construct atomic objects like so:

import atomics2

a = atomics2.atomic(width=4, atype=atomics2.INT)
print(a)  # AtomicInt(value=0, width=4, readonly=False, signed=True)

buf = bytearray(2)
with atomics2.atomicview(buffer=buf, atype=atomics2.BYTES) as a:
    print(a)  # AtomicBytesView(value=b'\x00\x00', width=2, readonly=True)

You should only need to construct objects with an atype of BYTES, INT, or UINT. Using an atype of ANY or INTGERAL will require additional kwargs, and an atype of ANY will result in an object that doesn't actually expose any atomic operations (only properties, explained in sections further on).

The atomic() function returns a corresponding Atomic* object.

The atomicview() function returns a corresponding Atomic*ViewContext object. You can use this context object in a with statement to obtain an Atomic*View object. The buffer parameter may be any object that supports the buffer protocol.

Construction can raise UnsupportedWidthException and AlignmentError.

NOTE: the width property of Atomic*View objects is derived from the buffer's length as if it were contiguous. It is equivalent to calling memoryview(buf).nbytes.

Lifetime

Objects of Atomic* classes (i.e. objects returned by the atomic() function) have a self-contained buffer which is automatically freed. They can be passed around and stored liked regular variables, and there is nothing special about their lifetime.

Objects of Atomic*ViewContext classes (i.e. objects returned by the atomicview() function) and Atomic*View objects obtained from said objects have a much stricter usage contract.

Contract

The buffer used to construct an Atomic*ViewContext object (either directly or through atomicview()) MUST NOT be invalidated until .release() is called. This is aided by the fact that .release() is called automatically in .__exit__(...) and .__del__(). As long as you immediately use the context object in a with statement, and DO NOT invalidate the buffer inside that with scope, you will always be safe.

The protections implemented are shown in this example:

import atomics2


buf = bytearray(4)
ctx = atomics2.atomicview(buffer=buf, atype=atomics2.INT)

# ctx.release() here will cause ctx.__enter__() to raise:
# ValueError("Cannot open context after calling 'release'.")

with ctx as a:  # this calls ctx.__enter__()
    # ctx.release() here will raise:
    # ValueError("Cannot call 'release' while context is open.")

    # ctx.__enter__() here will raise:
    # ValueError("Cannot open context multiple times.")
    
    print(a.load())  # ok

# ctx.__exit__(...) now called
# we can safely invalidate object 'buf' now

# ctx.__enter__() will raise:
# ValueError("Cannot open context after calling 'release'.")

# accessing object 'a' in any way will also raise an exception

Furthermore, in CPython, all built-in types supporting the buffer protocol will throw a BufferError exception if you try to invalidate them while they're in use (i.e. before calling .release()).

As a last resort, if you absolutely must invalidate the buffer inside the with context (where you can't call .release()), you may call .__exit__(...) manually on the Atomic*ViewContext object. This is to force explicitness about something considered to be bad practice and dangerous.

Where it's allowed, .release() may be called multiple times with no ill-effects. This also applies to .__exit__(...), which has no restrictions on where it can be called.

Alignment

Different platforms may each have their own alignment requirements for atomic operations of given widths. This library provides the Alignment class in atomics2 to ensure that a given buffer meets these requirements.

from atomics2 import Alignment

buf = bytearray(8)
align = Alignment(len(buf))
assert align.is_valid(buf)

If an atomic class is constructed from a misaligned buffer, the constructor will raise AlignmentError.

By default, .is_valid calls .is_valid_recommended. The class Alignment also exposes .is_valid_minimum. Currently, no atomic class makes use of the minimum alignment, so checking for it is pointless. Support for it will be added in a future release.

Properties

All Atomic* and Atomic*View classes have the following properties:

  • width: width in bytes of the underlying buffer (as if it were contiguous)
  • readonly: whether the object supports modifying operations
  • ops_supported: a sorted list of OpType enum values representing which operations are supported on the object

Integral Atomic* and Atomic*View classes also have the following property:

  • signed: whether arithmetic operations are signed or unsigned

In both cases, the behaviour on overflow is defined to wraparound.

Operations

Base Atomic and AtomicView objects (corresponding to ANY) expose no atomic operations.

AtomicBytes and AtomicBytesView objects support the following operations:

  • [base]: load, store
  • [xchg]: exchange, cmpxchg_weak, cmpxchg_strong
  • [bitwise]: bit_test, bit_compl, bit_set, bit_reset
  • [binary]: bin_or, bin_xor, bin_and, bin_not
  • [binary]: bin_fetch_or, bin_fetch_xor, bin_fetch_and, bin_fetch_not

Integral Atomic* and Atomic*View classes additionally support the following operations:

  • [arithmetic]: add, sub, inc, dec, neg
  • [arithmetic]: fetch_add, fetch_sub, fetch_inc, fetch_dec, fetch_neg

The usage of (most of) these functions is modelled directly on the C++11 std::atomic implementation found here.

Compare Exchange (cmpxchg_*)

The cmpxchg_* functions return CmpxchgResult. This has the attributes .success: bool which indicates whether the exchange took place, and .expected: T which holds the original value of the atomic object.
The cmpxchg_weak function may fail spuriously, even if expected matches the actual value. It should be used as shown below:

import atomics2


def atomic_mul(a: atomics2.INTEGRAL, operand: int):
    res = atomics2.CmpxchgResult(success=False, expected=a.load())
    while not res:
        desired = res.expected * operand
        res = a.cmpxchg_weak(expected=res.expected, desired=desired)

In a real implementation of atomic_mul, care should be taken to ensure that desired fits in a (i.e. desired.bit_length() < (a.width * 8), assuming 8 bits in a byte).

Exceptions

All operations can raise UnsupportedOperationException (so check .ops_supported if you need to be sure).

Operations load, store, and cmpxchg_* can raise MemoryOrderError if called with an invalid memory order. MemoryOrder enum values expose the functions is_valid_store_order(), is_valid_load_order(), and is_valid_fail_order() to check with.

Special Methods

AtomicBytes and AtomicBytesView implement the __bytes__ special method.

Integral Atomic* and Atomic*View classes implement the __int__ special method. They intentionally do not implement __index__.

There is a notable lack of any classes implementing special methods corresponding to atomic operations; this is intentional. Assignment in Python is not available as a special method, and we do not want to encourage people to use other special methods with this class, lest it lead to them accidentally using assignment when they meant .store(...).

Memory Order

The MemoryOrder enum class is provided in atomics2, and the memory orders are directly copied from C++11's std::memory_order documentation found here, except for CONSUME (which would be pointless to expose in this library).

All operations have a default memory order, SEQ_CST. This will enforce sequential consistency, and essentially make your multi-threaded and/or multi-processed program be as correct as if it were to run in a single thread.

IF YOU DO NOT UNDERSTAND THE LINKED DOCUMENTATION, DO NOT USE YOUR OWN MEMORY ORDERS!!! Stick with the defaults to be safe. (And realistically, this is Python, you won't get a noticeable performance boost from using a more lax memory order).

The following helper functions are provided:

  • .is_valid_store_order() (for store op)
  • .is_valid_load_order() ( for load op)
  • .is_valid_fail_order() (for the fail ordering in cmpxchg_* ops)

Passing an invalid memory order to one of these ops will raise MemoryOrderError.

Exceptions

The following exceptions are available in atomics2.exc:

  • AlignmentError
  • MemoryOrderError
  • UnsupportedWidthException
  • UnsupportedOperationException

Building

IMPORTANT: Make sure you have the latest version of pip installed.

Using setup.py's build or bdist_wheel commands will run the build_patomic command (which you can also run directly).

This clones the patomic library into a temporary directory, builds it, and then copies the shared library into atomics2._clib.

This requires that git be installed on your system (a requirement of the GitPython module). You will also need a C compiler with C11 <stdatomic.h> support (or MSVC on Windows), otherwise patomic will build but support no operations. CMake is also required but should be automatically pip install'd if not available.

If you absolutely cannot get build_patomic to work, go to patomic, follow the instructions on building it (making sure to build the shared library version), and then copy-paste the shared library file into atomics2._clib manually.

NOTE: Currently, the library builds a dummy extension in order to trick setuptools into building a non-purepython wheel. If you are ok with a purepython wheel, then feel free to remove the code for that from setup.py (at the bottom).
Otherwise, you will need a C99 compliant C compiler, and probably the development libraries/headers for whichever version of Python you're using.

Future Thoughts

  • add docstrings
  • add support for minimum alignment
  • add support for constructing Atomic classes' buffers in shared memory
  • add support for passing Atomic objects to sub-processes and sub-interpreters
  • reimplement in C or Cython for performance gains (preliminary benchmarks put such implementations at 2x the speed of a raw int)

Contributing

I don't have a guide for contributing yet. This section is here to make the following two points:

  • new operations must first be implemented in patomic before this library can be updated
  • new architectures, widths, and existing unsupported operations must be supported in patomic (no change required in this library)

License and Attribution

This project is licensed under the GNU General Public License v3 (LICENSE.txt), the same license as the original project.

atomics2 is a fork of atomics, copyright doodspav, which also authored the underlying patomic C library. Changes in this fork are copyright Michiel van der Lee.

Download files

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

Source Distribution

atomics2-1.1.0.tar.gz (46.6 kB view details)

Uploaded Source

Built Distributions

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

atomics2-1.1.0-py311.py312.py313.py314-none-win_arm64.whl (73.2 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14Windows ARM64

atomics2-1.1.0-py311.py312.py313.py314-none-win_amd64.whl (61.8 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14Windows x86-64

atomics2-1.1.0-py311.py312.py313.py314-none-win32.whl (55.3 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14Windows x86

atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_x86_64.whl (183.0 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14musllinux: musl 1.2+ x86-64

atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_s390x.whl (191.6 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14musllinux: musl 1.2+ s390x

atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_ppc64le.whl (194.4 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14musllinux: musl 1.2+ ppc64le

atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_i686.whl (165.5 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14musllinux: musl 1.2+ i686

atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_aarch64.whl (193.1 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14musllinux: musl 1.2+ ARM64

atomics2-1.1.0-py311.py312.py313.py314-none-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl (195.3 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14manylinux: glibc 2.17+ s390xmanylinux: glibc 2.28+ s390x

atomics2-1.1.0-py311.py312.py313.py314-none-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl (193.9 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14manylinux: glibc 2.17+ ppc64lemanylinux: glibc 2.28+ ppc64le

atomics2-1.1.0-py311.py312.py313.py314-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (195.4 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

atomics2-1.1.0-py311.py312.py313.py314-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (183.4 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14manylinux: glibc 2.28+ x86-64manylinux: glibc 2.5+ x86-64

atomics2-1.1.0-py311.py312.py313.py314-none-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl (164.6 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14manylinux: glibc 2.28+ i686manylinux: glibc 2.5+ i686

atomics2-1.1.0-py311.py312.py313.py314-none-macosx_11_0_arm64.whl (71.7 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14macOS 11.0+ ARM64

atomics2-1.1.0-py311.py312.py313.py314-none-macosx_10_13_x86_64.whl (69.2 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14macOS 10.13+ x86-64

atomics2-1.1.0-py311.py312.py313.py314-none-macosx_10_13_universal2.whl (103.2 kB view details)

Uploaded Python 3.11Python 3.12Python 3.13Python 3.14macOS 10.13+ universal2 (ARM64, x86-64)

File details

Details for the file atomics2-1.1.0.tar.gz.

File metadata

  • Download URL: atomics2-1.1.0.tar.gz
  • Upload date:
  • Size: 46.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for atomics2-1.1.0.tar.gz
Algorithm Hash digest
SHA256 1590b5b1007ab97c7588c23bad737ddc0779a273d12c2ad1cb27168b4d35611d
MD5 d306ced0e84577eac1a9bd8ae1596479
BLAKE2b-256 f411da3da29fd32821fabe3accbe328e9d0f2e07b445017b08dcd4b42089ddb8

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0.tar.gz:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-win_arm64.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-win_arm64.whl
Algorithm Hash digest
SHA256 75d81cfade68f59b76479ad2b4a98930da7ebb97037f7358ecdabf786264314f
MD5 9d8d49a60a418914c590cf54d0b8bb78
BLAKE2b-256 cf59a5af8c7375ad894dba4167a0f1e046f1f139abd200ad7a1799347f4bcc82

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-win_arm64.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-win_amd64.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-win_amd64.whl
Algorithm Hash digest
SHA256 000d8055022919d81e30ada577e07c7861649b1cb5fc123b8737844fe11cdcec
MD5 bf36b4d17a76531cf931eb6d394fb49b
BLAKE2b-256 6b8910f393b2d04d56430192c9282f62360c3e061069ef9af14ce286ab5045a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-win_amd64.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-win32.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-win32.whl
Algorithm Hash digest
SHA256 007be3349917789ac3dd0c3f32a08a53501aa5c59abaf4e344edf4c9bfa94e77
MD5 7a3c52338c948ba5621554e77295fd06
BLAKE2b-256 9ad79b6c60208300d4b9b89644cb08dcf8b3e02084a7d275fdc60306b741c8e2

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-win32.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 08baa1ff9de7312777cc9b19a6653fe48eca556a75417b115e8e1f3349c096d3
MD5 610e8894178b8bfcbcf77d56786dce04
BLAKE2b-256 0197751ed68efd7ab1084650e86b592d4de0042d23b2846eaf1f6641bce61e56

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_x86_64.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_s390x.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_s390x.whl
Algorithm Hash digest
SHA256 2c6cb7f54b12abd76e0f6bcc717ffce2e87765ae45aa9967e0b77f0ab1ee63f2
MD5 7e6d5aaf5510a60f78e3101f24b8b477
BLAKE2b-256 929a8dd5d6f30a1bac453466f9cc6cf89ea41b89d00450d22bf361bfe01e95f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_s390x.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_ppc64le.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_ppc64le.whl
Algorithm Hash digest
SHA256 8a36b7ad6d4e1c11ac80f479ebfd5d623e042d1749301d5755984b99ac48c256
MD5 d8cce686d3d6abcf86979889eff81e1b
BLAKE2b-256 ff6a8055039d9ad3cb6f0fca90079077bf7a27a1c1beaa9b8851874decfc2950

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_ppc64le.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 418a2690274db0bea2bafe8ff9e664acbeda913cc78ee13c80a490491c219094
MD5 791aa9780253c165519a42e0d2d24c57
BLAKE2b-256 82f8355681dc0034c3463bc1cd26e26eafda307428994e0c4a35dd751fd8a35a

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_i686.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 2f5b72309ceb6badd5903a06fda0d5947a6cc1ec84d7945a71e5eb7d269cc191
MD5 0429fad27d4c75a7a1ccb0b33bddaf07
BLAKE2b-256 4c9fb9bbb230c8633d3040d1e61dd7735541569ea348a3e2a90f2f9064d86d79

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-musllinux_1_2_aarch64.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl
Algorithm Hash digest
SHA256 6e621d65653f3bd43d0c779e6feed4fa2277a1d0faef94854bcc0f8365a7b7ae
MD5 c480da1af7e6e3278d1032f417e113cd
BLAKE2b-256 f532f358805cd4c73ca31a18d4299ba5c74e002477d0741148be248ea6194133

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 d411c75117b4dcf76d254601dcfb44b51de28ad1c9f3c978bfb69fda3ff3e94d
MD5 05a2e244d4e3b4604a9c13f9dfb91420
BLAKE2b-256 7dd8951370dcb0dea94662587298c8645144c7761e4585743e735e43b4995965

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 806b1dd9a6b0976664b76edfad176877ada9bf7d37aba00f27987d46ab6be525
MD5 6c87ec45b130b1bf7927e5a54907e9ad
BLAKE2b-256 245c9336c8b70a01660c2f7f4e66b21c9f2efab0f2b52d70510d03ed9398f7c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 24ccc1353e0b9ab987f990a4f769f96bcc116a75e53c369725bd4a91f792ad0c
MD5 3b68a19233416a51a714e4178673ea70
BLAKE2b-256 de43d5e78467d3e0bd5f369dba83ee8f6c7f1e6512623c17d8c2d60b96cd4faf

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl
Algorithm Hash digest
SHA256 8923f3f774e4ee049bb3ae3743969a602bc672369a3e32a48aa439a80d80be6d
MD5 912db25688b941eeebf3ba98c10e9905
BLAKE2b-256 05d5441e67cd3ffd0303fa7e3c47bd8f0aa8f176b8e703e0e71d4d6f8afde4e6

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3201f0d13fe97c899335bfc617ee2647eaa377a89c72c50b7d4a61433a609e00
MD5 9e4a9e72c849cd86fe20e0a47e346960
BLAKE2b-256 052560fe6bafb4081dcc059c12f3e062d06f7a0f7a0efa770f2ecd94a9dbaca2

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-macosx_11_0_arm64.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 d59fa37e7fdde9ea1df9d3a86a9bab7286e7e2251355b420f4ef42e7d7153f4c
MD5 755f79fb8f1e27a38877379a6b6638fd
BLAKE2b-256 ea02561ab39dd53fc38c4e4406fc6816c837e2a85775100b1dd4308f558ee6c1

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-macosx_10_13_x86_64.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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

File details

Details for the file atomics2-1.1.0-py311.py312.py313.py314-none-macosx_10_13_universal2.whl.

File metadata

File hashes

Hashes for atomics2-1.1.0-py311.py312.py313.py314-none-macosx_10_13_universal2.whl
Algorithm Hash digest
SHA256 7b26af12ffe1bf63e054d232d1149fd776da46104fbcd817cb34fffa6837ad7e
MD5 fe8281cee0228b27fe2092cdc644e9cf
BLAKE2b-256 46b97d239b3e8cef8617599ff80612f2679dba004d96b3f9f5bb3dc162bae0a6

See more details on using hashes here.

Provenance

The following attestation bundles were made for atomics2-1.1.0-py311.py312.py313.py314-none-macosx_10_13_universal2.whl:

Publisher: on-release.yml on mvanderlee/atomics2

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 Sentry Error logging StatusPage Status page