micrograd-cpp-engine 0.1.0__tar.gz

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.
Files changed (113) hide show
  1. micrograd_cpp_engine-0.1.0/.claude/settings.local.json +9 -0
  2. micrograd_cpp_engine-0.1.0/.github/workflows/publish.yml +25 -0
  3. micrograd_cpp_engine-0.1.0/.gitignore +93 -0
  4. micrograd_cpp_engine-0.1.0/CMakeLists.txt +23 -0
  5. micrograd_cpp_engine-0.1.0/Micrograd.docx +0 -0
  6. micrograd_cpp_engine-0.1.0/PKG-INFO +7 -0
  7. micrograd_cpp_engine-0.1.0/PUBLISHING.md +289 -0
  8. micrograd_cpp_engine-0.1.0/README.md +531 -0
  9. micrograd_cpp_engine-0.1.0/docs/architecture.md +54 -0
  10. micrograd_cpp_engine-0.1.0/docs/stability_and_fixes.md +66 -0
  11. micrograd_cpp_engine-0.1.0/examples/01_adder.py +28 -0
  12. micrograd_cpp_engine-0.1.0/examples/02_mlp_xor.py +21 -0
  13. micrograd_cpp_engine-0.1.0/examples/03_toy_regression.py +23 -0
  14. micrograd_cpp_engine-0.1.0/examples/05_custom_op.py +41 -0
  15. micrograd_cpp_engine-0.1.0/examples/06_jit_speedup.py +30 -0
  16. micrograd_cpp_engine-0.1.0/examples/08_save_load.py +34 -0
  17. micrograd_cpp_engine-0.1.0/include/micrograd/active_fn.hpp +14 -0
  18. micrograd_cpp_engine-0.1.0/include/micrograd/adam.hpp +21 -0
  19. micrograd_cpp_engine-0.1.0/include/micrograd/autograd.hpp +29 -0
  20. micrograd_cpp_engine-0.1.0/include/micrograd/device.hpp +30 -0
  21. micrograd_cpp_engine-0.1.0/include/micrograd/dtype.hpp +36 -0
  22. micrograd_cpp_engine-0.1.0/include/micrograd/function.hpp +67 -0
  23. micrograd_cpp_engine-0.1.0/include/micrograd/ir.hpp +82 -0
  24. micrograd_cpp_engine-0.1.0/include/micrograd/ir_fwd.hpp +9 -0
  25. micrograd_cpp_engine-0.1.0/include/micrograd/linear.hpp +24 -0
  26. micrograd_cpp_engine-0.1.0/include/micrograd/loss.hpp +11 -0
  27. micrograd_cpp_engine-0.1.0/include/micrograd/micrograd.hpp +26 -0
  28. micrograd_cpp_engine-0.1.0/include/micrograd/module.hpp +33 -0
  29. micrograd_cpp_engine-0.1.0/include/micrograd/momentum.hpp +17 -0
  30. micrograd_cpp_engine-0.1.0/include/micrograd/op.hpp +67 -0
  31. micrograd_cpp_engine-0.1.0/include/micrograd/op_registry.hpp +44 -0
  32. micrograd_cpp_engine-0.1.0/include/micrograd/optimizer.hpp +27 -0
  33. micrograd_cpp_engine-0.1.0/include/micrograd/relu.hpp +12 -0
  34. micrograd_cpp_engine-0.1.0/include/micrograd/sequential.hpp +16 -0
  35. micrograd_cpp_engine-0.1.0/include/micrograd/serializer.hpp +31 -0
  36. micrograd_cpp_engine-0.1.0/include/micrograd/sgd.hpp +17 -0
  37. micrograd_cpp_engine-0.1.0/include/micrograd/shape.hpp +44 -0
  38. micrograd_cpp_engine-0.1.0/include/micrograd/softmax.hpp +15 -0
  39. micrograd_cpp_engine-0.1.0/include/micrograd/storage.hpp +39 -0
  40. micrograd_cpp_engine-0.1.0/include/micrograd/stream.hpp +30 -0
  41. micrograd_cpp_engine-0.1.0/include/micrograd/tensor.hpp +71 -0
  42. micrograd_cpp_engine-0.1.0/pyproject.toml +20 -0
  43. micrograd_cpp_engine-0.1.0/python/micrograd/__init__.py +17 -0
  44. micrograd_cpp_engine-0.1.0/python/micrograd/data/__init__.py +2 -0
  45. micrograd_cpp_engine-0.1.0/python/micrograd/data/toy_datasets.py +22 -0
  46. micrograd_cpp_engine-0.1.0/python/micrograd/function.py +61 -0
  47. micrograd_cpp_engine-0.1.0/python/micrograd/losses.py +16 -0
  48. micrograd_cpp_engine-0.1.0/python/micrograd/nn/__init__.py +8 -0
  49. micrograd_cpp_engine-0.1.0/python/micrograd/nn/conv.py +64 -0
  50. micrograd_cpp_engine-0.1.0/python/micrograd/nn/linear.py +34 -0
  51. micrograd_cpp_engine-0.1.0/python/micrograd/nn/module.py +40 -0
  52. micrograd_cpp_engine-0.1.0/python/micrograd/nn/relu.py +6 -0
  53. micrograd_cpp_engine-0.1.0/python/micrograd/nn/sequential.py +18 -0
  54. micrograd_cpp_engine-0.1.0/python/micrograd/nn/softmax.py +39 -0
  55. micrograd_cpp_engine-0.1.0/python/micrograd/op_def/__init__.py +23 -0
  56. micrograd_cpp_engine-0.1.0/python/micrograd/optim/__init__.py +5 -0
  57. micrograd_cpp_engine-0.1.0/python/micrograd/optim/adam.py +7 -0
  58. micrograd_cpp_engine-0.1.0/python/micrograd/optim/momentum.py +7 -0
  59. micrograd_cpp_engine-0.1.0/python/micrograd/optim/sgd.py +28 -0
  60. micrograd_cpp_engine-0.1.0/python/micrograd/tensor.py +54 -0
  61. micrograd_cpp_engine-0.1.0/python/micrograd/train/__init__.py +2 -0
  62. micrograd_cpp_engine-0.1.0/python/micrograd/train/loop.py +25 -0
  63. micrograd_cpp_engine-0.1.0/python/micrograd/transforms/__init__.py +5 -0
  64. micrograd_cpp_engine-0.1.0/python/micrograd/transforms/grad.py +33 -0
  65. micrograd_cpp_engine-0.1.0/python/micrograd/transforms/jit.py +24 -0
  66. micrograd_cpp_engine-0.1.0/python/micrograd/transforms/vmap.py +76 -0
  67. micrograd_cpp_engine-0.1.0/src/CMakeLists.txt +55 -0
  68. micrograd_cpp_engine-0.1.0/src/core/active_fn.cpp +19 -0
  69. micrograd_cpp_engine-0.1.0/src/core/adam.cpp +38 -0
  70. micrograd_cpp_engine-0.1.0/src/core/autograd.cpp +103 -0
  71. micrograd_cpp_engine-0.1.0/src/core/function.cpp +140 -0
  72. micrograd_cpp_engine-0.1.0/src/core/ir.cpp +66 -0
  73. micrograd_cpp_engine-0.1.0/src/core/linear.cpp +48 -0
  74. micrograd_cpp_engine-0.1.0/src/core/loss.cpp +44 -0
  75. micrograd_cpp_engine-0.1.0/src/core/module.cpp +42 -0
  76. micrograd_cpp_engine-0.1.0/src/core/momentum.cpp +27 -0
  77. micrograd_cpp_engine-0.1.0/src/core/op.cpp +14 -0
  78. micrograd_cpp_engine-0.1.0/src/core/op_kernels.cpp +643 -0
  79. micrograd_cpp_engine-0.1.0/src/core/op_registry.cpp +175 -0
  80. micrograd_cpp_engine-0.1.0/src/core/optimizer.cpp +15 -0
  81. micrograd_cpp_engine-0.1.0/src/core/relu.cpp +10 -0
  82. micrograd_cpp_engine-0.1.0/src/core/sequential.cpp +21 -0
  83. micrograd_cpp_engine-0.1.0/src/core/serializer.cpp +193 -0
  84. micrograd_cpp_engine-0.1.0/src/core/sgd.cpp +33 -0
  85. micrograd_cpp_engine-0.1.0/src/core/softmax.cpp +44 -0
  86. micrograd_cpp_engine-0.1.0/src/core/storage.cpp +25 -0
  87. micrograd_cpp_engine-0.1.0/src/core/stream.cpp +21 -0
  88. micrograd_cpp_engine-0.1.0/src/core/tensor.cpp +98 -0
  89. micrograd_cpp_engine-0.1.0/src/kernels/cpu/binary_kernels.cpp +52 -0
  90. micrograd_cpp_engine-0.1.0/src/kernels/cpu/binary_kernels.hpp +69 -0
  91. micrograd_cpp_engine-0.1.0/src/kernels/cpu/matmul_kernels.cpp +27 -0
  92. micrograd_cpp_engine-0.1.0/src/kernels/cpu/matmul_kernels.hpp +12 -0
  93. micrograd_cpp_engine-0.1.0/src/kernels/cpu/reduce_kernels.cpp +63 -0
  94. micrograd_cpp_engine-0.1.0/src/kernels/cpu/reduce_kernels.hpp +17 -0
  95. micrograd_cpp_engine-0.1.0/src/kernels/cpu/unary_kernels.cpp +34 -0
  96. micrograd_cpp_engine-0.1.0/src/kernels/cpu/unary_kernels.hpp +15 -0
  97. micrograd_cpp_engine-0.1.0/src/python/module.cpp +25 -0
  98. micrograd_cpp_engine-0.1.0/src/python/py_function.cpp +24 -0
  99. micrograd_cpp_engine-0.1.0/src/python/py_loss.cpp +11 -0
  100. micrograd_cpp_engine-0.1.0/src/python/py_module.cpp +43 -0
  101. micrograd_cpp_engine-0.1.0/src/python/py_op_registry.cpp +13 -0
  102. micrograd_cpp_engine-0.1.0/src/python/py_optim.cpp +37 -0
  103. micrograd_cpp_engine-0.1.0/src/python/py_serializer.cpp +22 -0
  104. micrograd_cpp_engine-0.1.0/src/python/py_tensor.cpp +152 -0
  105. micrograd_cpp_engine-0.1.0/src/python/py_transforms.cpp +13 -0
  106. micrograd_cpp_engine-0.1.0/tests/e2e/test_toy_regression.py +32 -0
  107. micrograd_cpp_engine-0.1.0/tests/e2e/test_xor.py +33 -0
  108. micrograd_cpp_engine-0.1.0/tests/python/test_autograd_gradcheck.py +157 -0
  109. micrograd_cpp_engine-0.1.0/tests/python/test_conv2d.py +166 -0
  110. micrograd_cpp_engine-0.1.0/tests/python/test_module.py +66 -0
  111. micrograd_cpp_engine-0.1.0/tests/python/test_op_def.py +57 -0
  112. micrograd_cpp_engine-0.1.0/tests/python/test_serializer.py +49 -0
  113. micrograd_cpp_engine-0.1.0/tests/python/test_transforms.py +56 -0
@@ -0,0 +1,9 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(python -c ' *)",
5
+ "Bash(pip install *)",
6
+ "Bash(cmake --version)"
7
+ ]
8
+ }
9
+ }
@@ -0,0 +1,25 @@
1
+ name: publish
2
+ on:
3
+ push:
4
+ tags: ['v*']
5
+ jobs:
6
+ build-and-publish:
7
+ runs-on: ubuntu-latest
8
+ permissions:
9
+ id-token: write # required for trusted publishing
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: actions/setup-python@v5
13
+ with:
14
+ python-version: '3.12'
15
+ - name: Install build deps
16
+ run: |
17
+ pip install build
18
+ sudo apt-get update
19
+ sudo apt-get install -y cmake g++
20
+ - name: Build
21
+ run: python -m build --sdist
22
+ - name: Publish to PyPI
23
+ uses: pypa/gh-action-pypi-publish@release/v1
24
+ with:
25
+ packages-dir: dist/
@@ -0,0 +1,93 @@
1
+ # ---- Python ----
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ *.pyd
7
+ .Python
8
+ build/
9
+ develop-eggs/
10
+ dist/
11
+ downloads/
12
+ eggs/
13
+ .eggs/
14
+ lib/
15
+ lib64/
16
+ parts/
17
+ sdist/
18
+ var/
19
+ wheels/
20
+ wheelhouse/
21
+ *.egg-info/
22
+ *.egg
23
+ MANIFEST
24
+
25
+ # ---- Virtual environments ----
26
+ .venv/
27
+ venv/
28
+ env/
29
+ ENV/
30
+ .ENV/
31
+
32
+ # ---- Test / type / lint caches ----
33
+ .pytest_cache/
34
+ .mypy_cache/
35
+ .ruff_cache/
36
+ .coverage
37
+ .coverage.*
38
+ htmlcov/
39
+ .tox/
40
+ .nox/
41
+ .cache
42
+ .pyright_cache/
43
+
44
+ # ---- C++ / CMake build outputs ----
45
+ build*/
46
+ out/
47
+ cmake-build-*/
48
+ CMakeCache.txt
49
+ CMakeFiles/
50
+ CMakeScripts/
51
+ Testing/
52
+ cmake_install.cmake
53
+ install_manifest.txt
54
+ CTestTestfile.cmake
55
+ _deps
56
+ Makefile
57
+ *.ninja
58
+ .ninja_log
59
+ .ninja_deps
60
+ compile_commands.json
61
+ CPM.cmake
62
+ *.o
63
+ *.obj
64
+ *.a
65
+ *.lib
66
+ *.exp
67
+ *.pdb
68
+ *.ilk
69
+
70
+ # ---- IDE / editor ----
71
+ .vscode/
72
+ .idea/
73
+ .vs/
74
+ *.swp
75
+ *.swo
76
+ *~
77
+ .DS_Store
78
+ Thumbs.db
79
+ desktop.ini
80
+ *.code-workspace
81
+
82
+ # ---- Distribution / packaging artifacts ----
83
+ *.whl
84
+ *.tar.gz
85
+ *.zip
86
+
87
+ # ---- Project-specific ----
88
+ # Generated flatbuffer headers (comment out if you commit them)
89
+ /include/micrograd/generated/
90
+
91
+ # Local env files
92
+ .env
93
+ .env.local
@@ -0,0 +1,23 @@
1
+ cmake_minimum_required(VERSION 3.20)
2
+ project(micrograd LANGUAGES CXX)
3
+
4
+ set(CMAKE_CXX_STANDARD 17)
5
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
7
+
8
+ option(MICROGRAD_BUILD_TESTS "Build C++ tests" OFF)
9
+ option(MICROGRAD_BUILD_PYTHON "Build Python bindings" ON)
10
+
11
+ if(MICROGRAD_BUILD_PYTHON)
12
+ find_package(Python REQUIRED COMPONENTS Interpreter Development)
13
+ find_package(pybind11 CONFIG REQUIRED)
14
+ endif()
15
+
16
+ find_package(Threads REQUIRED)
17
+
18
+ add_subdirectory(src)
19
+
20
+ if(MICROGRAD_BUILD_TESTS)
21
+ enable_testing()
22
+ add_subdirectory(tests/cpp)
23
+ endif()
@@ -0,0 +1,7 @@
1
+ Metadata-Version: 2.2
2
+ Name: micrograd-cpp-engine
3
+ Version: 0.1.0
4
+ Summary: A small autograd library with a C++ core and pybind11 Python bindings.
5
+ Requires-Python: >=3.9
6
+ Requires-Dist: numpy>=1.20
7
+
@@ -0,0 +1,289 @@
1
+ # Publishing MicroGrad to PyPI
2
+
3
+ This guide walks through building and publishing the `micrograd` package to
4
+ [PyPI](https://pypi.org/). The project uses
5
+ [`scikit-build-core`](https://scikit-build-core.readthedocs.io/) as its
6
+ build backend, so the standard `python -m build` + `twine` workflow works
7
+ without any extra glue.
8
+
9
+ > **Heads up on the package name.** PyPI package names are
10
+ > case-insensitive and global. Before publishing, search
11
+ > <https://pypi.org/search/?q=micrograd> and pick an available name (or
12
+ > scope under a prefix like `micrograd-cuda`). Update
13
+ > `pyproject.toml` (`[project].name`) and the wheel output name
14
+ > (`OUTPUT_NAME` in `src/CMakeLists.txt`) accordingly.
15
+
16
+ ---
17
+
18
+ ## 1. Prerequisites
19
+
20
+ You need:
21
+
22
+ | Tool | Min version | Install |
23
+ | --- | --- | --- |
24
+ | Python | 3.9 | <https://python.org/downloads/> |
25
+ | `pip` | 23+ | bundled with Python |
26
+ | `cmake` | 3.20+ | <https://cmake.org/download/> |
27
+ | C++ compiler | C++17 | MSVC 2019+, gcc 9+, or clang 10+ |
28
+ | `build` | latest | `pip install build` |
29
+ | `twine` | latest | `pip install twine` |
30
+
31
+ A C++ compiler is required because `scikit-build-core` invokes `cmake` to
32
+ build the `micrograd._C` extension on the user's machine.
33
+
34
+ ---
35
+
36
+ ## 2. One-time PyPI setup
37
+
38
+ 1. Create a PyPI account at <https://pypi.org/account/register/>.
39
+ 2. Enable two-factor authentication (required by PyPI).
40
+ 3. Create an API token at <https://pypi.org/manage/account/token/>.
41
+ Scope the token to the project (or to "Entire account" for the first
42
+ upload).
43
+ 4. (Optional but recommended for CI) configure
44
+ [trusted publishing](https://docs.pypi.org/trusted-publishers/) from
45
+ GitHub Actions so you don't need to manage long-lived tokens.
46
+
47
+ For TestPyPI (recommended dry-run target), repeat the steps at
48
+ <https://test.pypi.org/>.
49
+
50
+ ---
51
+
52
+ ## 3. Configure credentials locally
53
+
54
+ Put your token in `~/.pypirc`:
55
+
56
+ ```ini
57
+ [distutils]
58
+ index-servers =
59
+ pypi
60
+ testpypi
61
+
62
+ [pypi]
63
+ username = __token__
64
+ password = pypi-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
65
+
66
+ [testpypi]
67
+ repository = https://test.pypi.org/legacy/
68
+ username = __token__
69
+ password = pypi-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
70
+ ```
71
+
72
+ `twine` reads this file. Do **not** commit it. The `.gitignore` already
73
+ excludes it via the leading dotfile rules.
74
+
75
+ You can also pass `--username __token__ --password pypi-...` on the
76
+ command line, or use `keyring` (`pip install keyring && keyring set
77
+ https://upload.pypi.org/legacy/ __token__`).
78
+
79
+ ---
80
+
81
+ ## 4. Build the wheel and sdist
82
+
83
+ From the repository root:
84
+
85
+ ```bash
86
+ # Clean any previous build
87
+ rm -rf build/ dist/ *.egg-info
88
+
89
+ # Build sdist + wheel
90
+ python -m build
91
+ ```
92
+
93
+ This runs `scikit-build-core`, which:
94
+
95
+ 1. Compiles the C++ extension via `CMakeLists.txt` → produces
96
+ `micrograd/_C.<plat>.so` (Linux/macOS) or `_C.cp<python>-<plat>.pyd`
97
+ (Windows).
98
+ 2. Bundles `python/micrograd/*.py` and the compiled extension into a
99
+ wheel (`dist/micrograd-0.1.0-*.whl`).
100
+ 3. Produces a source distribution (`dist/micrograd-0.1.0.tar.gz`).
101
+
102
+ Inspect the wheel to verify the layout:
103
+
104
+ ```bash
105
+ unzip -l dist/micrograd-0.1.0-*.whl
106
+ ```
107
+
108
+ You should see `micrograd/__init__.py`, `micrograd/_C.*.so` (or `.pyd`),
109
+ and the rest of the `python/micrograd/` tree.
110
+
111
+ ---
112
+
113
+ ## 5. Smoke-test the wheel locally
114
+
115
+ ```bash
116
+ python -m venv .venv-test
117
+ . .venv-test/bin/activate # Windows: .venv-test\Scripts\activate
118
+ pip install dist/micrograd-0.1.0-*.whl
119
+ python -c "import micrograd; print(micrograd.__version__)"
120
+ python examples/01_adder.py
121
+ ```
122
+
123
+ If the import works and the example prints the expected output, the
124
+ wheel is good to publish.
125
+
126
+ ---
127
+
128
+ ## 6. Publish to TestPyPI first (highly recommended)
129
+
130
+ ```bash
131
+ python -m twine upload --repository testpypi dist/*
132
+ ```
133
+
134
+ This pushes to <https://test.pypi.org/project/micrograd/>. Test the
135
+ install from there in a clean environment:
136
+
137
+ ```bash
138
+ python -m venv .venv-testpypi
139
+ . .venv-testpypi/bin/activate
140
+ pip install --index-url https://test.pypi.org/simple/ \
141
+ --extra-index-url https://pypi.org/simple/ \
142
+ micrograd==0.1.0
143
+ python -c "import micrograd; print(micrograd.__version__)"
144
+ ```
145
+
146
+ (The `--extra-index-url` lets TestPyPI fall back to real PyPI for
147
+ dependencies like `numpy`.)
148
+
149
+ ---
150
+
151
+ ## 7. Publish to PyPI
152
+
153
+ ```bash
154
+ python -m twine upload dist/*
155
+ ```
156
+
157
+ You should see output ending in:
158
+
159
+ ```
160
+ Uploading micrograd-0.1.0-*.whl
161
+ Uploading micrograd-0.1.0.tar.gz
162
+ View at:
163
+ https://pypi.org/project/micrograd/0.1.0/
164
+ ```
165
+
166
+ ---
167
+
168
+ ## 8. Versioning workflow
169
+
170
+ This project follows [Semantic Versioning](https://semver.org/):
171
+ `MAJOR.MINOR.PATCH`.
172
+
173
+ For a new release:
174
+
175
+ 1. Edit `python/micrograd/__init__.py` and bump `__version__`.
176
+ 2. Edit `pyproject.toml` and bump `[project].version` to match.
177
+ 3. Commit the bump:
178
+
179
+ ```bash
180
+ git add python/micrograd/__init__.py pyproject.toml
181
+ git commit -m "Release 0.1.0"
182
+ ```
183
+
184
+ 4. Tag the release:
185
+
186
+ ```bash
187
+ git tag -a v0.1.0 -m "Release 0.1.0"
188
+ git push origin main --tags
189
+ ```
190
+
191
+ 5. Rebuild and re-publish:
192
+
193
+ ```bash
194
+ rm -rf build/ dist/
195
+ python -m build
196
+ python -m twine upload dist/*
197
+ ```
198
+
199
+ PyPI does not allow re-uploading the same version. To fix a release,
200
+ bump to `0.1.1` and re-publish.
201
+
202
+ ---
203
+
204
+ ## 9. Post-publish verification
205
+
206
+ ```bash
207
+ python -m venv .venv-check
208
+ . .venv-check/bin/activate
209
+ pip install --upgrade micrograd
210
+ python -c "import micrograd; print(micrograd.__version__)"
211
+ python examples/01_adder.py
212
+ ```
213
+
214
+ ---
215
+
216
+ ## 10. Common issues
217
+
218
+ ### "File already exists"
219
+ PyPI rejects duplicate uploads. Bump the version in both
220
+ `python/micrograd/__init__.py` and `pyproject.toml`, then rebuild.
221
+
222
+ ### "Invalid distribution filename"
223
+ The wheel name and Python version tags must match what the build
224
+ backend produces. `python -m build` should do the right thing; if you
225
+ renamed the project, check `[project].name` in `pyproject.toml`.
226
+
227
+ ### "CMake Error: CMAKE_CXX_COMPILER not set"
228
+ Install a C++ compiler (see Prerequisites) and re-run `python -m build`.
229
+
230
+ ### "ModuleNotFoundError: No module named 'micrograd._C' after install"
231
+ The C++ extension failed to compile. Re-run
232
+ `python -m build -v` and check the build log. On Windows you typically
233
+ need "Desktop development with C++" from the Visual Studio Build Tools
234
+ installer.
235
+
236
+ ### "ImportError: DLL load failed while importing _C" (Windows)
237
+ The Python version used to build the wheel doesn't match the
238
+ interpreter trying to load it. Build with the same Python (and same
239
+ architecture, e.g. CPython 3.11 x64) you intend to install into.
240
+
241
+ ### "Long description has invalid syntax"
242
+ If you add a long description, make sure the file referenced by
243
+ `[project.readme]` in `pyproject.toml` is valid Markdown or reStructuredText
244
+ and is committed to the repo (or to the sdist).
245
+
246
+ ---
247
+
248
+ ## 11. CI publishing (optional)
249
+
250
+ For trusted publishing from GitHub Actions, add `.github/workflows/publish.yml`:
251
+
252
+ ```yaml
253
+ name: publish
254
+ on:
255
+ push:
256
+ tags: ['v*']
257
+ jobs:
258
+ build-and-publish:
259
+ runs-on: ubuntu-latest
260
+ permissions:
261
+ id-token: write # required for trusted publishing
262
+ steps:
263
+ - uses: actions/checkout@v4
264
+ - uses: actions/setup-python@v5
265
+ with:
266
+ python-version: '3.11'
267
+ - name: Install build deps
268
+ run: |
269
+ pip install build
270
+ sudo apt-get update
271
+ sudo apt-get install -y cmake g++
272
+ - name: Build
273
+ run: python -m build
274
+ - name: Publish to PyPI
275
+ uses: pypa/gh-action-pypi-publish@release/v1
276
+ with:
277
+ packages-dir: dist/
278
+ ```
279
+
280
+ Configure trusted publishing on PyPI:
281
+ <https://docs.pypi.org/trusted-publishers/adding-a-publisher/>.
282
+
283
+ ---
284
+
285
+ ## 12. License reminder
286
+
287
+ `pyproject.toml` should declare a license. If you haven't already, add
288
+ SPDX metadata and either a `LICENSE` file at the repo root or a
289
+ `license = {text = "MIT"}` entry under `[project]`.