pycheck-neuron 1.0.0__py3-none-any.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.
@@ -0,0 +1,296 @@
1
+ Metadata-Version: 2.4
2
+ Name: pycheck-neuron
3
+ Version: 1.0.0
4
+ Summary: 32-rule static AST analyzer catching temporal lookahead bias, causal confusion, and uncertainty bugs in Python ML code. Zero dependencies.
5
+ Author: NEURON Team
6
+ Author-email: Fayo Ibrahim <fayo@neuron-lab.org>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/neuronlabs-ai/pycheck
9
+ Project-URL: Documentation, https://github.com/neuronlabs-ai/pycheck#readme
10
+ Project-URL: Repository, https://github.com/neuronlabs-ai/pycheck
11
+ Project-URL: Bug Tracker, https://github.com/neuronlabs-ai/pycheck/issues
12
+ Keywords: machine-learning,data-leakage,temporal-bias,lookahead-bias,backtesting,quantitative-finance,algorithmic-trading,linter,static-analysis,causal-inference,time-series,pandas,sklearn,scikit-learn,uncertainty,neuron,ml-safety,data-science,feature-engineering
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.7
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Operating System :: OS Independent
21
+ Classifier: Topic :: Software Development :: Quality Assurance
22
+ Classifier: Topic :: Software Development :: Testing
23
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
24
+ Classifier: Topic :: Office/Business :: Financial
25
+ Classifier: Intended Audience :: Science/Research
26
+ Classifier: Intended Audience :: Financial and Insurance Industry
27
+ Classifier: Intended Audience :: Developers
28
+ Classifier: Development Status :: 5 - Production/Stable
29
+ Classifier: Environment :: Console
30
+ Requires-Python: >=3.7
31
+ Description-Content-Type: text/markdown
32
+ License-File: LICENSE
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=7.0; extra == "dev"
35
+ Requires-Dist: build; extra == "dev"
36
+ Requires-Dist: twine; extra == "dev"
37
+ Dynamic: license-file
38
+
39
+ # PyCheck — ML Safety Analyzer
40
+
41
+ **30 rules. Zero dependencies. Catches the bugs that cost millions.**
42
+
43
+ PyCheck is a static AST analyzer that detects **temporal lookahead bias**, **causal confusion**, and **unguarded uncertainty** in Python ML and trading scripts — before you run a single line of code.
44
+
45
+ ```bash
46
+ pip install pycheck-neuron
47
+ pycheck my_strategy.py
48
+ ```
49
+
50
+ ---
51
+
52
+ ## The Problem It Solves
53
+
54
+ These bugs are invisible to Python, pytest, and your IDE. They only show up in production — often after you've already lost money or shipped a flawed model.
55
+
56
+ **Lookahead bias** — the single most expensive silent bug in quantitative ML:
57
+ ```python
58
+ # This looks fine. Python won't complain. Your backtest will show 94% accuracy.
59
+ # In production, you lose everything — because this uses data from the future.
60
+ df['target'] = df['close'].shift(-1) # ERROR[T001]: future data access
61
+ X_scaled = scaler.fit_transform(X) # ERROR[T010]: test set leaks into training
62
+ cv = KFold(n_splits=5, shuffle=True) # ERROR[T012]: shuffles time — leaks future
63
+ ```
64
+
65
+ PyCheck catches all three before execution:
66
+
67
+ ```
68
+ =================================================================
69
+ PyCheck — NEURON ML Safety Analyzer
70
+ Scanning: strategy.py
71
+ Rules: 30 active
72
+ =================================================================
73
+
74
+ ERROR[T001]: .shift(-1) accesses data 1 rows INTO THE FUTURE
75
+ --> strategy.py:4:14
76
+ 4 | df['target'] = df['close'].shift(-1)
77
+ ^^^^^^^^^^^
78
+ help: Use .shift(1) to access past data instead
79
+
80
+ ERROR[T010]: .fit_transform() on full dataset leaks test statistics into training
81
+ --> strategy.py:8:11
82
+ 8 | X_scaled = scaler.fit_transform(X)
83
+ ^^^^^^^^^^^
84
+ help: Use .fit(X_train).transform(X_train), then .transform(X_test) separately
85
+
86
+ ERROR[T012]: KFold() shuffles time-series data across folds, leaking future into training
87
+ --> strategy.py:11:5
88
+ 11 | cv = KFold(n_splits=5, shuffle=True)
89
+ ^^^^^^^^^^^
90
+ help: Use TimeSeriesSplit() for temporal cross-validation
91
+
92
+ -----------------------------------------------------------------
93
+ Summary: 3 error(s), 0 warning(s)
94
+ These 3 error(s) would be COMPILE-TIME ERRORS in NEURON
95
+ Python detected: 0 of these issues at runtime
96
+ -----------------------------------------------------------------
97
+ ```
98
+
99
+ ---
100
+
101
+ ## What It Catches
102
+
103
+ ### Temporal Leak Rules (17 rules — `T001`–`T017`)
104
+
105
+ | Rule | What It Catches | Severity |
106
+ |------|----------------|----------|
107
+ | `T001` | `.shift(-1)` — accessing future data | **Error** |
108
+ | `T002` | `train_test_split()` on time-series data | **Error** |
109
+ | `T003` | `.rolling()` computed before the train/test split | Warning |
110
+ | `T004` | `.expanding()` computed before split | Warning |
111
+ | `T005` | `.pct_change(-1)` — future percent returns | **Error** |
112
+ | `T006` | `iloc[i + 1]` inside a loop — future index access | **Error** |
113
+ | `T007` | `.bfill()` — backward fill uses future to fill past | **Error** |
114
+ | `T008` | `.interpolate(method='cubic')` — non-causal interpolation | Warning |
115
+ | `T009` | `.rolling(center=True)` — centered window leaks future | **Error** |
116
+ | `T010` | `.fit_transform()` on full dataset — test leaks into train | **Error** |
117
+ | `T011` | `StandardScaler` / `MinMaxScaler` fitted before split | **Error** |
118
+ | `T012` | `KFold` instead of `TimeSeriesSplit` | **Error** |
119
+ | `T013` | `.resample()` on full dataset before split | Warning |
120
+ | `T014` | `.diff(-5)` — future difference computation | **Error** |
121
+ | `T015` | Negative `.shift()` inside `groupby().transform()` | **Error** |
122
+ | `T016` | `pd.merge_asof()` with `direction='nearest'` or `'forward'` | **Error** |
123
+ | `T017` | Target laundering & un-split target encoding (`regime_success_rate`) | **Error** |
124
+
125
+ ### Causal Confusion Rules (7 rules — `C001`–`C007`)
126
+
127
+ | Rule | What It Catches | Severity |
128
+ |------|----------------|----------|
129
+ | `C001` | `.corr()` used as a basis for trading or treatment decisions | Warning |
130
+ | `C002` | Target column included as a feature | **Error** |
131
+ | `C003` | Post-treatment variable included in features | Warning |
132
+ | `C004` | Filtering by outcome variable — survivorship bias | **Error** |
133
+ | `C005` | `.dropna()` removing non-random rows — selection bias | Warning |
134
+ | `C006` | p-value threshold without multiple comparison correction | Warning |
135
+ | `C007` | `.corrwith()` used for causal feature selection | Warning |
136
+
137
+ ### Uncertainty Rules (6 rules — `U001`–`U006`)
138
+
139
+ | Rule | What It Catches | Severity |
140
+ |------|----------------|----------|
141
+ | `U001` | `.predict()` without confidence or probability scores | Warning |
142
+ | `U002` | Hardcoded decision threshold (e.g. `if pred > 0.5`) | Warning |
143
+ | `U003` | `.predict_proba()` without calibration check | Info |
144
+ | `U004` | Single model without ensemble or uncertainty estimate | Info |
145
+ | `U005` | `.score()` evaluated on training data only | **Error** |
146
+ | `U006` | `.predict()` inside a production loop without guard | **Error** |
147
+
148
+ ### Data Quality Rules (2 rules)
149
+
150
+ | Rule | What It Catches | Severity |
151
+ |------|----------------|----------|
152
+ | `D002` | `except: pass` — silently swallowed pipeline errors | Warning |
153
+ | `D003` | Magic numbers in data operations | Info |
154
+
155
+ ---
156
+
157
+ ## Taint Flow Analysis
158
+
159
+ Beyond pattern matching, PyCheck traces how future-contaminated data **flows through your codebase**:
160
+
161
+ ```python
162
+ future_ret = df['close'].shift(-1) # Tainted source
163
+ signal = future_ret - df['close'] # Taint propagates
164
+ model.fit(X, signal) # ERROR: tainted label reaches .fit() sink
165
+ ```
166
+
167
+ The taint engine follows assignments across three levels of variable indirection.
168
+
169
+ ---
170
+
171
+ ## CLI Usage
172
+
173
+ ```bash
174
+ pycheck script.py # Errors + warnings (default)
175
+ pycheck script.py --info # Include info-level diagnostics
176
+ pycheck script.py --quiet # Errors only
177
+ pycheck script.py --json # JSON output — pipe into CI/CD
178
+ pycheck --list # List all 30 rules
179
+ pycheck --help
180
+ ```
181
+
182
+ ### JSON Output (CI/CD Integration)
183
+
184
+ ```bash
185
+ pycheck strategy.py --json | jq '.[] | select(.severity == "error")'
186
+ ```
187
+
188
+ Returns structured output for automated pipelines:
189
+ ```json
190
+ [
191
+ {
192
+ "line": 22,
193
+ "col": 14,
194
+ "severity": "error",
195
+ "code": "T001",
196
+ "message": ".shift(-5) accesses data 5 rows INTO THE FUTURE",
197
+ "help": "Use .shift(5) to access past data instead"
198
+ }
199
+ ]
200
+ ```
201
+
202
+ ### Exit Codes
203
+
204
+ - `0` — No errors found
205
+ - `1` — One or more errors found
206
+
207
+ Clean integration with `make`, `pre-commit`, GitHub Actions, and GitLab CI.
208
+
209
+ ---
210
+
211
+ ## Enterprise CI/CD & GitLab Integration
212
+
213
+ PyCheck natively exports into the **GitLab Code Quality** report format (`gl-codequality.json`), enabling quantitative teams, hedge funds, and enterprise banks to guard against lookahead bias directly in their Merge Requests.
214
+
215
+ ```bash
216
+ # Output GitLab Code Quality JSON directly to stdout
217
+ pycheck . --gitlab
218
+
219
+ # Or write report artifact while printing directory summary in CI job trace
220
+ pycheck . --gitlab --output gl-codequality.json
221
+ ```
222
+
223
+ ### Turnkey `.gitlab-ci.yml`
224
+
225
+ Add this job to your repository to automatically block any Merge Request containing lookahead leaks:
226
+
227
+ ```yaml
228
+ pycheck:
229
+ stage: test
230
+ image: python:3.11-slim
231
+ before_script:
232
+ - pip install pycheck-neuron
233
+ script:
234
+ - pycheck . --gitlab --output gl-codequality.json
235
+ artifacts:
236
+ reports:
237
+ codequality: gl-codequality.json
238
+ rules:
239
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
240
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
241
+ allow_failure: false
242
+ ```
243
+
244
+ GitLab will automatically annotate the Merge Request diff with red warnings on every line where temporal data leaks or unguarded point predictions are introduced.
245
+
246
+ ---
247
+
248
+ ## Real-World Examples
249
+
250
+ The `examples/` directory contains recreations of actual ML disasters:
251
+
252
+ | File | What It Demonstrates |
253
+ |------|---------------------|
254
+ | `zillow_ibuying.py` | 11 bugs replicating the structural failures behind the $881M Zillow Offers write-down |
255
+ | `yfinance_strategy.py` | The classic quant blog tutorial: `shift(-5)` + `fit_transform` before split |
256
+ | `sentdex_tutorial.py` | A widely-shared ML tutorial with silent time-series cross-validation errors |
257
+ | `leaky_pipeline.py` | A complete end-to-end pipeline showing taint propagation across 4 variables |
258
+ | `clean_pipeline.py` | The correct version — 0 errors, 0 warnings |
259
+
260
+ ---
261
+
262
+ ## VS Code Extension
263
+
264
+ The `pycheck-vscode` extension gives you **real-time red/yellow squiggles** as you write:
265
+
266
+ - Inline error markers on every flagged line
267
+ - Hover tooltips with rule description and fix suggestion
268
+ - Status bar showing live error/warning count
269
+
270
+ ---
271
+
272
+ ## Beyond Python: the NEURON Language
273
+
274
+ PyCheck catches these bugs **after you write them**.
275
+
276
+ [NEURON](https://github.com/neuronlabs-ai/neuron-lang) prevents them **before the program compiles** — by encoding time horizons, causal modes, and uncertainty directly into the type system:
277
+
278
+ ```python
279
+ # In NEURON, this is a compile-time error — not a runtime surprise:
280
+ fn strategy(prices: Temporal[Tensor, 0]) -> Tensor:
281
+ let future = prices.shift(-1)
282
+ # error[TemporalLeak]: shift(-1) produces offset +1 > 0
283
+ # Lookahead bias detected at compile time.
284
+ ```
285
+
286
+ For 100% compile-time temporal proofs, type-checked do-calculus, and native ahead-of-time compilation, see the [NEURON language](https://github.com/neuronlabs-ai/neuron-lang).
287
+
288
+ ---
289
+
290
+ ## License
291
+
292
+ MIT — free for any use.
293
+
294
+ ---
295
+
296
+ *PyCheck is built on the [NEURON](https://github.com/neuronlabs-ai/neuron-lang) type theory for temporal, causal, and uncertainty safety in ML programs.*
@@ -0,0 +1,12 @@
1
+ pycheck/__init__.py,sha256=DnfQ_9-EPxDtGgLLwYwSbAPRHC-mVvEdAlk76kd_sEs,311
2
+ pycheck/__main__.py,sha256=I0O-cpkys0wMWsoczRo4DsQvj8azMc2rMkfaBkEuQT4,93
3
+ pycheck/analyzer.py,sha256=BKuLGgM8hGXr9A4H0V_RA-fHZ8I4h8VdR-7esGCiXVg,7318
4
+ pycheck/cli.py,sha256=2e6vC4Hf8hgT_l0_WVtU_jXErKZhxx6csS3_gtXkcb4,7871
5
+ pycheck/flow.py,sha256=KJqpFXJLGFkvilqDlk0OnAZXuO5N5N9mgLbc1t_tXow,12866
6
+ pycheck/rules.py,sha256=5RcOH9HRfC0LTi6x-AUtOh6D59yegT47zSABtQPHx4w,41950
7
+ pycheck_neuron-1.0.0.dist-info/licenses/LICENSE,sha256=bEHvMGANsTvIx-xTv8l6Ukv_9IOlaBCYeRuL0CKQPcs,1089
8
+ pycheck_neuron-1.0.0.dist-info/METADATA,sha256=CmgtgVcN_CZd7afbbmLPQ-XdaRYvGBtqZ1tJbeFsDv4,11854
9
+ pycheck_neuron-1.0.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
10
+ pycheck_neuron-1.0.0.dist-info/entry_points.txt,sha256=K1DMmBZoTtvHNo0CFlth0EnWQvIh1t9ZcbfT0e5YfxM,45
11
+ pycheck_neuron-1.0.0.dist-info/top_level.txt,sha256=0iSa2bhZWXFaKObpl3Fh5v_kib5WXyxrHwfxdlxgwC4,8
12
+ pycheck_neuron-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pycheck = pycheck.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 NEURON Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ pycheck