stablehash


Namestablehash JSON
Version 0.3.0 PyPI version JSON
download
home_pageNone
SummaryStable hashing of Python data structures across separate processes and platforms.
upload_time2025-10-27 10:30:03
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseMIT
keywords dataclasses hash hashlib python hashing stable hash
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # stablehash

The `stablehash` module provides a "pure" hash function that is stable across Python processes and runs. This is in
contrast to the builtin `hash()` function, which may return a different value for the same input in separate
invokations even with the Python version.

We support most Python built-in types, including mutable types such as `list` and `dict`, as well as dataclasses. The
default internal hash algorithm is Blake2b, but this can be changed by passing a different `hashlib` algorithm to the
`stablehash` function.

## Usage

```python
from stablehash import stablehash

assert stablehash({"key": "value"}, algorithm="md5").hexdigest() == "0ea2506ffbeef2699760d422d7a8b971"
```

## Compatibility notes

### Since `0.3.x`
Hashing semantics are changed for certain inputs to improve stability:

* Dictionaries now hash independent of key insertion order (i.e., equal dicts produce the same digest regardless of the order keys were added).  
* Serialize floats as IEEE-754 64-bit little-endian (`struct.pack('<d', x)`) to guarantee cross-platform stable digests.  

These changes may cause the digest produced for the same value to **differ from** the `0.2.x` series. The public API is unchanged, but we treat changes that alter produced hashes as breaking from a user's perspective. (See PR [#20](https://github.com/NiklasRosenstein/python-stablehash/pull/20) for background.)

<details>

<summary>
<b>What should downstream users do?</b>
</summary>

* If your project depends on exact hash outputs (for example, using them as file identifiers or data fingerprints), either:  

  * pin an **upper bound** to the previous minor series: `stablehash >=0.2.0, <0.3.0`, or  
  * upgrade to `0.3.x` and **re-generate** your stored hashes.     

</details>

## Versioning policy

This project follows Semantic Versioning where applicable. During initial development (`0.y.z`), the public API should not be considered stable and **breaking changes may occur in a minor bump**. We therefore use the minor version to signal changes that can alter produced digests (semantic changes). Downstream users are encouraged to **specify an upper bound** on the minor version when depending on `0.y.z` releases. 

## API

### `stablehash(obj=..., *, algorithm="blake2b")`

Returns a `hashlib`-compatible object with the given algorithm and the hash of the given object. The algorithm must be
one of the algorithms supported by `hashlib`.

### `stablehash.update(obj)`

Updates the hash with the given object. If the object is not supported, a `TypeError` is raised.

### `stablehash.digest()`

Returns the digest of the hash as a bytes object.

### `stablehash.hexdigest()`

Returns the digest of the hash as a string object.

## Supported types

The following types are supported:

- `None`
- `bool`
- `int`
- `float`
- `str`
- `bytes`
- `tuple`
- `list`
- `set`
- `frozenset`
- `dict`
- `@dataclass` objects
- `datetime` objects (`datetime`, `date`, `time` and `timedelta`)
- `uuid.UUID`
- Picklable objects (e.g. those that implement `__getstate__()`)
- `type` objects (by their full qualified name)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "stablehash",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "dataclasses, hash, hashlib, python hashing, stable hash",
    "author": null,
    "author_email": "Niklas Rosenstein <rosensteinniklas@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/5f/01/159196c21db96a7adde6d52e7691762ef873a708c6d56ea4e8bd99ba8392/stablehash-0.3.0.tar.gz",
    "platform": null,
    "description": "# stablehash\n\nThe `stablehash` module provides a \"pure\" hash function that is stable across Python processes and runs. This is in\ncontrast to the builtin `hash()` function, which may return a different value for the same input in separate\ninvokations even with the Python version.\n\nWe support most Python built-in types, including mutable types such as `list` and `dict`, as well as dataclasses. The\ndefault internal hash algorithm is Blake2b, but this can be changed by passing a different `hashlib` algorithm to the\n`stablehash` function.\n\n## Usage\n\n```python\nfrom stablehash import stablehash\n\nassert stablehash({\"key\": \"value\"}, algorithm=\"md5\").hexdigest() == \"0ea2506ffbeef2699760d422d7a8b971\"\n```\n\n## Compatibility notes\n\n### Since `0.3.x`\nHashing semantics are changed for certain inputs to improve stability:\n\n* Dictionaries now hash independent of key insertion order (i.e., equal dicts produce the same digest regardless of the order keys were added).  \n* Serialize floats as IEEE-754 64-bit little-endian (`struct.pack('<d', x)`) to guarantee cross-platform stable digests.  \n\nThese changes may cause the digest produced for the same value to **differ from** the `0.2.x` series. The public API is unchanged, but we treat changes that alter produced hashes as breaking from a user's perspective. (See PR [#20](https://github.com/NiklasRosenstein/python-stablehash/pull/20) for background.)\n\n<details>\n\n<summary>\n<b>What should downstream users do?</b>\n</summary>\n\n* If your project depends on exact hash outputs (for example, using them as file identifiers or data fingerprints), either:  \n\n  * pin an **upper bound** to the previous minor series: `stablehash >=0.2.0, <0.3.0`, or  \n  * upgrade to `0.3.x` and **re-generate** your stored hashes.     \n\n</details>\n\n## Versioning policy\n\nThis project follows Semantic Versioning where applicable. During initial development (`0.y.z`), the public API should not be considered stable and **breaking changes may occur in a minor bump**. We therefore use the minor version to signal changes that can alter produced digests (semantic changes). Downstream users are encouraged to **specify an upper bound** on the minor version when depending on `0.y.z` releases. \n\n## API\n\n### `stablehash(obj=..., *, algorithm=\"blake2b\")`\n\nReturns a `hashlib`-compatible object with the given algorithm and the hash of the given object. The algorithm must be\none of the algorithms supported by `hashlib`.\n\n### `stablehash.update(obj)`\n\nUpdates the hash with the given object. If the object is not supported, a `TypeError` is raised.\n\n### `stablehash.digest()`\n\nReturns the digest of the hash as a bytes object.\n\n### `stablehash.hexdigest()`\n\nReturns the digest of the hash as a string object.\n\n## Supported types\n\nThe following types are supported:\n\n- `None`\n- `bool`\n- `int`\n- `float`\n- `str`\n- `bytes`\n- `tuple`\n- `list`\n- `set`\n- `frozenset`\n- `dict`\n- `@dataclass` objects\n- `datetime` objects (`datetime`, `date`, `time` and `timedelta`)\n- `uuid.UUID`\n- Picklable objects (e.g. those that implement `__getstate__()`)\n- `type` objects (by their full qualified name)\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Stable hashing of Python data structures across separate processes and platforms.",
    "version": "0.3.0",
    "project_urls": {
        "Issues": "https://github.com/NiklasRosenstein/python-stablehash/issues",
        "Repository": "https://github.com/NiklasRosenstein/python-stablehash"
    },
    "split_keywords": [
        "dataclasses",
        " hash",
        " hashlib",
        " python hashing",
        " stable hash"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7b7a4eb9fc77dececb5478f1d105b6b6c5a64706aa0715134b0bf50a1081406f",
                "md5": "fee62ba0d9d16dad08d965542173efed",
                "sha256": "82b59223e7c5c9b6df42dd4d3f1dbdc1356ecf80102405f5355dc287b28b77f6"
            },
            "downloads": -1,
            "filename": "stablehash-0.3.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "fee62ba0d9d16dad08d965542173efed",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 7354,
            "upload_time": "2025-10-27T10:30:02",
            "upload_time_iso_8601": "2025-10-27T10:30:02.294922Z",
            "url": "https://files.pythonhosted.org/packages/7b/7a/4eb9fc77dececb5478f1d105b6b6c5a64706aa0715134b0bf50a1081406f/stablehash-0.3.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5f01159196c21db96a7adde6d52e7691762ef873a708c6d56ea4e8bd99ba8392",
                "md5": "df736a11abe954bd8130f127fc1d57b0",
                "sha256": "31d89697683c664487b6f995759aa14bc65bb9de31ad8beca5e99c8678b66baf"
            },
            "downloads": -1,
            "filename": "stablehash-0.3.0.tar.gz",
            "has_sig": false,
            "md5_digest": "df736a11abe954bd8130f127fc1d57b0",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 8166,
            "upload_time": "2025-10-27T10:30:03",
            "upload_time_iso_8601": "2025-10-27T10:30:03.632881Z",
            "url": "https://files.pythonhosted.org/packages/5f/01/159196c21db96a7adde6d52e7691762ef873a708c6d56ea4e8bd99ba8392/stablehash-0.3.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-27 10:30:03",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "NiklasRosenstein",
    "github_project": "python-stablehash",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "stablehash"
}
        
Elapsed time: 2.61721s