libibt 0.0.1__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 (36) hide show
  1. libibt-0.0.1/.github/workflows/check.yml +49 -0
  2. libibt-0.0.1/.github/workflows/publish.yml +188 -0
  3. libibt-0.0.1/.github/workflows/pyodide.yml +85 -0
  4. libibt-0.0.1/.gitignore +39 -0
  5. libibt-0.0.1/.python-version +1 -0
  6. libibt-0.0.1/CLAUDE.md +61 -0
  7. libibt-0.0.1/Cargo.lock +904 -0
  8. libibt-0.0.1/Cargo.toml +22 -0
  9. libibt-0.0.1/PKG-INFO +177 -0
  10. libibt-0.0.1/README.md +152 -0
  11. libibt-0.0.1/justfile +95 -0
  12. libibt-0.0.1/pyproject.toml +106 -0
  13. libibt-0.0.1/reference/ibt_parser.py +374 -0
  14. libibt-0.0.1/rust/src/channel.rs +129 -0
  15. libibt-0.0.1/rust/src/error.rs +22 -0
  16. libibt-0.0.1/rust/src/header.rs +147 -0
  17. libibt-0.0.1/rust/src/lib.rs +155 -0
  18. libibt-0.0.1/rust/src/reader.rs +246 -0
  19. libibt-0.0.1/rust/src/session_info.rs +49 -0
  20. libibt-0.0.1/rust/src/var_header.rs +138 -0
  21. libibt-0.0.1/scripts/pyodide_tests/run_unit_tests.py +79 -0
  22. libibt-0.0.1/scripts/pyodide_tests/test_bytes_input.py +117 -0
  23. libibt-0.0.1/scripts/run_pyodide_tests.mjs +143 -0
  24. libibt-0.0.1/scripts/run_pyodide_tests_idbfs.mjs +123 -0
  25. libibt-0.0.1/src/libibt/__init__.py +6 -0
  26. libibt-0.0.1/src/libibt/_libibt_rs.pyi +10 -0
  27. libibt-0.0.1/src/libibt/base.py +290 -0
  28. libibt-0.0.1/src/libibt/py.typed +0 -0
  29. libibt-0.0.1/tests/conftest.py +27 -0
  30. libibt-0.0.1/tests/test_channels.py +108 -0
  31. libibt-0.0.1/tests/test_cross_validation.py +187 -0
  32. libibt-0.0.1/tests/test_data/test.ibt +0 -0
  33. libibt-0.0.1/tests/test_logfile.py +192 -0
  34. libibt-0.0.1/tests/test_parse.py +90 -0
  35. libibt-0.0.1/tests/test_reference.py +204 -0
  36. libibt-0.0.1/uv.lock +786 -0
@@ -0,0 +1,49 @@
1
+ name: Check
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ concurrency:
9
+ group: ${{ github.workflow }}-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ jobs:
13
+ check:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: actions-rust-lang/setup-rust-toolchain@v1
19
+ with:
20
+ toolchain: stable
21
+ components: rustfmt, clippy
22
+
23
+ - uses: astral-sh/setup-uv@v5
24
+ with:
25
+ enable-cache: true
26
+
27
+ - name: Set up Python
28
+ run: uv python install 3.12
29
+
30
+ - name: Check Rust formatting
31
+ run: cargo fmt --check
32
+
33
+ - name: Clippy lints
34
+ run: cargo clippy --all-targets -- -W clippy::all
35
+
36
+ - name: Rust tests
37
+ run: cargo test
38
+
39
+ - name: Install Python dependencies
40
+ run: uv sync
41
+
42
+ - name: Check Python formatting
43
+ run: uv run black --check .
44
+
45
+ - name: Type check
46
+ run: uv run mypy src/
47
+
48
+ - name: Python tests
49
+ run: uv run pytest tests/ -v
@@ -0,0 +1,188 @@
1
+ name: Build and Publish
2
+
3
+ on:
4
+ push:
5
+ branches: [ master, main ]
6
+ pull_request:
7
+ branches: [ master, main ]
8
+ release:
9
+ types: [published]
10
+ workflow_dispatch:
11
+ inputs:
12
+ publish_to_pypi:
13
+ description: 'Publish to PyPI'
14
+ required: true
15
+ default: 'false'
16
+ type: boolean
17
+
18
+ jobs:
19
+ check:
20
+ name: Lint and test
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - uses: actions-rust-lang/setup-rust-toolchain@v1
26
+ with:
27
+ toolchain: stable
28
+ components: rustfmt, clippy
29
+
30
+ - uses: astral-sh/setup-uv@v5
31
+ with:
32
+ enable-cache: true
33
+
34
+ - name: Set up Python
35
+ run: uv python install 3.12
36
+
37
+ - name: Check Rust formatting
38
+ run: cargo fmt --check
39
+
40
+ - name: Clippy lints
41
+ run: cargo clippy --all-targets -- -W clippy::all
42
+
43
+ - name: Rust tests
44
+ run: cargo test
45
+
46
+ - name: Install Python dependencies
47
+ run: uv sync
48
+
49
+ - name: Check Python formatting
50
+ run: uv run black --check .
51
+
52
+ - name: Type check
53
+ run: uv run mypy src/
54
+
55
+ build-wheels:
56
+ name: Build wheel (${{ matrix.os }}, Python ${{ matrix.python-version }})
57
+ needs: check
58
+ runs-on: ${{ matrix.os }}
59
+ strategy:
60
+ fail-fast: false
61
+ matrix:
62
+ # Note: windows-11-arm excluded until pyarrow publishes Windows ARM64 wheels
63
+ os: [ubuntu-latest, ubuntu-24.04-arm, macos-15-intel, macos-latest, windows-latest]
64
+ python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
65
+
66
+ steps:
67
+ - uses: actions/checkout@v4
68
+
69
+ - name: Install Rust toolchain
70
+ uses: dtolnay/rust-toolchain@stable
71
+
72
+ - name: Install uv
73
+ uses: astral-sh/setup-uv@v5
74
+
75
+ - name: Build wheel
76
+ run: uvx cibuildwheel==3.3.1 --output-dir wheelhouse
77
+ env:
78
+ CIBW_BUILD: "cp${{ matrix.python-version == '3.10' && '310' || matrix.python-version == '3.11' && '311' || matrix.python-version == '3.12' && '312' || matrix.python-version == '3.13' && '313' || '314' }}-*"
79
+ CIBW_BUILD_VERBOSITY: 1
80
+ CIBW_BEFORE_BUILD: "pip install numpy"
81
+ # Install Rust inside manylinux container (host toolchain not available)
82
+ CIBW_BEFORE_ALL_LINUX: "curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable -y"
83
+ CIBW_ENVIRONMENT_LINUX: 'PATH="$HOME/.cargo/bin:$PATH"'
84
+ # Build only native arch per runner (no cross-compilation or emulation)
85
+ CIBW_ARCHS_LINUX: "native"
86
+ CIBW_ARCHS_MACOS: "native"
87
+ CIBW_ARCHS_WINDOWS: "native"
88
+ CIBW_ENVIRONMENT_MACOS: 'MACOSX_DEPLOYMENT_TARGET=10.13'
89
+
90
+ - name: Upload wheel
91
+ uses: actions/upload-artifact@v4
92
+ with:
93
+ name: wheel-${{ matrix.os }}-${{ matrix.python-version }}
94
+ path: ./wheelhouse/*.whl
95
+
96
+ build-sdist:
97
+ name: Build source distribution
98
+ runs-on: ubuntu-latest
99
+
100
+ steps:
101
+ - uses: actions/checkout@v4
102
+
103
+ - name: Install uv
104
+ uses: astral-sh/setup-uv@v5
105
+
106
+ - name: Build sdist
107
+ run: uv build --sdist
108
+
109
+ - name: Upload sdist
110
+ uses: actions/upload-artifact@v4
111
+ with:
112
+ name: sdist
113
+ path: dist/*.tar.gz
114
+
115
+ test-wheels:
116
+ name: Test wheel (${{ matrix.os }}, Python ${{ matrix.python-version }})
117
+ runs-on: ${{ matrix.os }}
118
+ needs: build-wheels
119
+ strategy:
120
+ fail-fast: false
121
+ matrix:
122
+ # Note: windows-11-arm excluded until pyarrow publishes Windows ARM64 wheels
123
+ os: [ubuntu-latest, ubuntu-24.04-arm, macos-15-intel, macos-latest, windows-latest]
124
+ python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
125
+
126
+ steps:
127
+ - uses: actions/checkout@v4
128
+
129
+ - name: Install uv
130
+ uses: astral-sh/setup-uv@v5
131
+
132
+ - name: Download wheel artifact
133
+ uses: actions/download-artifact@v4
134
+ with:
135
+ name: wheel-${{ matrix.os }}-${{ matrix.python-version }}
136
+ path: dist/
137
+
138
+ - name: Create venv and install wheel (Unix)
139
+ if: runner.os != 'Windows'
140
+ run: |
141
+ uv venv .venv --python ${{ matrix.python-version }}
142
+ WHEEL=$(ls dist/*.whl | head -1)
143
+ uv pip install --python .venv "${WHEEL}[test]"
144
+
145
+ - name: Create venv and install wheel (Windows)
146
+ if: runner.os == 'Windows'
147
+ shell: pwsh
148
+ run: |
149
+ uv venv .venv --python ${{ matrix.python-version }}
150
+ $wheel = (Get-ChildItem dist/*.whl | Select-Object -First 1).FullName
151
+ uv pip install --python .venv "${wheel}[test]"
152
+
153
+ - name: Run tests
154
+ run: uv run --python .venv pytest tests/ -v --tb=short
155
+
156
+ publish:
157
+ name: Publish to PyPI
158
+ runs-on: ubuntu-latest
159
+ needs: [build-wheels, build-sdist, test-wheels]
160
+ if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.publish_to_pypi == true)
161
+ environment:
162
+ name: pypi
163
+ url: https://pypi.org/p/libibt
164
+
165
+ permissions:
166
+ id-token: write
167
+ contents: write
168
+
169
+ steps:
170
+ - name: Download all artifacts
171
+ uses: actions/download-artifact@v4
172
+ with:
173
+ path: dist/
174
+ merge-multiple: true
175
+
176
+ - name: List artifacts
177
+ run: ls -la dist/
178
+
179
+ - name: Publish to PyPI
180
+ uses: pypa/gh-action-pypi-publish@release/v1
181
+ with:
182
+ packages-dir: dist/
183
+
184
+ - name: Upload assets to GitHub Release
185
+ if: github.event_name == 'release'
186
+ env:
187
+ GH_TOKEN: ${{ github.token }}
188
+ run: gh release upload "${{ github.event.release.tag_name }}" dist/* --repo "${{ github.repository }}"
@@ -0,0 +1,85 @@
1
+ name: Pyodide (WebAssembly) Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [ master, main ]
6
+ pull_request:
7
+ branches: [ master, main ]
8
+
9
+ jobs:
10
+ pyodide-build:
11
+ runs-on: ubuntu-latest
12
+ name: Build wheel for Pyodide
13
+
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.13"
21
+
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v4
24
+
25
+ - name: Install Rust nightly with wasm32-unknown-emscripten
26
+ uses: dtolnay/rust-toolchain@nightly
27
+ with:
28
+ targets: wasm32-unknown-emscripten
29
+ components: rust-src
30
+
31
+ - name: Install Emscripten SDK
32
+ uses: mymindstorm/setup-emsdk@v14
33
+ with:
34
+ version: "4.0.9"
35
+
36
+ - name: Install pyodide-build
37
+ run: |
38
+ uv pip install --system --prerelease=allow "wheel<0.44.0"
39
+ uv pip install --system --prerelease=allow pyodide-build==0.29.3
40
+
41
+ - name: Install Pyodide xbuildenv
42
+ run: pyodide xbuildenv install 0.29.3
43
+
44
+ - name: Build wheel for Pyodide
45
+ run: pyodide build --exports whole_archive
46
+ env:
47
+ RUSTUP_TOOLCHAIN: nightly
48
+ CARGO_BUILD_TARGET: wasm32-unknown-emscripten
49
+ RUSTFLAGS: "-Zemscripten-wasm-eh"
50
+ PYO3_CROSS_PYTHON_VERSION: "3.13"
51
+
52
+ - name: Upload wheel artifact
53
+ uses: actions/upload-artifact@v4
54
+ with:
55
+ name: pyodide-wheel
56
+ path: dist/*.whl
57
+ retention-days: 7
58
+
59
+ pyodide-test:
60
+ runs-on: ubuntu-latest
61
+ needs: pyodide-build
62
+ name: Test with Pyodide
63
+
64
+ steps:
65
+ - uses: actions/checkout@v4
66
+
67
+ - name: Install Node.js
68
+ uses: actions/setup-node@v4
69
+ with:
70
+ node-version: '20'
71
+
72
+ - name: Download wheel artifact
73
+ uses: actions/download-artifact@v4
74
+ with:
75
+ name: pyodide-wheel
76
+ path: dist/
77
+
78
+ - name: Install Pyodide
79
+ run: npm install pyodide@0.29.3
80
+
81
+ - name: Run unit tests in Pyodide
82
+ run: node scripts/run_pyodide_tests.mjs --dist-dir=./dist
83
+
84
+ - name: Run bytes input tests in Pyodide
85
+ run: node scripts/run_pyodide_tests_idbfs.mjs --dist-dir=./dist
@@ -0,0 +1,39 @@
1
+ # Rust
2
+ target/
3
+ Cargo.lock
4
+
5
+ # Python
6
+ __pycache__/
7
+ *.py[cod]
8
+ *.so
9
+ *.pyd
10
+ *.egg-info/
11
+ dist/
12
+ build/
13
+ .eggs/
14
+
15
+ # Virtual environments
16
+ .venv/
17
+ venv/
18
+
19
+ # IDE
20
+ .idea/
21
+ .vscode/
22
+ *.swp
23
+
24
+ # OS
25
+ .DS_Store
26
+ Thumbs.db
27
+
28
+ # Test data (IBT files are large)
29
+ *.ibt
30
+ !tests/test_data/*.ibt
31
+
32
+ # Claude local settings
33
+ .claude/settings.local.json
34
+
35
+ # Pyodide
36
+ .pyodide-xbuildenv-*/
37
+ node_modules/
38
+ package.json
39
+ package-lock.json
@@ -0,0 +1 @@
1
+ 3.12
libibt-0.0.1/CLAUDE.md ADDED
@@ -0,0 +1,61 @@
1
+ # libibt — Agent Instructions
2
+
3
+ ## Project overview
4
+
5
+ Python library for reading iRacing IBT telemetry files. Rust core parses the binary format, PyO3 bridges to Python, and a Python `LogFile` dataclass provides the user-facing API. Data is returned as PyArrow tables.
6
+
7
+ ## Source control
8
+
9
+ **Use `sl` (Sapling) only. Never use `git`.**
10
+
11
+ ## Architecture
12
+
13
+ ```
14
+ rust/src/
15
+ lib.rs — PyO3 module + ibt() entry point
16
+ reader.rs — IbtFile: mmap, header parsing, channel extraction
17
+ header.rs — Binary header structs
18
+ var_header.rs — Variable header parsing (name, type, offset)
19
+ channel.rs — Arrow RecordBatch construction per channel
20
+ session_info.rs — Session YAML extraction
21
+ error.rs — Error types
22
+
23
+ src/libibt/
24
+ __init__.py — Public API: ibt(), LogFile
25
+ base.py — LogFile dataclass (channels, laps, metadata, filtering, resampling)
26
+ _libibt_rs.pyi — Type stubs for the Rust extension
27
+
28
+ tests/
29
+ test_parse.py — Basic parsing tests
30
+ test_reference.py — Cross-validation against reference parser
31
+ test_channels.py — Channel data tests
32
+ test_logfile.py — LogFile method tests
33
+ ```
34
+
35
+ ## Build and test
36
+
37
+ ```bash
38
+ uv sync # Install dependencies
39
+ just build # Build Rust extension (release)
40
+ just build-debug # Build Rust extension (debug, faster)
41
+ just test # uv run pytest tests/ -v
42
+ just check # All checks: lint, clippy, typecheck, test-rust, test
43
+ just format # Black + cargo fmt
44
+ just typecheck # mypy src/
45
+ just clippy # Rust lints
46
+ ```
47
+
48
+ Always use `uv run` for Python commands, never bare `python` or `pytest`.
49
+
50
+ ## Key details
51
+
52
+ - **Python >=3.10**, Rust 2021 edition
53
+ - **Dependencies**: pyarrow, numpy (version-constrained by Python version)
54
+ - **Build system**: maturin (configured in pyproject.toml)
55
+ - **Formatter**: Black (line-length 100)
56
+ - **Type checker**: mypy (strict optional, check untyped defs)
57
+ - **Timecodes**: int64 milliseconds throughout
58
+ - **Channels**: each is a 2-column PyArrow table (`timecodes` + value), with field metadata (units, desc, interpolate)
59
+ - **Laps**: PyArrow table with columns `num`, `start_time`, `end_time` (all ms)
60
+ - **Array variables** (count > 1) are not yet supported — only scalar variables become channels
61
+ - **LogFile methods are immutable** — filtering/resampling returns new instances