copium 0.1.dev1__cp314-cp314-win_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of copium might be problematic. Click here for more details.

copium/__about__.pyi ADDED
@@ -0,0 +1,25 @@
1
+ """Version information."""
2
+
3
+ from typing import Literal, NamedTuple, TypeVar, Final, Generic
4
+
5
+ NameT = TypeVar("NameT")
6
+ EmailT = TypeVar("EmailT")
7
+
8
+ class Author(NamedTuple, Generic[NameT, EmailT]):
9
+ name: NameT
10
+ email: EmailT
11
+
12
+ class VersionInfo(NamedTuple):
13
+ major: int
14
+ minor: int
15
+ patch: int
16
+ prerelease: str | None
17
+ build: int | None
18
+ build_hash: str
19
+
20
+ __version__: str
21
+ __version_tuple__: VersionInfo
22
+ __commit_id__: str | None
23
+ __build_hash__: str
24
+
25
+ __authors__: Final[tuple[Author[Literal["Arseny Boykov (Bobronium)"], Literal["hi@bobronium.me"]]]]
copium/__init__.pyi ADDED
@@ -0,0 +1,31 @@
1
+ import sys
2
+ from copy import Error
3
+ from typing import Any, TypeVar
4
+
5
+ __all__ = ["copy", "deepcopy", "Error"]
6
+
7
+ T = TypeVar("T")
8
+
9
+ def copy(x: T) -> T:
10
+ """
11
+ Natively compiled copy.
12
+
13
+ :param x: object to copy.
14
+ :return: shallow copy of the `x`.
15
+ """
16
+
17
+ def deepcopy(x: T, memo: dict[int, Any] | None = None) -> T:
18
+ """
19
+ Natively compiled deepcopy.
20
+
21
+ :param x: object to deepcopy
22
+ :param memo: treat as opaque.
23
+ :return: deep copy of the `x`.
24
+ """
25
+
26
+ if sys.version_info >= (3, 13):
27
+ def replace(obj: T, /, **changes: Any) -> T:
28
+ """
29
+ Creates a new object of the same type as obj, replacing fields with values from changes.
30
+ """
31
+ __all__.append("replace")
copium/extra.pyi ADDED
@@ -0,0 +1,20 @@
1
+ from typing import Callable
2
+ from typing import TypeVar
3
+
4
+ __all__ = ["repeatcall", "replicate"]
5
+
6
+ T = TypeVar("T")
7
+
8
+ def repeatcall(function: Callable[[], T], size: int, /) -> list[T]:
9
+ """
10
+ Call function repeatedly size times and return the list of results.
11
+
12
+ Equivalent of [function() for _ in range(size)], but faster.
13
+ """
14
+
15
+ def replicate(obj: T, /, n: int) -> list[T]:
16
+ """
17
+ Returns n copies of the object in a list.
18
+
19
+ Equivalent of [deepcopy(obj) for _ in range(n)], but faster.
20
+ """
copium/patch.pyi ADDED
@@ -0,0 +1,16 @@
1
+ __all__ = ["enable", "disable", "enabled"]
2
+
3
+ def enable() -> bool:
4
+ """
5
+ :return: True if copium was enabled, False if it was already enabled.
6
+ """
7
+
8
+ def disable() -> bool:
9
+ """
10
+ :return: True if copium was disabled, False if it was already disabled.
11
+ """
12
+
13
+ def enabled() -> bool:
14
+ """
15
+ :return: Whether copium is currently enabled.
16
+ """
copium/py.typed ADDED
File without changes
@@ -0,0 +1,244 @@
1
+ Metadata-Version: 2.4
2
+ Name: copium
3
+ Version: 0.1.dev1
4
+ Summary: Fastest deepcopy implementation for CPython
5
+ Author-email: "Arseny Boykov (Bobronium)" <hi@bobronium.me>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/Bobronium/copium
8
+ Project-URL: Source, https://github.com/Bobronium/copium
9
+ Project-URL: Issues, https://github.com/Bobronium/copium/issues
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Development Status :: 3 - Alpha
18
+ Classifier: Intended Audience :: Developers
19
+ Classifier: Topic :: Software Development :: Libraries
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Provides-Extra: dev
24
+ Requires-Dist: copium[lint]; extra == "dev"
25
+ Requires-Dist: copium[typecheck]; extra == "dev"
26
+ Requires-Dist: copium[test]; extra == "dev"
27
+ Requires-Dist: copium[docs]; extra == "dev"
28
+ Provides-Extra: lint
29
+ Requires-Dist: ruff>=0.5; extra == "lint"
30
+ Provides-Extra: typecheck
31
+ Requires-Dist: mypy>=1.10; extra == "typecheck"
32
+ Requires-Dist: pyright>=1.1.400; extra == "typecheck"
33
+ Requires-Dist: zuban>=0.2.0; extra == "typecheck"
34
+ Requires-Dist: pytest; extra == "typecheck"
35
+ Provides-Extra: test
36
+ Requires-Dist: pytest>=8; extra == "test"
37
+ Requires-Dist: pytest-assert-type>=0.1.5; extra == "test"
38
+ Requires-Dist: indifference>=0.1.0; extra == "test"
39
+ Requires-Dist: typing-extensions; python_version < "3.12" and extra == "test"
40
+ Requires-Dist: datamodelzoo; extra == "test"
41
+ Requires-Dist: pytest-codspeed>=4.2.0; extra == "test"
42
+ Requires-Dist: pytest-test-groups>=1.2.1; extra == "test"
43
+ Provides-Extra: docs
44
+ Requires-Dist: mkdocs-material; extra == "docs"
45
+ Requires-Dist: mkdocstrings[python]; extra == "docs"
46
+ Requires-Dist: mkdocs-autorefs; extra == "docs"
47
+ Requires-Dist: mkdocs-section-index; extra == "docs"
48
+ Provides-Extra: benchmark
49
+ Requires-Dist: tyro>=0.9.33; extra == "benchmark"
50
+ Requires-Dist: pyperf>=2.9.0; extra == "benchmark"
51
+ Requires-Dist: ipython>=8.37.0; extra == "benchmark"
52
+ Requires-Dist: datamodelzoo; extra == "benchmark"
53
+ Provides-Extra: build
54
+ Requires-Dist: build>=1.3.0; extra == "build"
55
+ Requires-Dist: cibuildwheel>=2.23.3; extra == "build"
56
+ Requires-Dist: pip>=25.3; extra == "build"
57
+ Requires-Dist: setuptools>=80.9.0; extra == "build"
58
+ Requires-Dist: setuptools-scm>=9.2.2; extra == "build"
59
+ Requires-Dist: wheel>=0.45.1; extra == "build"
60
+ Dynamic: license-file
61
+
62
+ # copium
63
+
64
+ [![image](https://img.shields.io/pypi/v/copium.svg)](https://pypi.python.org/pypi/copium)
65
+ [![image](https://img.shields.io/pypi/l/copium.svg)](https://pypi.python.org/pypi/copium)
66
+ [![image](https://img.shields.io/pypi/pyversions/copium.svg)](https://pypi.python.org/pypi/copium)
67
+ [![Actions status](https://github.com/Bobronium/copium/actions/workflows/build.yml/badge.svg)](https://github.com/Bobronium/copium/actions)
68
+
69
+ An extremely fast Python copy/deepcopy implementation, written in C.
70
+
71
+ <div align="center">
72
+ <picture>
73
+ <source srcset="https://raw.githubusercontent.com/Bobronium/copium/main/assets/chart_dark.svg" media="(prefers-color-scheme: dark)">
74
+ <source srcset="https://raw.githubusercontent.com/Bobronium/copium/main/assets/chart_light.svg" media="(prefers-color-scheme: light)">
75
+ <img src="https://raw.githubusercontent.com/Bobronium/copium/main/assets/chart_light.svg" alt="Benchmark results bar chart">
76
+ </picture>
77
+ </div>
78
+
79
+ <div align="center">
80
+ <i><code>deepcopy_memo</code> suite from <a href="https://github.com/python/pyperformance/blob/643526f166869c6006009d316be38a35a3cffb2c/pyperformance/data-files/benchmarks/bm_deepcopy/run_benchmark.py#L88">python/pyperformance</a></i>
81
+ </div>
82
+
83
+ ## Highlights
84
+
85
+ - ~3x faster on mixed data
86
+ - ~6x faster on typical data
87
+ - [~30 faster in some cases](#benchmarks)
88
+ - [Requires **zero** code changes to adopt](#1-you-set-copium_patch_deepcopy1-before-launch)
89
+ - Passes all tests from `CPython/Lib/test/test_copy.py`
90
+
91
+ ## Installation
92
+
93
+ ```bash
94
+ pip install copium
95
+ ```
96
+
97
+ ## Usage
98
+
99
+ `copium` is designed to be drop-in replacement for `copy` module.
100
+
101
+ After installation deepcopy will be fast in either of 3 cases:
102
+
103
+ ##### 1) You set `COPIUM_PATCH_DEEPCOPY=1` before launch
104
+
105
+ ##### 2) You call `copium.patch.enable()` manually at launch
106
+
107
+ ##### 3) You use `copium.deepcopy()` directly
108
+
109
+ Generally any code that uses stdlib `copy` can be replaced with `copium` simply by:
110
+
111
+ ```diff
112
+ - from copy import deepcopy
113
+ + from copium import deepcopy
114
+ ```
115
+
116
+ Alternatively, you can import `copium.patch` once and enable it:
117
+
118
+ ```python
119
+ import copium.patch
120
+
121
+
122
+ copium.patch.enable()
123
+ ```
124
+
125
+ Or just `export COPIUM_PATCH_DEEPCOPY=1` before running your Python process.
126
+
127
+ This will automatically call `copium.patch.enable()` on start, and all calls to `copy.deepcopy()` will be forwarded to
128
+ `copium.deepcopy()`. On Python 3.12+ there's no performance overhead compared to direct
129
+ usage.
130
+
131
+ There are two main benefits of using `copium.patch`,
132
+
133
+ - It requires zero code changes
134
+ - It automatically makes any third party code that uses deepcopy faster, for
135
+ instance, it will speed up instantiations of pydantic
136
+ models with mutable defaults
137
+ \(see [pydantic_core](https://github.com/pydantic/pydantic-core/blob/f1239f81d944bcda84bffec64527d46f041ccc9e/src/validators/with_default.rs#L23)).
138
+
139
+ ## Caveats
140
+
141
+ - `copium.deepcopy()` ignores `sys.getrecursionlimit()`. It still may raise `RecursionError` at some point, but at much
142
+ larger depths than default interpreter recursion limit (see `tests.test_copium.test_recursion_error`)
143
+ - unless `memo` argument supplied as `dict` when calling `copium.deepcopy()`, special lightweight memo storage will be
144
+ used to reduce memoization overhead. It implements `MutableMapping` methods, so any custom `__deepcopy__` methods
145
+ should work as expected
146
+ - `copium.deepcopy()` will raise `TypeError` if `type(memo) is not dict` — if you're unsure what it means, don't worry —
147
+ you don't need to supply memo to deepcopy in the first place.
148
+ - `copium` uses unstable CPython API. This means that it might break on new major Python release
149
+
150
+ ## Benchmarks
151
+
152
+ A full benchmark suite is in progress and will be published soon.
153
+ In the meanwhile, you can reproduce the results shown in the chart above with this minimal script
154
+
155
+ <details>
156
+ <summary>Pyperf case</summary>
157
+
158
+ ```shell
159
+ cat > benchmark.py << 'PY'
160
+ # /// script
161
+ # requires-python = ">=3.10"
162
+ # dependencies = [
163
+ # "pyperf",
164
+ # "copium",
165
+ # ]
166
+ # ///
167
+ import pyperf
168
+
169
+ runner = pyperf.Runner()
170
+
171
+ setup = """
172
+ import copy
173
+ from decimal import Decimal
174
+
175
+ payload = {
176
+ "a": 1,
177
+ "b": (b := [(1, 2, 3), (4, 5, 6)]),
178
+ "c": [Decimal("3.14"), complex(), [], (), frozenset(), b],
179
+ }
180
+ """
181
+
182
+ runner.timeit(name="deepcopy", stmt=f"b=copy.deepcopy(payload)", setup=setup)
183
+ PY
184
+ ```
185
+
186
+ ```shell
187
+ uv run --python 3.14t benchmark.py -q -o copy3.14t.json && \
188
+ COPIUM_PATCH_DEEPCOPY=1 PYTHON_GIL=0 \
189
+ uv run --python 3.14t benchmark.py -q -o copium3.14t.json --copy-env && \
190
+ uvx pyperf compare_to copy3.14t.json copium3.14t.json --table
191
+ ```
192
+
193
+ Output:
194
+
195
+ ```shell
196
+ deepcopy: Mean +- std dev: 20.8 us +- 1.6 us
197
+ deepcopy: Mean +- std dev: 928 ns +- 11 ns
198
+ +--------------+---------+--------------------+
199
+ | Benchmark | copy | copium |
200
+ +===========+=========+=======================+
201
+ | deepcopy | 20.8 us | 928 ns: 22.40x faster |
202
+ +-----------+---------+-----------------------+
203
+ ```
204
+
205
+ ```shell
206
+ ❯ uv run --python 3.13 benchmark.py -q -o copy3.13.json && \
207
+ COPIUM_PATCH_DEEPCOPY=1 \
208
+ uv run --python 3.13 benchmark.py -q -o copium3.13.json --copy-env && \
209
+ uvx pyperf compare_to copy3.13.json copium3.13.json --table
210
+ ```
211
+
212
+ ```shell
213
+ deepcopy: Mean +- std dev: 10.8 us +- 0.9 us
214
+ deepcopy: Mean +- std dev: 880 ns +- 23 ns
215
+ +-----------+-----------+-----------------------+
216
+ | Benchmark | copy3.13t | copium3.13t |
217
+ +===========+===========+=======================+
218
+ | deepcopy | 10.8 us | 880 ns: 12.26x faster |
219
+ +-----------+-----------+-----------------------+
220
+ ```
221
+
222
+ ```shell
223
+ ❯ uv run --python 3.13t benchmark.py -q -o copy3.13t.json && \
224
+ COPIUM_PATCH_DEEPCOPY=1 PYTHON_GIL=0 \
225
+ uv run --python 3.13t benchmark.py -q -o copium3.13t.json --copy-env && \
226
+ uvx pyperf compare_to copy3.13t.json copium3.13t.json --table
227
+ ```
228
+
229
+ ```shell
230
+ deepcopy: Mean +- std dev: 29.0 us +- 6.7 us
231
+ deepcopy: Mean +- std dev: 942 ns +- 29 ns
232
+ +-----------+-----------+-----------------------+
233
+ | Benchmark | copy3.13t | copium3.13t |
234
+ +===========+===========+=======================+
235
+ | deepcopy | 29.0 us | 942 ns: 30.84x faster |
236
+ +-----------+-----------+-----------------------+
237
+ ```
238
+
239
+ </details>
240
+
241
+ ## Development
242
+
243
+ - Install Task: https://taskfile.dev
244
+ - All checks: `task` / `task MATRIX=1`
@@ -0,0 +1,12 @@
1
+ copium.cp314-win_arm64.pyd,sha256=z_EmWbrKQa4kDxh97r01bPZBPdI_D5TjoPkH0In1mtY,77312
2
+ copium_autopatch.pth,sha256=NCHGm5AZ9EpUpfXXpDHYK5boi4wWP2H_RO9Q9_gOXFg,110
3
+ copium/__about__.pyi,sha256=lWT2-HImwGj9mt9I5rf7DiBIw4VMIUr3Xu3HJSKo90k,597
4
+ copium/__init__.pyi,sha256=KRiIlDGPPtyRYskLnol3dwAAq8fQMBUO4WbkjFXjSJg,737
5
+ copium/extra.pyi,sha256=-4xYscNJStfi1OWCujQySrG1I9n765H4hvFCSSy0cUA,529
6
+ copium/patch.pyi,sha256=3cRRiGtORimaqGJuK6LRo0_11I8pVm8Lm8UhqjiwtBQ,378
7
+ copium/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ copium-0.1.dev1.dist-info/licenses/LICENSE,sha256=MjA6uIe4yQtub-SeLwMcoBsjtRkOI2RH2U4ZRGhNx2k,1096
9
+ copium-0.1.dev1.dist-info/METADATA,sha256=_CwqJXIM3h5EzhS_0pRUfT6nsXDX7gPDJmRD44k91CA,9081
10
+ copium-0.1.dev1.dist-info/WHEEL,sha256=bMXkUWfr_3hlaRObp_pv9_U0ksvQo0T0Mwq6lQkXaZc,101
11
+ copium-0.1.dev1.dist-info/top_level.txt,sha256=GZDlOGAVPhG7xdRAtxyamzeXrv8DCjarx47lcsT-XFI,7
12
+ copium-0.1.dev1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: false
4
+ Tag: cp314-cp314-win_arm64
5
+
@@ -0,0 +1,18 @@
1
+ MIT License
2
+
3
+ Copyright (c) <year> <copyright holders>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6
+ associated documentation files (the "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
9
+ following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial
12
+ portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15
+ LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
16
+ EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ copium
Binary file
copium_autopatch.pth ADDED
@@ -0,0 +1 @@
1
+ import os, sys; os.environ.get('COPIUM_PATCH_DEEPCOPY') == '1' and __import__('copium.patch').patch.enable()