cymem


Namecymem JSON
Version 2.0.10 PyPI version JSON
download
home_pagehttps://github.com/explosion/cymem
SummaryManage calls to calloc/free through Cython
upload_time2024-11-22 22:27:33
maintainerNone
docs_urlNone
authorMatthew Honnibal
requires_pythonNone
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <a href="https://explosion.ai"><img src="https://explosion.ai/assets/img/logo.svg" width="125" height="125" align="right" /></a>

# cymem: A Cython Memory Helper

cymem provides two small memory-management helpers for Cython. They make it easy
to tie memory to a Python object's life-cycle, so that the memory is freed when
the object is garbage collected.

[![tests](https://github.com/explosion/cymem/actions/workflows/tests.yml/badge.svg)](https://github.com/explosion/cymem/actions/workflows/tests.yml)
[![pypi Version](https://img.shields.io/pypi/v/cymem.svg?style=flat-square&logo=pypi&logoColor=white)](https://pypi.python.org/pypi/cymem)
[![conda Version](https://img.shields.io/conda/vn/conda-forge/cymem.svg?style=flat-square&logo=conda-forge&logoColor=white)](https://anaconda.org/conda-forge/cymem)
[![Python wheels](https://img.shields.io/badge/wheels-%E2%9C%93-4c1.svg?longCache=true&style=flat-square&logo=python&logoColor=white)](https://github.com/explosion/wheelwright/releases)

## Overview

The most useful is `cymem.Pool`, which acts as a thin wrapper around the calloc
function:

```python
from cymem.cymem cimport Pool
cdef Pool mem = Pool()
data1 = <int*>mem.alloc(10, sizeof(int))
data2 = <float*>mem.alloc(12, sizeof(float))
```

The `Pool` object saves the memory addresses internally, and frees them when the
object is garbage collected. Typically you'll attach the `Pool` to some cdef'd
class. This is particularly handy for deeply nested structs, which have
complicated initialization functions. Just pass the `Pool` object into the
initializer, and you don't have to worry about freeing your struct at all — all
of the calls to `Pool.alloc` will be automatically freed when the `Pool`
expires.

## Installation

Installation is via [pip](https://pypi.python.org/pypi/pip), and requires
[Cython](http://cython.org). Before installing, make sure that your `pip`,
`setuptools` and `wheel` are up to date.

```bash
pip install -U pip setuptools wheel
pip install cymem
```

## Example Use Case: An array of structs

Let's say we want a sequence of sparse matrices. We need fast access, and a
Python list isn't performing well enough. So, we want a C-array or C++ vector,
which means we need the sparse matrix to be a C-level struct — it can't be a
Python class. We can write this easily enough in Cython:

```python
"""Example without Cymem

To use an array of structs, we must carefully walk the data structure when
we deallocate it.
"""

from libc.stdlib cimport calloc, free

cdef struct SparseRow:
    size_t length
    size_t* indices
    double* values

cdef struct SparseMatrix:
    size_t length
    SparseRow* rows

cdef class MatrixArray:
    cdef size_t length
    cdef SparseMatrix** matrices

    def __cinit__(self, list py_matrices):
        self.length = 0
        self.matrices = NULL

    def __init__(self, list py_matrices):
        self.length = len(py_matrices)
        self.matrices = <SparseMatrix**>calloc(len(py_matrices), sizeof(SparseMatrix*))

        for i, py_matrix in enumerate(py_matrices):
            self.matrices[i] = sparse_matrix_init(py_matrix)

    def __dealloc__(self):
        for i in range(self.length):
            sparse_matrix_free(self.matrices[i])
        free(self.matrices)


cdef SparseMatrix* sparse_matrix_init(list py_matrix) except NULL:
    sm = <SparseMatrix*>calloc(1, sizeof(SparseMatrix))
    sm.length = len(py_matrix)
    sm.rows = <SparseRow*>calloc(sm.length, sizeof(SparseRow))
    cdef size_t i, j
    cdef dict py_row
    cdef size_t idx
    cdef double value
    for i, py_row in enumerate(py_matrix):
        sm.rows[i].length = len(py_row)
        sm.rows[i].indices = <size_t*>calloc(sm.rows[i].length, sizeof(size_t))
        sm.rows[i].values = <double*>calloc(sm.rows[i].length, sizeof(double))
        for j, (idx, value) in enumerate(py_row.items()):
            sm.rows[i].indices[j] = idx
            sm.rows[i].values[j] = value
    return sm


cdef void* sparse_matrix_free(SparseMatrix* sm) except *:
    cdef size_t i
    for i in range(sm.length):
        free(sm.rows[i].indices)
        free(sm.rows[i].values)
    free(sm.rows)
    free(sm)
```

We wrap the data structure in a Python ref-counted class at as low a level as we
can, given our performance constraints. This allows us to allocate and free the
memory in the `__cinit__` and `__dealloc__` Cython special methods.

However, it's very easy to make mistakes when writing the `__dealloc__` and
`sparse_matrix_free` functions, leading to memory leaks. cymem prevents you from
writing these deallocators at all. Instead, you write as follows:

```python
"""Example with Cymem.

Memory allocation is hidden behind the Pool class, which remembers the
addresses it gives out.  When the Pool object is garbage collected, all of
its addresses are freed.

We don't need to write MatrixArray.__dealloc__ or sparse_matrix_free,
eliminating a common class of bugs.
"""
from cymem.cymem cimport Pool

cdef struct SparseRow:
    size_t length
    size_t* indices
    double* values

cdef struct SparseMatrix:
    size_t length
    SparseRow* rows


cdef class MatrixArray:
    cdef size_t length
    cdef SparseMatrix** matrices
    cdef Pool mem

    def __cinit__(self, list py_matrices):
        self.mem = None
        self.length = 0
        self.matrices = NULL

    def __init__(self, list py_matrices):
        self.mem = Pool()
        self.length = len(py_matrices)
        self.matrices = <SparseMatrix**>self.mem.alloc(self.length, sizeof(SparseMatrix*))
        for i, py_matrix in enumerate(py_matrices):
            self.matrices[i] = sparse_matrix_init(self.mem, py_matrix)

cdef SparseMatrix* sparse_matrix_init_cymem(Pool mem, list py_matrix) except NULL:
    sm = <SparseMatrix*>mem.alloc(1, sizeof(SparseMatrix))
    sm.length = len(py_matrix)
    sm.rows = <SparseRow*>mem.alloc(sm.length, sizeof(SparseRow))
    cdef size_t i, j
    cdef dict py_row
    cdef size_t idx
    cdef double value
    for i, py_row in enumerate(py_matrix):
        sm.rows[i].length = len(py_row)
        sm.rows[i].indices = <size_t*>mem.alloc(sm.rows[i].length, sizeof(size_t))
        sm.rows[i].values = <double*>mem.alloc(sm.rows[i].length, sizeof(double))
        for j, (idx, value) in enumerate(py_row.items()):
            sm.rows[i].indices[j] = idx
            sm.rows[i].values[j] = value
    return sm
```

All that the `Pool` class does is remember the addresses it gives out. When the
`MatrixArray` object is garbage-collected, the `Pool` object will also be
garbage collected, which triggers a call to `Pool.__dealloc__`. The `Pool` then
frees all of its addresses. This saves you from walking back over your nested
data structures to free them, eliminating a common class of errors.

## Custom Allocators

Sometimes external C libraries use private functions to allocate and free
objects, but we'd still like the laziness of the `Pool`.

```python
from cymem.cymem cimport Pool, WrapMalloc, WrapFree
cdef Pool mem = Pool(WrapMalloc(priv_malloc), WrapFree(priv_free))
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/explosion/cymem",
    "name": "cymem",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": null,
    "author": "Matthew Honnibal",
    "author_email": "matt@explosion.ai",
    "download_url": "https://files.pythonhosted.org/packages/b6/62/eac45989f3d3296133f292f3097cb4c1f9d3ad3e5a85e79bbd2c7f96278f/cymem-2.0.10.tar.gz",
    "platform": null,
    "description": "<a href=\"https://explosion.ai\"><img src=\"https://explosion.ai/assets/img/logo.svg\" width=\"125\" height=\"125\" align=\"right\" /></a>\n\n# cymem: A Cython Memory Helper\n\ncymem provides two small memory-management helpers for Cython. They make it easy\nto tie memory to a Python object's life-cycle, so that the memory is freed when\nthe object is garbage collected.\n\n[![tests](https://github.com/explosion/cymem/actions/workflows/tests.yml/badge.svg)](https://github.com/explosion/cymem/actions/workflows/tests.yml)\n[![pypi Version](https://img.shields.io/pypi/v/cymem.svg?style=flat-square&logo=pypi&logoColor=white)](https://pypi.python.org/pypi/cymem)\n[![conda Version](https://img.shields.io/conda/vn/conda-forge/cymem.svg?style=flat-square&logo=conda-forge&logoColor=white)](https://anaconda.org/conda-forge/cymem)\n[![Python wheels](https://img.shields.io/badge/wheels-%E2%9C%93-4c1.svg?longCache=true&style=flat-square&logo=python&logoColor=white)](https://github.com/explosion/wheelwright/releases)\n\n## Overview\n\nThe most useful is `cymem.Pool`, which acts as a thin wrapper around the calloc\nfunction:\n\n```python\nfrom cymem.cymem cimport Pool\ncdef Pool mem = Pool()\ndata1 = <int*>mem.alloc(10, sizeof(int))\ndata2 = <float*>mem.alloc(12, sizeof(float))\n```\n\nThe `Pool` object saves the memory addresses internally, and frees them when the\nobject is garbage collected. Typically you'll attach the `Pool` to some cdef'd\nclass. This is particularly handy for deeply nested structs, which have\ncomplicated initialization functions. Just pass the `Pool` object into the\ninitializer, and you don't have to worry about freeing your struct at all \u2014 all\nof the calls to `Pool.alloc` will be automatically freed when the `Pool`\nexpires.\n\n## Installation\n\nInstallation is via [pip](https://pypi.python.org/pypi/pip), and requires\n[Cython](http://cython.org). Before installing, make sure that your `pip`,\n`setuptools` and `wheel` are up to date.\n\n```bash\npip install -U pip setuptools wheel\npip install cymem\n```\n\n## Example Use Case: An array of structs\n\nLet's say we want a sequence of sparse matrices. We need fast access, and a\nPython list isn't performing well enough. So, we want a C-array or C++ vector,\nwhich means we need the sparse matrix to be a C-level struct \u2014 it can't be a\nPython class. We can write this easily enough in Cython:\n\n```python\n\"\"\"Example without Cymem\n\nTo use an array of structs, we must carefully walk the data structure when\nwe deallocate it.\n\"\"\"\n\nfrom libc.stdlib cimport calloc, free\n\ncdef struct SparseRow:\n    size_t length\n    size_t* indices\n    double* values\n\ncdef struct SparseMatrix:\n    size_t length\n    SparseRow* rows\n\ncdef class MatrixArray:\n    cdef size_t length\n    cdef SparseMatrix** matrices\n\n    def __cinit__(self, list py_matrices):\n        self.length = 0\n        self.matrices = NULL\n\n    def __init__(self, list py_matrices):\n        self.length = len(py_matrices)\n        self.matrices = <SparseMatrix**>calloc(len(py_matrices), sizeof(SparseMatrix*))\n\n        for i, py_matrix in enumerate(py_matrices):\n            self.matrices[i] = sparse_matrix_init(py_matrix)\n\n    def __dealloc__(self):\n        for i in range(self.length):\n            sparse_matrix_free(self.matrices[i])\n        free(self.matrices)\n\n\ncdef SparseMatrix* sparse_matrix_init(list py_matrix) except NULL:\n    sm = <SparseMatrix*>calloc(1, sizeof(SparseMatrix))\n    sm.length = len(py_matrix)\n    sm.rows = <SparseRow*>calloc(sm.length, sizeof(SparseRow))\n    cdef size_t i, j\n    cdef dict py_row\n    cdef size_t idx\n    cdef double value\n    for i, py_row in enumerate(py_matrix):\n        sm.rows[i].length = len(py_row)\n        sm.rows[i].indices = <size_t*>calloc(sm.rows[i].length, sizeof(size_t))\n        sm.rows[i].values = <double*>calloc(sm.rows[i].length, sizeof(double))\n        for j, (idx, value) in enumerate(py_row.items()):\n            sm.rows[i].indices[j] = idx\n            sm.rows[i].values[j] = value\n    return sm\n\n\ncdef void* sparse_matrix_free(SparseMatrix* sm) except *:\n    cdef size_t i\n    for i in range(sm.length):\n        free(sm.rows[i].indices)\n        free(sm.rows[i].values)\n    free(sm.rows)\n    free(sm)\n```\n\nWe wrap the data structure in a Python ref-counted class at as low a level as we\ncan, given our performance constraints. This allows us to allocate and free the\nmemory in the `__cinit__` and `__dealloc__` Cython special methods.\n\nHowever, it's very easy to make mistakes when writing the `__dealloc__` and\n`sparse_matrix_free` functions, leading to memory leaks. cymem prevents you from\nwriting these deallocators at all. Instead, you write as follows:\n\n```python\n\"\"\"Example with Cymem.\n\nMemory allocation is hidden behind the Pool class, which remembers the\naddresses it gives out.  When the Pool object is garbage collected, all of\nits addresses are freed.\n\nWe don't need to write MatrixArray.__dealloc__ or sparse_matrix_free,\neliminating a common class of bugs.\n\"\"\"\nfrom cymem.cymem cimport Pool\n\ncdef struct SparseRow:\n    size_t length\n    size_t* indices\n    double* values\n\ncdef struct SparseMatrix:\n    size_t length\n    SparseRow* rows\n\n\ncdef class MatrixArray:\n    cdef size_t length\n    cdef SparseMatrix** matrices\n    cdef Pool mem\n\n    def __cinit__(self, list py_matrices):\n        self.mem = None\n        self.length = 0\n        self.matrices = NULL\n\n    def __init__(self, list py_matrices):\n        self.mem = Pool()\n        self.length = len(py_matrices)\n        self.matrices = <SparseMatrix**>self.mem.alloc(self.length, sizeof(SparseMatrix*))\n        for i, py_matrix in enumerate(py_matrices):\n            self.matrices[i] = sparse_matrix_init(self.mem, py_matrix)\n\ncdef SparseMatrix* sparse_matrix_init_cymem(Pool mem, list py_matrix) except NULL:\n    sm = <SparseMatrix*>mem.alloc(1, sizeof(SparseMatrix))\n    sm.length = len(py_matrix)\n    sm.rows = <SparseRow*>mem.alloc(sm.length, sizeof(SparseRow))\n    cdef size_t i, j\n    cdef dict py_row\n    cdef size_t idx\n    cdef double value\n    for i, py_row in enumerate(py_matrix):\n        sm.rows[i].length = len(py_row)\n        sm.rows[i].indices = <size_t*>mem.alloc(sm.rows[i].length, sizeof(size_t))\n        sm.rows[i].values = <double*>mem.alloc(sm.rows[i].length, sizeof(double))\n        for j, (idx, value) in enumerate(py_row.items()):\n            sm.rows[i].indices[j] = idx\n            sm.rows[i].values[j] = value\n    return sm\n```\n\nAll that the `Pool` class does is remember the addresses it gives out. When the\n`MatrixArray` object is garbage-collected, the `Pool` object will also be\ngarbage collected, which triggers a call to `Pool.__dealloc__`. The `Pool` then\nfrees all of its addresses. This saves you from walking back over your nested\ndata structures to free them, eliminating a common class of errors.\n\n## Custom Allocators\n\nSometimes external C libraries use private functions to allocate and free\nobjects, but we'd still like the laziness of the `Pool`.\n\n```python\nfrom cymem.cymem cimport Pool, WrapMalloc, WrapFree\ncdef Pool mem = Pool(WrapMalloc(priv_malloc), WrapFree(priv_free))\n```\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Manage calls to calloc/free through Cython",
    "version": "2.0.10",
    "project_urls": {
        "Homepage": "https://github.com/explosion/cymem"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9854304b4f262524aa3bbf4e41b21fb7aa90fc507979995a12ad3b81c30d5650",
                "md5": "38a4c2990ae50fe54199016be61c0cb3",
                "sha256": "010f78804cf5e2fbd08abad210d2b78a828bea1a9f978737e28e1614f5a258b4"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp310-cp310-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "38a4c2990ae50fe54199016be61c0cb3",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 41843,
            "upload_time": "2024-11-22T22:26:53",
            "upload_time_iso_8601": "2024-11-22T22:26:53.412997Z",
            "url": "https://files.pythonhosted.org/packages/98/54/304b4f262524aa3bbf4e41b21fb7aa90fc507979995a12ad3b81c30d5650/cymem-2.0.10-cp310-cp310-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "72270a7e6f2b4f4183ce707aeae65880194600d0d42964753c256074b9d0fca9",
                "md5": "379a42a25a3caaec3c82e0ce4e02c1b1",
                "sha256": "9688f691518859e76c24c37686314dc5163f2fae1b9df264714220fc087b09a5"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp310-cp310-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "379a42a25a3caaec3c82e0ce4e02c1b1",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 41649,
            "upload_time": "2024-11-22T22:26:55",
            "upload_time_iso_8601": "2024-11-22T22:26:55.416765Z",
            "url": "https://files.pythonhosted.org/packages/72/27/0a7e6f2b4f4183ce707aeae65880194600d0d42964753c256074b9d0fca9/cymem-2.0.10-cp310-cp310-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "16d8889f7b98211919f4bf53b901712440c2110ebfc69fcf234af063eed5c9a7",
                "md5": "a867df69198ba69539dcda018f79c768",
                "sha256": "61ce538c594f348b90037b03910da31ce7aacca090ea64063593688c55f6adad"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "a867df69198ba69539dcda018f79c768",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 204712,
            "upload_time": "2024-11-22T22:26:57",
            "upload_time_iso_8601": "2024-11-22T22:26:57.106462Z",
            "url": "https://files.pythonhosted.org/packages/16/d8/889f7b98211919f4bf53b901712440c2110ebfc69fcf234af063eed5c9a7/cymem-2.0.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "975b3de3d725c88a9aad0dca72a42da576d76f19e83b660cec912cb60585c46c",
                "md5": "86344e353edb4268240467acb9883881",
                "sha256": "4d45b99c727dfc303db3bb9f136b86731a4d231fbf9c27ce5745ea4a527da0b5"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp310-cp310-musllinux_1_2_x86_64.whl",
            "has_sig": false,
            "md5_digest": "86344e353edb4268240467acb9883881",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 194955,
            "upload_time": "2024-11-22T22:26:58",
            "upload_time_iso_8601": "2024-11-22T22:26:58.547007Z",
            "url": "https://files.pythonhosted.org/packages/97/5b/3de3d725c88a9aad0dca72a42da576d76f19e83b660cec912cb60585c46c/cymem-2.0.10-cp310-cp310-musllinux_1_2_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "496b2fe6abc7f4577f681625b9b374c88ad7f68b7d9c249049409c4d8ca67c37",
                "md5": "8210135d488067c28960345e5c474d60",
                "sha256": "a03abe0e2f8925707c3dee88060bea1a94b9a24afc7d07ee17f319022126bcb4"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp310-cp310-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "8210135d488067c28960345e5c474d60",
            "packagetype": "bdist_wheel",
            "python_version": "cp310",
            "requires_python": null,
            "size": 39034,
            "upload_time": "2024-11-22T22:27:00",
            "upload_time_iso_8601": "2024-11-22T22:27:00.531077Z",
            "url": "https://files.pythonhosted.org/packages/49/6b/2fe6abc7f4577f681625b9b374c88ad7f68b7d9c249049409c4d8ca67c37/cymem-2.0.10-cp310-cp310-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "05036dd38133209a100f9e5468dfd60aabf081eb8f4f9bb1fe171601e593dfb6",
                "md5": "3b89b3287dba6633b2cb42020ce88b63",
                "sha256": "18dc5a7b6a325d5fc0b2b40beb02673f36f64655ee086649c91e44ce092c7b36"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp311-cp311-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "3b89b3287dba6633b2cb42020ce88b63",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 41961,
            "upload_time": "2024-11-22T22:27:02",
            "upload_time_iso_8601": "2024-11-22T22:27:02.323692Z",
            "url": "https://files.pythonhosted.org/packages/05/03/6dd38133209a100f9e5468dfd60aabf081eb8f4f9bb1fe171601e593dfb6/cymem-2.0.10-cp311-cp311-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "16d404fe526361d32f823da4a9a7af0ae4be745439c71bf70d15a87da2c48f89",
                "md5": "250f53dd5e9e922525f9fba08487df45",
                "sha256": "d30ce83ff9009e5c5c8186845d9d583f867dace88113089bfc0ee1c348e45d5a"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp311-cp311-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "250f53dd5e9e922525f9fba08487df45",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 41697,
            "upload_time": "2024-11-22T22:27:03",
            "upload_time_iso_8601": "2024-11-22T22:27:03.438330Z",
            "url": "https://files.pythonhosted.org/packages/16/d4/04fe526361d32f823da4a9a7af0ae4be745439c71bf70d15a87da2c48f89/cymem-2.0.10-cp311-cp311-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2f8590d3222ead3a3c12005128100877ee6cb6c280d6cd100f53eaa9dc02d260",
                "md5": "a2ee0cb809ba5997901c81932e50786d",
                "sha256": "ce6cb07416c82633503974f331abde9e1514c90aae8b3240884e749c2a60adbc"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "a2ee0cb809ba5997901c81932e50786d",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 218806,
            "upload_time": "2024-11-22T22:27:05",
            "upload_time_iso_8601": "2024-11-22T22:27:05.149067Z",
            "url": "https://files.pythonhosted.org/packages/2f/85/90d3222ead3a3c12005128100877ee6cb6c280d6cd100f53eaa9dc02d260/cymem-2.0.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a770a12fea4fc0518a076df319aea5c30d13750739447c6d2c7b46d233e6f867",
                "md5": "e9b824a3f9edea404004921ba8104b9c",
                "sha256": "34406e2bff8707719f3f4b262e50b04876369233d5277a7c2d0c2e73a8579b46"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp311-cp311-musllinux_1_2_x86_64.whl",
            "has_sig": false,
            "md5_digest": "e9b824a3f9edea404004921ba8104b9c",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 207061,
            "upload_time": "2024-11-22T22:27:06",
            "upload_time_iso_8601": "2024-11-22T22:27:06.658378Z",
            "url": "https://files.pythonhosted.org/packages/a7/70/a12fea4fc0518a076df319aea5c30d13750739447c6d2c7b46d233e6f867/cymem-2.0.10-cp311-cp311-musllinux_1_2_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b384dd8e3bc7a773abb7d33dc654594323a31e2f79bde3f245feb09dc3f4996d",
                "md5": "40835bf784728726f8788098c34e5bba",
                "sha256": "51218af9645541005a1313d6640bf6e86e7fb4b38a87268a5ea428d50ac3cec2"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp311-cp311-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "40835bf784728726f8788098c34e5bba",
            "packagetype": "bdist_wheel",
            "python_version": "cp311",
            "requires_python": null,
            "size": 39320,
            "upload_time": "2024-11-22T22:27:08",
            "upload_time_iso_8601": "2024-11-22T22:27:08.663797Z",
            "url": "https://files.pythonhosted.org/packages/b3/84/dd8e3bc7a773abb7d33dc654594323a31e2f79bde3f245feb09dc3f4996d/cymem-2.0.10-cp311-cp311-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1727a4383a1f534676f1fccb90e35154b3cd1d333954c756b1b01839b5554169",
                "md5": "35899037133aa825a9109b7da4b9c738",
                "sha256": "c6ed8b1ed448cd65e12405a02aa71b22a4094d8a623205625057c4c73ba4b133"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp312-cp312-macosx_10_13_x86_64.whl",
            "has_sig": false,
            "md5_digest": "35899037133aa825a9109b7da4b9c738",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 42577,
            "upload_time": "2024-11-22T22:27:09",
            "upload_time_iso_8601": "2024-11-22T22:27:09.880966Z",
            "url": "https://files.pythonhosted.org/packages/17/27/a4383a1f534676f1fccb90e35154b3cd1d333954c756b1b01839b5554169/cymem-2.0.10-cp312-cp312-macosx_10_13_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "55de068d791d77c5f46844ee00c56414a6c7d9a3e80a82228ecb17c6530886bc",
                "md5": "ad71c6679cc3f9d5342fba043f2f3802",
                "sha256": "5e57928d9e93c61265281ea01a1d24499d397625b2766a0c5735b99bceb3ba75"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp312-cp312-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "ad71c6679cc3f9d5342fba043f2f3802",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 42206,
            "upload_time": "2024-11-22T22:27:11",
            "upload_time_iso_8601": "2024-11-22T22:27:11.699316Z",
            "url": "https://files.pythonhosted.org/packages/55/de/068d791d77c5f46844ee00c56414a6c7d9a3e80a82228ecb17c6530886bc/cymem-2.0.10-cp312-cp312-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "35aff93d0fdd5f6174038c6745b708bb97e71f4568e7a9b25501ea481e269e3c",
                "md5": "b9cfb70078272fbeab335f1709c98f7c",
                "sha256": "dc4932060a5d55648fa4a3960f1cad9905572ed5c6f02af42f849e869d2803d4"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "b9cfb70078272fbeab335f1709c98f7c",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 227944,
            "upload_time": "2024-11-22T22:27:13",
            "upload_time_iso_8601": "2024-11-22T22:27:13.545041Z",
            "url": "https://files.pythonhosted.org/packages/35/af/f93d0fdd5f6174038c6745b708bb97e71f4568e7a9b25501ea481e269e3c/cymem-2.0.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "8e116bc72829cef14d1598a4c9f9381ac3d8b4e09d98f8496c9042cd994b7f13",
                "md5": "0293b899a7754d1a594d43ebf5c8a0dd",
                "sha256": "f4bc6c823b400d32cddcfeefb3f352d52a0cc911cb0b5c1ef64e3f9741fd56b9"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp312-cp312-musllinux_1_2_x86_64.whl",
            "has_sig": false,
            "md5_digest": "0293b899a7754d1a594d43ebf5c8a0dd",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 216400,
            "upload_time": "2024-11-22T22:27:15",
            "upload_time_iso_8601": "2024-11-22T22:27:15.011759Z",
            "url": "https://files.pythonhosted.org/packages/8e/11/6bc72829cef14d1598a4c9f9381ac3d8b4e09d98f8496c9042cd994b7f13/cymem-2.0.10-cp312-cp312-musllinux_1_2_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "16401b6bdfaab3f80eeb302cd6212c2dcaa735d055db509487cf8da51764b74d",
                "md5": "d1f294cd3e40288b7ab3876d237b0a64",
                "sha256": "6ae7f22af4bc4311f06c925df61c62219c11939dffc9c91d67caf89a7e1557a5"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp312-cp312-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "d1f294cd3e40288b7ab3876d237b0a64",
            "packagetype": "bdist_wheel",
            "python_version": "cp312",
            "requires_python": null,
            "size": 39243,
            "upload_time": "2024-11-22T22:27:16",
            "upload_time_iso_8601": "2024-11-22T22:27:16.279381Z",
            "url": "https://files.pythonhosted.org/packages/16/40/1b6bdfaab3f80eeb302cd6212c2dcaa735d055db509487cf8da51764b74d/cymem-2.0.10-cp312-cp312-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fa88e5c8f44e80a64fdca827f2dd2e323afdef339ae83f1a32763940f40232de",
                "md5": "0d0949b7f273dc0af4df175272bbe7a9",
                "sha256": "5698a515900dc697874444fa05d8d852bbad43543de2e7834ec3895156cc2aad"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp313-cp313-macosx_10_13_x86_64.whl",
            "has_sig": false,
            "md5_digest": "0d0949b7f273dc0af4df175272bbe7a9",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": null,
            "size": 42340,
            "upload_time": "2024-11-22T22:27:17",
            "upload_time_iso_8601": "2024-11-22T22:27:17.870984Z",
            "url": "https://files.pythonhosted.org/packages/fa/88/e5c8f44e80a64fdca827f2dd2e323afdef339ae83f1a32763940f40232de/cymem-2.0.10-cp313-cp313-macosx_10_13_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e4275f76934645f53704fb116802480b21af5c3cbb71ba4661f5af1a1e5ba210",
                "md5": "7606091ee59619d9f644c36b2763bc0a",
                "sha256": "6580d657d0f208d675d62cc052fb908529d52d24282342e24a9843de85352b88"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp313-cp313-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "7606091ee59619d9f644c36b2763bc0a",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": null,
            "size": 41903,
            "upload_time": "2024-11-22T22:27:20",
            "upload_time_iso_8601": "2024-11-22T22:27:20.096406Z",
            "url": "https://files.pythonhosted.org/packages/e4/27/5f76934645f53704fb116802480b21af5c3cbb71ba4661f5af1a1e5ba210/cymem-2.0.10-cp313-cp313-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "76335d62b0e0461aed0a93d3a14a17e0e869d8eab9b2c0e9407f69ff763818ed",
                "md5": "b497f52d4b6c9a4ceb27b82e7a2ce8c2",
                "sha256": "ea72cf0e369f3cf1f10038d572143d88ce7c959222cf7d742acbeb45e00ac5c0"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "b497f52d4b6c9a4ceb27b82e7a2ce8c2",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": null,
            "size": 222927,
            "upload_time": "2024-11-22T22:27:21",
            "upload_time_iso_8601": "2024-11-22T22:27:21.245432Z",
            "url": "https://files.pythonhosted.org/packages/76/33/5d62b0e0461aed0a93d3a14a17e0e869d8eab9b2c0e9407f69ff763818ed/cymem-2.0.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b7ee47f412bdf64ab5ad9d14ce6ed9378a989dac3651f61ae190a5ff9fb866f6",
                "md5": "31368596fe27eb402aa396bcf08fdc48",
                "sha256": "33d7f5014ad36af22995847fccd82ca0bd4b0394fb1d9dd9fef1e8cefdab2444"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp313-cp313-musllinux_1_2_x86_64.whl",
            "has_sig": false,
            "md5_digest": "31368596fe27eb402aa396bcf08fdc48",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": null,
            "size": 219143,
            "upload_time": "2024-11-22T22:27:22",
            "upload_time_iso_8601": "2024-11-22T22:27:22.551186Z",
            "url": "https://files.pythonhosted.org/packages/b7/ee/47f412bdf64ab5ad9d14ce6ed9378a989dac3651f61ae190a5ff9fb866f6/cymem-2.0.10-cp313-cp313-musllinux_1_2_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "38f8a8c04468929043acf8048cce72e438412c7c949f6983b6dc14209e4371ec",
                "md5": "7aab41228af76b9d48124b5185c8a465",
                "sha256": "82f19a39052747309ced6b948b34aff62aa00c795c9d9d3d31a071e8c791efee"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp313-cp313-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "7aab41228af76b9d48124b5185c8a465",
            "packagetype": "bdist_wheel",
            "python_version": "cp313",
            "requires_python": null,
            "size": 39046,
            "upload_time": "2024-11-22T22:27:23",
            "upload_time_iso_8601": "2024-11-22T22:27:23.811539Z",
            "url": "https://files.pythonhosted.org/packages/38/f8/a8c04468929043acf8048cce72e438412c7c949f6983b6dc14209e4371ec/cymem-2.0.10-cp313-cp313-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f92b7d21a744ffd1bb23a1be32d7a5c2654acde45879f50ea5cdf4b98acd344b",
                "md5": "75ec06270cf58c20e63516e8047d2876",
                "sha256": "e644c3c48663d2c0580292e1d636e7eb8885bfe9df75f929d8ad0403621b75fe"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp39-cp39-macosx_10_9_x86_64.whl",
            "has_sig": false,
            "md5_digest": "75ec06270cf58c20e63516e8047d2876",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 42430,
            "upload_time": "2024-11-22T22:27:26",
            "upload_time_iso_8601": "2024-11-22T22:27:26.431729Z",
            "url": "https://files.pythonhosted.org/packages/f9/2b/7d21a744ffd1bb23a1be32d7a5c2654acde45879f50ea5cdf4b98acd344b/cymem-2.0.10-cp39-cp39-macosx_10_9_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "48b84df61a854855a2bbb311236140142ffd823d35dd1b97c988bc8898969be9",
                "md5": "0793a9b8ccb5cf334093db18cbca6155",
                "sha256": "0f2bc8c69a23e3243e3a0c0feca08c9d4454d3cb7934bb11f5e1b3333151d69d"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp39-cp39-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "0793a9b8ccb5cf334093db18cbca6155",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 42182,
            "upload_time": "2024-11-22T22:27:28",
            "upload_time_iso_8601": "2024-11-22T22:27:28.241237Z",
            "url": "https://files.pythonhosted.org/packages/48/b8/4df61a854855a2bbb311236140142ffd823d35dd1b97c988bc8898969be9/cymem-2.0.10-cp39-cp39-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c135dd4e55ba3ebeca0fc71662ad53a150472b9d654e49cda22f3a776687bb0d",
                "md5": "4fb3f2104e4e2a9fcc66052101076555",
                "sha256": "5369f1974854102ee1751577f13acbbb6a13ba73f9fbb44580f8f3275dae0205"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "4fb3f2104e4e2a9fcc66052101076555",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 208176,
            "upload_time": "2024-11-22T22:27:29",
            "upload_time_iso_8601": "2024-11-22T22:27:29.360975Z",
            "url": "https://files.pythonhosted.org/packages/c1/35/dd4e55ba3ebeca0fc71662ad53a150472b9d654e49cda22f3a776687bb0d/cymem-2.0.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "efa964b7d68d6cdcaf0f9c56b665977156ae344ae38d37c01e978916560ebca2",
                "md5": "e03dc1f142243f6b991743b691a250de",
                "sha256": "ffb6181d589e65c46c2d515d8326746a2e0bda31b67c8b1edfbf0663249f84fb"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp39-cp39-musllinux_1_2_x86_64.whl",
            "has_sig": false,
            "md5_digest": "e03dc1f142243f6b991743b691a250de",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 199714,
            "upload_time": "2024-11-22T22:27:31",
            "upload_time_iso_8601": "2024-11-22T22:27:31.492408Z",
            "url": "https://files.pythonhosted.org/packages/ef/a9/64b7d68d6cdcaf0f9c56b665977156ae344ae38d37c01e978916560ebca2/cymem-2.0.10-cp39-cp39-musllinux_1_2_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f956b1e79ace8590d7309d35134214c838cff320bc852194a35ec4da44c5ed07",
                "md5": "adb8ed6c605e73515ca263cff729b2fa",
                "sha256": "9805f7dbf078a0e2eb417b7e1166cedc590887b55e38a3f3ba5349649c93e6be"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10-cp39-cp39-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "adb8ed6c605e73515ca263cff729b2fa",
            "packagetype": "bdist_wheel",
            "python_version": "cp39",
            "requires_python": null,
            "size": 39546,
            "upload_time": "2024-11-22T22:27:32",
            "upload_time_iso_8601": "2024-11-22T22:27:32.730426Z",
            "url": "https://files.pythonhosted.org/packages/f9/56/b1e79ace8590d7309d35134214c838cff320bc852194a35ec4da44c5ed07/cymem-2.0.10-cp39-cp39-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b662eac45989f3d3296133f292f3097cb4c1f9d3ad3e5a85e79bbd2c7f96278f",
                "md5": "0140bc12ee02ca9bbcd99797587aa490",
                "sha256": "f51700acfa1209b4a221dc892cca8030f4bc10d4c153dec098042f484c7f07a4"
            },
            "downloads": -1,
            "filename": "cymem-2.0.10.tar.gz",
            "has_sig": false,
            "md5_digest": "0140bc12ee02ca9bbcd99797587aa490",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 10239,
            "upload_time": "2024-11-22T22:27:33",
            "upload_time_iso_8601": "2024-11-22T22:27:33.875716Z",
            "url": "https://files.pythonhosted.org/packages/b6/62/eac45989f3d3296133f292f3097cb4c1f9d3ad3e5a85e79bbd2c7f96278f/cymem-2.0.10.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-22 22:27:33",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "explosion",
    "github_project": "cymem",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "cymem"
}
        
Elapsed time: 0.64745s