summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-04-10 08:54:19 +0000
committerCoprDistGit <infra@openeuler.org>2023-04-10 08:54:19 +0000
commit58742d983e8638b03441fbf7ce597c9eff40500b (patch)
tree30d13b0861d78ed2a02636a55f73ab3cb20ecb16
parent269b232c77331bb9e8ad365b1dc0f5f2a4b90ab0 (diff)
automatic import of python-cymem
-rw-r--r--.gitignore1
-rw-r--r--python-cymem.spec659
-rw-r--r--sources1
3 files changed, 661 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..9710ab2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/cymem-2.0.7.tar.gz
diff --git a/python-cymem.spec b/python-cymem.spec
new file mode 100644
index 0000000..a26ca1c
--- /dev/null
+++ b/python-cymem.spec
@@ -0,0 +1,659 @@
+%global _empty_manifest_terminate_build 0
+Name: python-cymem
+Version: 2.0.7
+Release: 1
+Summary: Manage calls to calloc/free through Cython
+License: MIT
+URL: https://github.com/explosion/cymem
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/b0/d3/50c90dd821e44ad289653f0029d1690fca82f90df293e77e21443f5ea4fc/cymem-2.0.7.tar.gz
+
+
+%description
+<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.
+
+[![Azure Pipelines](https://img.shields.io/azure-devops/build/explosion-ai/public/2/master.svg?logo=azure-pipelines&style=flat-square)](https://dev.azure.com/explosion-ai/public/_build?definitionId=2)
+[![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))
+```
+
+
+%package -n python3-cymem
+Summary: Manage calls to calloc/free through Cython
+Provides: python-cymem
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+BuildRequires: python3-cffi
+BuildRequires: gcc
+BuildRequires: gdb
+%description -n python3-cymem
+<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.
+
+[![Azure Pipelines](https://img.shields.io/azure-devops/build/explosion-ai/public/2/master.svg?logo=azure-pipelines&style=flat-square)](https://dev.azure.com/explosion-ai/public/_build?definitionId=2)
+[![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))
+```
+
+
+%package help
+Summary: Development documents and examples for cymem
+Provides: python3-cymem-doc
+%description help
+<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.
+
+[![Azure Pipelines](https://img.shields.io/azure-devops/build/explosion-ai/public/2/master.svg?logo=azure-pipelines&style=flat-square)](https://dev.azure.com/explosion-ai/public/_build?definitionId=2)
+[![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))
+```
+
+
+%prep
+%autosetup -n cymem-2.0.7
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-cymem -f filelist.lst
+%dir %{python3_sitearch}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Mon Apr 10 2023 Python_Bot <Python_Bot@openeuler.org> - 2.0.7-1
+- Package Spec generated
diff --git a/sources b/sources
new file mode 100644
index 0000000..ff9c02e
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+f9f8b455bb055061e7e0133676556136 cymem-2.0.7.tar.gz