marshmallow-core 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.
- marshmallow_core-0.1.0/.github/workflows/ci.yml +44 -0
- marshmallow_core-0.1.0/.github/workflows/release.yml +78 -0
- marshmallow_core-0.1.0/.gitignore +16 -0
- marshmallow_core-0.1.0/BACKLOG.md +81 -0
- marshmallow_core-0.1.0/CLAUDE.md +145 -0
- marshmallow_core-0.1.0/Cargo.lock +172 -0
- marshmallow_core-0.1.0/Cargo.toml +18 -0
- marshmallow_core-0.1.0/PKG-INFO +140 -0
- marshmallow_core-0.1.0/README.md +121 -0
- marshmallow_core-0.1.0/ROADMAP.md +79 -0
- marshmallow_core-0.1.0/performance/__init__.py +1 -0
- marshmallow_core-0.1.0/performance/analyze_paths.py +139 -0
- marshmallow_core-0.1.0/performance/benchmark.py +121 -0
- marshmallow_core-0.1.0/performance/schemas.py +150 -0
- marshmallow_core-0.1.0/pyproject.toml +31 -0
- marshmallow_core-0.1.0/python/marshmallow_core/__init__.py +28 -0
- marshmallow_core-0.1.0/python/marshmallow_core/_compiler.py +542 -0
- marshmallow_core-0.1.0/python/marshmallow_core/_patch.py +307 -0
- marshmallow_core-0.1.0/run_tests.sh +11 -0
- marshmallow_core-0.1.0/src/lib.rs +1486 -0
- marshmallow_core-0.1.0/tests/test_equivalence.py +1309 -0
- marshmallow_core-0.1.0/tests/test_smoke.py +61 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ci-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: test (py${{ matrix.python-version }})
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ matrix.python-version }}
|
|
26
|
+
|
|
27
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
28
|
+
|
|
29
|
+
- name: Build the wheel (Rust core + Python) and install it
|
|
30
|
+
run: |
|
|
31
|
+
python -m pip install --upgrade pip maturin pytest
|
|
32
|
+
maturin build --release --out dist
|
|
33
|
+
# Pulls stock marshmallow from PyPI as a declared dependency.
|
|
34
|
+
python -m pip install dist/*.whl
|
|
35
|
+
|
|
36
|
+
- name: Run the suite (core active)
|
|
37
|
+
run: pytest -q
|
|
38
|
+
|
|
39
|
+
- name: Run the suite with the core disabled
|
|
40
|
+
env:
|
|
41
|
+
MARSHMALLOW_NO_ACCEL: "1"
|
|
42
|
+
# The handshake tests assert the core is active, so exclude them here;
|
|
43
|
+
# everything else must still pass on the pure-Python fallback.
|
|
44
|
+
run: pytest -q -k "not core_active and not protocol"
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Builds abi3 wheels + sdist on a version tag and publishes them to PyPI via
|
|
4
|
+
# trusted publishing. Setup required once before the first release:
|
|
5
|
+
# 1. Create the PyPI project's trusted publisher pointing at this repo +
|
|
6
|
+
# workflow (https://docs.pypi.org/trusted-publishers/).
|
|
7
|
+
# 2. Create a GitHub Environment named "pypi" (Settings > Environments).
|
|
8
|
+
# Then push a tag like `v0.1.0` (or run manually for a dry run that only builds).
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
push:
|
|
12
|
+
tags: ["v*"]
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
wheels:
|
|
20
|
+
name: wheels-${{ matrix.platform.runner }}-${{ matrix.platform.target }}
|
|
21
|
+
runs-on: ${{ matrix.platform.runner }}
|
|
22
|
+
strategy:
|
|
23
|
+
fail-fast: false
|
|
24
|
+
matrix:
|
|
25
|
+
platform:
|
|
26
|
+
- { runner: ubuntu-latest, target: x86_64, manylinux: auto }
|
|
27
|
+
- { runner: ubuntu-latest, target: aarch64, manylinux: auto }
|
|
28
|
+
# No Intel macOS wheel: the scarce macos-13 (Intel) runners queue for a
|
|
29
|
+
# long time and are being wound down, so they blocked the release. Only
|
|
30
|
+
# Apple-Silicon (arm64) macOS wheels are built; Intel-Mac users install
|
|
31
|
+
# from the sdist (which compiles the Rust core locally).
|
|
32
|
+
- { runner: macos-14, target: aarch64, manylinux: "" }
|
|
33
|
+
- { runner: windows-latest, target: x64, manylinux: "" }
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@v4
|
|
36
|
+
- uses: actions/setup-python@v5
|
|
37
|
+
with:
|
|
38
|
+
python-version: "3.12"
|
|
39
|
+
- name: Build abi3 wheel
|
|
40
|
+
uses: PyO3/maturin-action@v1
|
|
41
|
+
with:
|
|
42
|
+
target: ${{ matrix.platform.target }}
|
|
43
|
+
args: --release --out dist
|
|
44
|
+
manylinux: ${{ matrix.platform.manylinux }}
|
|
45
|
+
- uses: actions/upload-artifact@v4
|
|
46
|
+
with:
|
|
47
|
+
name: wheels-${{ matrix.platform.runner }}-${{ matrix.platform.target }}
|
|
48
|
+
path: dist
|
|
49
|
+
|
|
50
|
+
sdist:
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
steps:
|
|
53
|
+
- uses: actions/checkout@v4
|
|
54
|
+
- name: Build sdist
|
|
55
|
+
uses: PyO3/maturin-action@v1
|
|
56
|
+
with:
|
|
57
|
+
command: sdist
|
|
58
|
+
args: --out dist
|
|
59
|
+
- uses: actions/upload-artifact@v4
|
|
60
|
+
with:
|
|
61
|
+
name: wheels-sdist
|
|
62
|
+
path: dist
|
|
63
|
+
|
|
64
|
+
publish:
|
|
65
|
+
name: Publish to PyPI
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
needs: [wheels, sdist]
|
|
68
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
69
|
+
environment: pypi
|
|
70
|
+
permissions:
|
|
71
|
+
id-token: write # trusted publishing; no API token needed
|
|
72
|
+
steps:
|
|
73
|
+
- uses: actions/download-artifact@v4
|
|
74
|
+
with:
|
|
75
|
+
pattern: wheels-*
|
|
76
|
+
path: dist
|
|
77
|
+
merge-multiple: true
|
|
78
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Backlog
|
|
2
|
+
|
|
3
|
+
Flat, actionable todo list derived from [ROADMAP.md](ROADMAP.md). Work top to
|
|
4
|
+
bottom within a phase.
|
|
5
|
+
|
|
6
|
+
## Phase 0 — Measurement
|
|
7
|
+
|
|
8
|
+
- [x] Create `performance/` directory
|
|
9
|
+
- [x] Port `benchmark.py` from the fork; drive it via `install()`/`uninstall()`
|
|
10
|
+
- [x] Add flat-scalar schema benchmark case
|
|
11
|
+
- [x] Add nested schema benchmark case
|
|
12
|
+
- [x] Add list-heavy schema benchmark case
|
|
13
|
+
- [x] Add validator-heavy schema benchmark case
|
|
14
|
+
- [x] Benchmark `dump`, `load`, `dumps`, `loads` for each case
|
|
15
|
+
- [x] Print a stock-vs-core comparison table
|
|
16
|
+
- [x] Write a coverage probe: report per-field native vs callback for a schema
|
|
17
|
+
- [x] Document how to run the benchmark in README
|
|
18
|
+
|
|
19
|
+
## Phase 1 — Coverage gaps
|
|
20
|
+
|
|
21
|
+
### Hook-bearing load schemas
|
|
22
|
+
- [x] Map out marshmallow 4.x `_do_load` body (pre_load → deserialize → validators → post_load)
|
|
23
|
+
- [x] In `_patched_do_load`, run `pre_load` in Python before the core step
|
|
24
|
+
- [x] Call the core for the per-field deserialize when hooks are present
|
|
25
|
+
- [x] Run field validators in Python after the core step
|
|
26
|
+
- [x] Run schema validators (`validates_schema`) in Python
|
|
27
|
+
- [x] Run `post_load` in Python after the core step
|
|
28
|
+
- [x] Remove the `not _has_load_hooks(self)` guard once the split works
|
|
29
|
+
- [x] Add equivalence tests for pre_load + post_load + validates schemas
|
|
30
|
+
|
|
31
|
+
### Native validators
|
|
32
|
+
- [x] Add a validator tag space (compiler + lib.rs)
|
|
33
|
+
- [x] Native `Range` validator
|
|
34
|
+
- [x] Native `Length` validator
|
|
35
|
+
- [x] Native `OneOf` validator
|
|
36
|
+
- [x] Compile only recognized validators; fall back on any other
|
|
37
|
+
- [x] Equivalence tests: pass + fail inputs for each validator
|
|
38
|
+
|
|
39
|
+
### New field types
|
|
40
|
+
- [x] Native `Decimal` (dump + load)
|
|
41
|
+
- [x] Native `Dict`/`Mapping` (dump + load) — plain dict-copy case
|
|
42
|
+
- [x] Native `Constant`
|
|
43
|
+
- [x] Share `Number` base coercion with Integer/Float — Decimal reuses the
|
|
44
|
+
field's own (`Number`-based) `_serialize`/`_deserialize` rather than
|
|
45
|
+
duplicating coercion in Rust
|
|
46
|
+
- [x] Equivalence tests for each new field type (valid + error)
|
|
47
|
+
|
|
48
|
+
## Phase 2 — Fused JSON path
|
|
49
|
+
|
|
50
|
+
- [x] Add a dump→JSON-bytes core object in `lib.rs` (`DumpSerializer.run_json`)
|
|
51
|
+
- [x] Build the JSON-dump payload in `_compiler.py` (`build_dump_json_serializer`)
|
|
52
|
+
- [x] Wrap `Schema.dumps` in `_patch.py`
|
|
53
|
+
- [x] Equivalence tests: `dumps` output matches stock
|
|
54
|
+
- [~] Add a JSON→loaded core object in `lib.rs` — **implemented + benchmarked,
|
|
55
|
+
not shipped.** A `serde_json`-backed single-pass `LoadDeserializer.run_json`
|
|
56
|
+
was prototyped, but it is consistently *slower* than CPython's C `json.loads`
|
|
57
|
+
followed by the already-accelerated `_do_load` (e.g. nested 2.12µs vs 1.96µs;
|
|
58
|
+
100-record list 60µs vs 37µs). `loads` already benefits from the `_do_load`
|
|
59
|
+
patch, so fusing it only adds a heavy dependency and a regression. Reverted
|
|
60
|
+
per the roadmap's "confirm a real gain, not a regression" rule.
|
|
61
|
+
- [~] Build the JSON-load payload in `_compiler.py` — see above (reverted)
|
|
62
|
+
- [~] Wrap `Schema.loads` in `_patch.py` with `AccelFallback` — see above (reverted)
|
|
63
|
+
- [~] Equivalence tests: `loads` result + errors match stock — verified during the
|
|
64
|
+
prototype (big-int/error/unknown-key parity held); dropped with the revert
|
|
65
|
+
|
|
66
|
+
## Phase 3 — Remaining deferrals + micro-opts
|
|
67
|
+
|
|
68
|
+
- [x] Support `unknown=INCLUDE`
|
|
69
|
+
- [x] Support collection/dotted `partial`
|
|
70
|
+
- [x] Support dotted attribute writes (`set_value`)
|
|
71
|
+
- [x] Cache `_has_load_hooks` on the class (per-class `WeakKeyDictionary`)
|
|
72
|
+
- [x] Precompute the known-keys frozenset once (built per compile, held by the
|
|
73
|
+
Rust `LoadSerializer`)
|
|
74
|
+
|
|
75
|
+
## Per-change checklist (every code item)
|
|
76
|
+
|
|
77
|
+
- [x] Implemented in **both** `_compiler.py` and `lib.rs`
|
|
78
|
+
- [x] Dump/load tags kept in sync
|
|
79
|
+
- [x] Bumped `PROTOCOL_VERSION` + `_EXPECTED_PROTOCOL` if payload/tags changed
|
|
80
|
+
- [x] Equivalence test added (valid + error inputs)
|
|
81
|
+
- [x] Re-ran benchmark to confirm a real gain
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## What this is
|
|
6
|
+
|
|
7
|
+
**marshmallow_core** is a standalone, opt-in Rust acceleration core for the
|
|
8
|
+
published [marshmallow](https://github.com/marshmallow-code/marshmallow) library.
|
|
9
|
+
It installs *alongside* an unmodified `pip install marshmallow` and, when
|
|
10
|
+
activated, monkey-patches `Schema._serialize` / `Schema._do_load` to run a PyO3
|
|
11
|
+
extension instead of marshmallow's per-object Python loops. It is **strictly a
|
|
12
|
+
speedup**: with the core installed, `dump`/`load` produce results identical to
|
|
13
|
+
stock marshmallow, falling back to pure Python for anything not modelled
|
|
14
|
+
natively (and, on load, for *every* error/edge case).
|
|
15
|
+
|
|
16
|
+
Activation is explicit and process-wide:
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
import marshmallow_core
|
|
20
|
+
marshmallow_core.install() # patch marshmallow.Schema
|
|
21
|
+
... # use marshmallow as usual
|
|
22
|
+
marshmallow_core.uninstall() # restore the stock methods
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
This is a mixed Python/Rust project built with **maturin** (`flit`-style src
|
|
26
|
+
layout under `python/`, Rust under `src/`). Python 3.10+ ; the extension is
|
|
27
|
+
`abi3` so one wheel covers all supported versions.
|
|
28
|
+
|
|
29
|
+
## Provenance
|
|
30
|
+
|
|
31
|
+
The Rust core (`src/lib.rs`) and the compiler (`python/marshmallow_core/_compiler.py`)
|
|
32
|
+
were lifted from marshmallow's own `rust-core` branch — `crates/marshmallow-core/src/lib.rs`
|
|
33
|
+
and `src/marshmallow/_accel.py` respectively. The crucial difference: in that
|
|
34
|
+
branch the core is wired *into* `schema.py`; here it lives outside marshmallow
|
|
35
|
+
and patches in from the outside via `_patch.py`. When fixing core logic, the
|
|
36
|
+
upstream branch is the reference implementation to diff against.
|
|
37
|
+
|
|
38
|
+
## Commands
|
|
39
|
+
|
|
40
|
+
Requires `cargo` (rustup) and [`maturin`](https://www.maturin.rs/) (run via `uvx`).
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Build the Rust core + install the package into the current venv (iterating):
|
|
44
|
+
uvx maturin develop --release
|
|
45
|
+
|
|
46
|
+
# Build a wheel without installing (verifies Rust compiles + maturin metadata):
|
|
47
|
+
uvx maturin build --release # -> target/wheels/marshmallow_core-*.whl
|
|
48
|
+
|
|
49
|
+
# Run the suite. IMPORTANT: test against STOCK marshmallow, not a checkout of
|
|
50
|
+
# the fork (the fork has its own baked-in accel and would double-patch). Use a
|
|
51
|
+
# throwaway venv with marshmallow from PyPI:
|
|
52
|
+
WHEEL=$(ls -t target/wheels/*.whl | head -1)
|
|
53
|
+
uv venv /tmp/mc && uv pip install --python /tmp/mc/bin/python marshmallow pytest "$WHEEL"
|
|
54
|
+
/tmp/mc/bin/python -m pytest -q # whole suite
|
|
55
|
+
/tmp/mc/bin/python -m pytest tests/test_equivalence.py::test_load_equivalence -q # one test
|
|
56
|
+
MARSHMALLOW_NO_ACCEL=1 /tmp/mc/bin/python -m pytest -q -k "not core_active and not protocol" # pure-Python path
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`MARSHMALLOW_NO_ACCEL=1` disables the core even after `install()` (the
|
|
60
|
+
pure-Python path is always correct). CI (`.github/workflows/ci.yml`) runs the
|
|
61
|
+
suite on py3.10–3.13 both with the core active and disabled.
|
|
62
|
+
|
|
63
|
+
## Architecture
|
|
64
|
+
|
|
65
|
+
Three Python modules plus one Rust file. Read `_patch.py`, then `_compiler.py`,
|
|
66
|
+
then `src/lib.rs`.
|
|
67
|
+
|
|
68
|
+
### `_patch.py` — the install() shim (replaces the fork's `schema.py` edits)
|
|
69
|
+
|
|
70
|
+
`install()` saves and overwrites `Schema._serialize` and `Schema._do_load`.
|
|
71
|
+
The wrappers try the compiled core and otherwise call the saved originals:
|
|
72
|
+
|
|
73
|
+
- The compiled serializer/deserializer is **cached per Schema instance** on
|
|
74
|
+
`vars(schema)["_mc_dump_serializer"]` / `["_mc_load_deserializer"]` — `_UNSET`
|
|
75
|
+
(not built), `None` (not compilable → always pure Python), or a core object.
|
|
76
|
+
- `_do_load` only attempts the core when the call uses the schema's own
|
|
77
|
+
`unknown`, `partial` is `True`-or-falsy, and the schema has **no load hooks**
|
|
78
|
+
(`_has_load_hooks` checks `pre_load`/`post_load`/`validates`/`validates_schema`).
|
|
79
|
+
On `AccelFallback` from the core it falls through to the original `_do_load`.
|
|
80
|
+
|
|
81
|
+
**Key divergence from the upstream branch:** there, a *root* schema with load
|
|
82
|
+
hooks still uses the core for the per-field step with Python running the hooks
|
|
83
|
+
*around* it. That split lives *inside* `_do_load` and cannot be reproduced by
|
|
84
|
+
wrapping the method from outside, so here **hook-bearing schemas use the
|
|
85
|
+
pure-Python load path entirely**. Correct, just not accelerated. Dump is fully
|
|
86
|
+
accelerated regardless of dump hooks (they run via `dump`, not `_serialize`).
|
|
87
|
+
|
|
88
|
+
### `_compiler.py` — Schema → payload (the "compiler")
|
|
89
|
+
|
|
90
|
+
Inspects a *bound* Schema and compiles it into a recursive tuple "payload"
|
|
91
|
+
describing each field as either **native** (formatted/parsed entirely in Rust)
|
|
92
|
+
or a **callback** (defers to the Python `Field.serialize`/`deserialize`).
|
|
93
|
+
`build_dump_serializer` / `build_load_deserializer` return `None` to mean "use
|
|
94
|
+
pure Python". `is_available()` gates everything (extension importable + protocol
|
|
95
|
+
match + not `MARSHMALLOW_NO_ACCEL`). It reads only attributes present in stock
|
|
96
|
+
marshmallow 4.x.
|
|
97
|
+
|
|
98
|
+
### `src/lib.rs` — the PyO3 core
|
|
99
|
+
|
|
100
|
+
Parses payloads into `DumpSerializer` / `LoadDeserializer`, built as the
|
|
101
|
+
extension `marshmallow_core._core` (`[lib] name = "_core"`, `module-name =
|
|
102
|
+
"marshmallow_core._core"`). The **load** core handles only the happy path: the
|
|
103
|
+
instant it hits any error/edge case it raises `AccelFallback` and Python re-runs
|
|
104
|
+
the unchanged pure-Python load, so every message/value matches exactly.
|
|
105
|
+
`KeyboardInterrupt`/`SystemExit` from a callback propagate unchanged (never
|
|
106
|
+
converted to `AccelFallback`). The **dump core has no `AccelFallback`** — it
|
|
107
|
+
can't defer mid-serialization — so every native dump element must be provably
|
|
108
|
+
identical to `Field._serialize`.
|
|
109
|
+
|
|
110
|
+
### Invariants when changing the core
|
|
111
|
+
|
|
112
|
+
- **Dump and load tag spaces are distinct integers** and must stay in sync
|
|
113
|
+
between `_compiler.py` and `lib.rs`. When adding a native field type, add it
|
|
114
|
+
in *both* (build the element tuple in `_compiler.py`, parse + apply in
|
|
115
|
+
`lib.rs`), keep tags aligned, and verify accel-on output equals accel-off
|
|
116
|
+
output across **valid and error** inputs (`tests/test_equivalence.py`).
|
|
117
|
+
- The extension exports `PROTOCOL_VERSION`; `_compiler._EXPECTED_PROTOCOL` must
|
|
118
|
+
match it. Bump both together when payload shapes/tags change.
|
|
119
|
+
- **What stays pure-Python:** custom `dict_class`/`get_attribute`,
|
|
120
|
+
self-referential schemas, custom strptime temporal formats,
|
|
121
|
+
`NaiveDateTime`/`AwareDateTime` on load, callable defaults, unrecognized field
|
|
122
|
+
validators (anything but `Range`/`Length`/`OneOf`), field-level
|
|
123
|
+
`pre_load`/`post_load`, a `Dict` with key/value fields, and any field type
|
|
124
|
+
without a native element. **Now accelerated** (Phase 1/3): `unknown=INCLUDE`,
|
|
125
|
+
collection/dotted `partial`, dotted attribute writes (`set_value`),
|
|
126
|
+
`Range`/`Length`/`OneOf` validators, `Decimal`/`Dict`/`Constant` fields,
|
|
127
|
+
schema-level load hooks (`pre_load`/`post_load`/`validates`/`validates_schema`
|
|
128
|
+
run in Python around the core's per-field step), and `dumps` (fused to JSON in
|
|
129
|
+
Rust). `loads` is accelerated via the patched load path (a fused JSON *parser*
|
|
130
|
+
was prototyped but did not beat C `json.loads`, so it ships unfused).
|
|
131
|
+
|
|
132
|
+
## Testing conventions
|
|
133
|
+
|
|
134
|
+
`tests/test_equivalence.py` is the source of truth: an autouse fixture calls
|
|
135
|
+
`install()`, and each `_dump_both`/`_load_both` helper runs once accelerated,
|
|
136
|
+
then `monkeypatch`es `_compiler.build_*` to `None` to force the pure path, and
|
|
137
|
+
asserts the two are equal. `tests/test_smoke.py` is a quick install/uninstall +
|
|
138
|
+
equivalence sanity check. New native fields need a case in `test_equivalence.py`.
|
|
139
|
+
|
|
140
|
+
## Development
|
|
141
|
+
|
|
142
|
+
- commit only after passing tests
|
|
143
|
+
- for every big part create a new branch
|
|
144
|
+
- for every small task(feature) make a commit
|
|
145
|
+
- do not commit thing that i'nt make functionality
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 4
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "autocfg"
|
|
7
|
+
version = "1.5.1"
|
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
+
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
|
10
|
+
|
|
11
|
+
[[package]]
|
|
12
|
+
name = "heck"
|
|
13
|
+
version = "0.5.0"
|
|
14
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
15
|
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
16
|
+
|
|
17
|
+
[[package]]
|
|
18
|
+
name = "indoc"
|
|
19
|
+
version = "2.0.7"
|
|
20
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
21
|
+
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
|
|
22
|
+
dependencies = [
|
|
23
|
+
"rustversion",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[[package]]
|
|
27
|
+
name = "libc"
|
|
28
|
+
version = "0.2.186"
|
|
29
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
30
|
+
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
|
31
|
+
|
|
32
|
+
[[package]]
|
|
33
|
+
name = "marshmallow_core"
|
|
34
|
+
version = "0.1.0"
|
|
35
|
+
dependencies = [
|
|
36
|
+
"pyo3",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[[package]]
|
|
40
|
+
name = "memoffset"
|
|
41
|
+
version = "0.9.1"
|
|
42
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
43
|
+
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
|
44
|
+
dependencies = [
|
|
45
|
+
"autocfg",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[[package]]
|
|
49
|
+
name = "once_cell"
|
|
50
|
+
version = "1.21.4"
|
|
51
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
52
|
+
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
53
|
+
|
|
54
|
+
[[package]]
|
|
55
|
+
name = "portable-atomic"
|
|
56
|
+
version = "1.13.1"
|
|
57
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
58
|
+
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
|
59
|
+
|
|
60
|
+
[[package]]
|
|
61
|
+
name = "proc-macro2"
|
|
62
|
+
version = "1.0.106"
|
|
63
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
64
|
+
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
|
65
|
+
dependencies = [
|
|
66
|
+
"unicode-ident",
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
[[package]]
|
|
70
|
+
name = "pyo3"
|
|
71
|
+
version = "0.27.2"
|
|
72
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
73
|
+
checksum = "ab53c047fcd1a1d2a8820fe84f05d6be69e9526be40cb03b73f86b6b03e6d87d"
|
|
74
|
+
dependencies = [
|
|
75
|
+
"indoc",
|
|
76
|
+
"libc",
|
|
77
|
+
"memoffset",
|
|
78
|
+
"once_cell",
|
|
79
|
+
"portable-atomic",
|
|
80
|
+
"pyo3-build-config",
|
|
81
|
+
"pyo3-ffi",
|
|
82
|
+
"pyo3-macros",
|
|
83
|
+
"unindent",
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
[[package]]
|
|
87
|
+
name = "pyo3-build-config"
|
|
88
|
+
version = "0.27.2"
|
|
89
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
90
|
+
checksum = "b455933107de8642b4487ed26d912c2d899dec6114884214a0b3bb3be9261ea6"
|
|
91
|
+
dependencies = [
|
|
92
|
+
"target-lexicon",
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
[[package]]
|
|
96
|
+
name = "pyo3-ffi"
|
|
97
|
+
version = "0.27.2"
|
|
98
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
99
|
+
checksum = "1c85c9cbfaddf651b1221594209aed57e9e5cff63c4d11d1feead529b872a089"
|
|
100
|
+
dependencies = [
|
|
101
|
+
"libc",
|
|
102
|
+
"pyo3-build-config",
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
[[package]]
|
|
106
|
+
name = "pyo3-macros"
|
|
107
|
+
version = "0.27.2"
|
|
108
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
109
|
+
checksum = "0a5b10c9bf9888125d917fb4d2ca2d25c8df94c7ab5a52e13313a07e050a3b02"
|
|
110
|
+
dependencies = [
|
|
111
|
+
"proc-macro2",
|
|
112
|
+
"pyo3-macros-backend",
|
|
113
|
+
"quote",
|
|
114
|
+
"syn",
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
[[package]]
|
|
118
|
+
name = "pyo3-macros-backend"
|
|
119
|
+
version = "0.27.2"
|
|
120
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
121
|
+
checksum = "03b51720d314836e53327f5871d4c0cfb4fb37cc2c4a11cc71907a86342c40f9"
|
|
122
|
+
dependencies = [
|
|
123
|
+
"heck",
|
|
124
|
+
"proc-macro2",
|
|
125
|
+
"pyo3-build-config",
|
|
126
|
+
"quote",
|
|
127
|
+
"syn",
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
[[package]]
|
|
131
|
+
name = "quote"
|
|
132
|
+
version = "1.0.45"
|
|
133
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
134
|
+
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
|
135
|
+
dependencies = [
|
|
136
|
+
"proc-macro2",
|
|
137
|
+
]
|
|
138
|
+
|
|
139
|
+
[[package]]
|
|
140
|
+
name = "rustversion"
|
|
141
|
+
version = "1.0.22"
|
|
142
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
143
|
+
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
|
144
|
+
|
|
145
|
+
[[package]]
|
|
146
|
+
name = "syn"
|
|
147
|
+
version = "2.0.117"
|
|
148
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
149
|
+
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
|
150
|
+
dependencies = [
|
|
151
|
+
"proc-macro2",
|
|
152
|
+
"quote",
|
|
153
|
+
"unicode-ident",
|
|
154
|
+
]
|
|
155
|
+
|
|
156
|
+
[[package]]
|
|
157
|
+
name = "target-lexicon"
|
|
158
|
+
version = "0.13.5"
|
|
159
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
160
|
+
checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
|
161
|
+
|
|
162
|
+
[[package]]
|
|
163
|
+
name = "unicode-ident"
|
|
164
|
+
version = "1.0.24"
|
|
165
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
166
|
+
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
|
167
|
+
|
|
168
|
+
[[package]]
|
|
169
|
+
name = "unindent"
|
|
170
|
+
version = "0.2.4"
|
|
171
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
172
|
+
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "marshmallow_core"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
description = "Rust acceleration core for marshmallow serialization (separate, opt-in package)"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
repository = "https://github.com/gunlinux/marshmallow_core"
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
|
|
10
|
+
[lib]
|
|
11
|
+
name = "_core"
|
|
12
|
+
crate-type = ["cdylib"]
|
|
13
|
+
|
|
14
|
+
[dependencies]
|
|
15
|
+
pyo3 = { version = "0.27", features = ["extension-module", "abi3-py310"] }
|
|
16
|
+
|
|
17
|
+
[profile.release]
|
|
18
|
+
lto = "thin"
|