1{
2 lib,
3 buildPythonPackage,
4 fetchFromGitHub,
5
6 cmake,
7 ninja,
8 # build-system
9 hatchling,
10 scikit-build-core,
11 hatch-vcs,
12 nanobind,
13 # deps
14 antlr4-python3-runtime,
15 atopile-easyeda2kicad,
16 black,
17 case-converter,
18 cookiecutter,
19 dataclasses-json,
20 deprecated,
21 fastapi-github-oidc,
22 freetype-py,
23 gitpython,
24 kicad-python,
25 kicadcliwrapper,
26 matplotlib,
27 mcp,
28 more-itertools,
29 natsort,
30 numpy,
31 ordered-set,
32 pathvalidate,
33 pint,
34 posthog,
35 psutil,
36 pydantic-settings,
37 pygls,
38 questionary,
39 requests,
40 rich,
41 ruamel-yaml,
42 ruff,
43 semver,
44 sexpdata,
45 shapely,
46 typer,
47 urllib3,
48 zstd,
49 pythonOlder,
50
51 # tests
52 pytestCheckHook,
53
54 pytest-benchmark,
55 pytest-timeout,
56 pytest-datafiles,
57 pytest-xdist,
58 hypothesis,
59 writableTmpDirAsHomeHook,
60}:
61
62buildPythonPackage rec {
63 pname = "atopile";
64 version = "0.11.2";
65 pyproject = true;
66
67 disabled = pythonOlder "3.13";
68
69 src = fetchFromGitHub {
70 owner = "atopile";
71 repo = "atopile";
72 tag = "v${version}";
73 hash = "sha256-JczlQulHlViV9pg0uPXd9Boagp74VBdZ1UMDXh2c3DA=";
74 };
75
76 build-system = [
77 hatchling
78 scikit-build-core
79 hatch-vcs
80 nanobind
81 ];
82
83 dontUseCmakeConfigure = true; # skip cmake configure invocation
84
85 nativeBuildInputs = [
86 cmake
87 ninja
88 ];
89
90 dependencies = [
91 antlr4-python3-runtime
92 atopile-easyeda2kicad
93 black # used as a dependency
94 case-converter
95 cookiecutter
96 dataclasses-json
97 deprecated
98 fastapi-github-oidc
99 freetype-py
100 gitpython
101 kicad-python
102 kicadcliwrapper
103 matplotlib
104 mcp
105 more-itertools
106 natsort
107 numpy
108 ordered-set
109 pathvalidate
110 pint
111 posthog
112 psutil
113 pydantic-settings
114 pygls
115 questionary
116 requests
117 rich
118 ruamel-yaml
119 ruff
120 semver
121 sexpdata
122 shapely
123 typer
124 urllib3
125 zstd
126 ];
127
128 pythonRelaxDeps = [
129 "posthog"
130 "zstd"
131 ];
132
133 pythonImportsCheck = [ "atopile" ];
134
135 nativeCheckInputs = [
136 writableTmpDirAsHomeHook
137 pytestCheckHook
138 pytest-xdist
139 pytest-benchmark
140 pytest-datafiles
141 pytest-timeout
142 hypothesis
143 ];
144
145 preCheck = ''
146 # do not report worker logs to filee
147 substituteInPlace test/conftest.py \
148 --replace-fail "worker_id =" "worker_id = None #"
149
150 # unrecognized flags
151 substituteInPlace pyproject.toml \
152 --replace-fail "--html=artifacts/test-report.html" "" \
153 --replace-fail "--self-contained-html" "" \
154 --replace-fail "--numprocesses=auto" "" \
155
156 # Replace this function call that cause test to hang
157 substituteInPlace \
158 test/cli/test_packages.py \
159 test/library/test_names.py \
160 test/test_examples.py \
161 test/test_parse_utils.py \
162 --replace-fail "_repo_root()" "Path('$(pwd)')"
163
164 # Fix crash due to empty list in fixture tests
165 substituteInPlace \
166 test/test_examples.py \
167 test/test_parse_utils.py \
168 --replace-fail "p.stem" "p.stem if isinstance(p, Path) else p"
169 '';
170
171 disabledTestPaths = [
172 # timouts
173 "test/test_cli.py"
174 "test/cli/test_packages.py"
175 "test/end_to_end/test_net_naming.py"
176 "test/end_to_end/test_pcb_export.py"
177 "test/exporters/bom/test_bom.py"
178 "test/front_end/test_front_end_pick.py"
179 "test/libs/picker/test_pickers.py"
180 ];
181
182 disabledTests = [
183 # timeout
184 "test_build_error_logging"
185 "test_performance_mifs_bus_params"
186 "test_resistor"
187 "test_reserved_attrs"
188 # requires internet
189 "test_simple_pick"
190 "test_simple_negative_pick"
191 "test_jlcpcb_pick_resistor"
192 "test_jlcpcb_pick_capacitor"
193 "test_regression_rp2040_usb_diffpair_full"
194 "test_model_translations"
195 # type error
196 "test_alternate_trait_constructor_with_params"
197 "test_parameterised_trait_with_params"
198 "test_trait_alternate_constructor_precedence"
199 "test_trait_template_enum"
200 "test_trait_template_enum_invalid"
201 # failure
202 "test_solve_voltage_divider_complex"
203 ];
204
205 # in order to use pytest marker, we need to use ppytestFlagsArray
206 # using pytestFlags causes `ERROR: file or directory not found: slow`
207 pytestFlagsArray = [
208 "-m='not slow and not not_in_ci and not regression'"
209 "--timeout=10" # any test taking long, timouts with more than 60s
210 "--benchmark-disable"
211 "--tb=line"
212 ];
213
214 doCheck = true;
215
216 meta = {
217 description = "Design circuit boards with code";
218 homepage = "https://atopile.io";
219 downloadPage = "https://github.com/atopile/atopile";
220 changelog = "https://github.com/atopile/atopile/releases/tag/${src.tag}";
221 license = with lib.licenses; [ mit ];
222 maintainers = with lib.maintainers; [ sigmanificient ];
223 mainProgram = "ato";
224 };
225}