1{
2 lib,
3 stdenv,
4 buildPythonPackage,
5 fetchFromGitHub,
6
7 # build-system
8 hatchling,
9
10 # preBuild
11 wgpu-native,
12
13 # dependencies
14 cffi,
15 rubicon-objc,
16 sniffio,
17
18 # optional dependency
19 glfw,
20
21 # docs
22 sphinx-rtd-theme,
23 sphinxHook,
24
25 # tests
26 anyio,
27 imageio,
28 numpy,
29 psutil,
30 pypng,
31 pytest,
32 ruff,
33 trio,
34
35 # passthru
36 testers,
37 wgpu-py,
38}:
39buildPythonPackage rec {
40 pname = "wgpu-py";
41 version = "0.23.0";
42 pyproject = true;
43
44 src = fetchFromGitHub {
45 owner = "pygfx";
46 repo = "wgpu-py";
47 tag = "v${version}";
48 hash = "sha256-z9MRnhPSI+9lGS0UQ5VnSwdCGdYdNnqlDQmb8JAqmyc=";
49 };
50
51 postPatch =
52 # `requests` is only used to fetch a copy of `wgpu-native` via `tools/hatch_build.py`.
53 # As we retrieve `wgpu-native` from nixpkgs instead, none of this is needed, and
54 # remove an extra dependency.
55 ''
56 substituteInPlace pyproject.toml \
57 --replace-fail 'requires = ["requests", "hatchling"]' 'requires = ["hatchling"]' \
58 --replace-fail '[tool.hatch.build.targets.wheel.hooks.custom]' "" \
59 --replace-fail 'path = "tools/hatch_build.py"' ""
60 ''
61 # Skip the compute_textures / astronauts example during testing, as it uses `imageio` to
62 # retrieve an image of an astronaut, which touches the network.
63 + ''
64 substituteInPlace examples/compute_textures.py \
65 --replace-fail 'import wgpu' 'import wgpu # run_example = false'
66 ''
67 # Tweak tests that fail due to a dependency of `wgpu-native`, `naga`, adding an `ir` module
68 + ''
69 substituteInPlace tests/test_wgpu_native_errors.py \
70 --replace-fail 'naga::' 'naga::ir::'
71 '';
72
73 # wgpu-py expects to have an appropriately named wgpu-native library in wgpu/resources
74 preBuild = ''
75 ln -s ${wgpu-native}/lib/libwgpu_native${stdenv.hostPlatform.extensions.library} \
76 wgpu/resources/libwgpu_native-release${stdenv.hostPlatform.extensions.library}
77 '';
78
79 build-system = [ hatchling ];
80
81 dependencies =
82 # Runtime dependencies
83 [
84 cffi
85 sniffio
86 ]
87 # Required only on darwin
88 ++ lib.optionals stdenv.hostPlatform.isDarwin [
89 rubicon-objc
90 ];
91
92 optional-dependencies = {
93 # jupyter = [ jupyter_rfb ] not in nixpkgs
94 glfw = [ glfw ];
95 # imgui = ["imgui-bundle>=1.2.1"] not in nixpkgs
96
97 docs = [
98 sphinxHook
99 sphinx-rtd-theme
100 ];
101 };
102
103 pythonRemoveDeps = [ "requests" ];
104
105 pythonImportsCheck = [ "wgpu" ];
106
107 nativeCheckInputs = [
108 anyio
109 imageio
110 numpy
111 psutil
112 pypng
113 pytest
114 ruff
115 trio
116 ];
117
118 # Tests break in Linux CI due to wgpu being unable to find any adapters.
119 # Ordinarily, this would be fixed in an approach similar to `pkgs/by-name/wg/wgpu-native/examples.nix`'s
120 # usage of `runtimeInputs` and `makeWrapperArgs`.
121 # Unfortunately, as this is a Python module without a `mainProgram`, `makeWrapperArgs` will not apply here,
122 # as there is no "script" to wrap.
123 doCheck = stdenv.hostPlatform.isDarwin;
124
125 installCheckPhase = ''
126 runHook preInstallCheck
127
128 for suite in tests examples codegen tests_mem; do
129 pytest -vvv $suite
130 done
131
132 runHook postInstallCheck
133 '';
134
135 passthru.tests.version = testers.testVersion {
136 package = wgpu-py;
137 command = "python3 -c 'import wgpu; print(wgpu.__version__)'";
138 };
139
140 meta = {
141 description = "WebGPU for Python";
142 homepage = "https://github.com/pygfx/wgpu-py";
143 changelog = "https://github.com/pygfx/wgpu-py/blob/${src.tag}/CHANGELOG.md";
144
145 platforms = lib.platforms.all;
146 license = lib.licenses.bsd2;
147 maintainers = [ lib.maintainers.bengsparks ];
148 };
149}