-
Notifications
You must be signed in to change notification settings - Fork 88
Expand file tree
/
Copy pathpyproject.toml
More file actions
219 lines (203 loc) · 9.04 KB
/
Copy pathpyproject.toml
File metadata and controls
219 lines (203 loc) · 9.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# scikit-build-core backend for `pip install .` / `pip install -e .` / sdist from
# source. Drives the same top-level CMakeLists.txt as the classic `cmake -B build`
# flow (both coexist). See docs: getting_started/build_from_source.
[build-system]
requires = ["scikit-build-core>=1.0", "numpy>=2.0"]
build-backend = "scikit_build_core.build"
[project]
name = "isaaccapture"
dynamic = ["version"]
description = "Isaac Teleop"
readme = "README.md"
requires-python = ">=3.11"
license = "Apache-2.0"
authors = [
{ name = "NVIDIA" },
]
# Mirror of src/core/python/requirements*.txt (keep in sync); see those files for
# the rationale behind the retargeters/grounding version pins.
dependencies = [
"isaacteleop>=1!1.6.dev0,<1!1.9",
"numpy>=1.23.0",
"pyyaml>=6.0.3",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0.0",
"pytest-cov>=4.0.0",
"pybind11-stubgen>=2.5",
"types-PyYAML",
"scipy-stubs",
]
ui = [
"imgui[glfw]>=2.0.0",
]
retargeters = [
"dex-retargeting>=0.4.6,<0.6.0",
"scipy>=1.15.0",
"pyyaml>=6.0.3",
"torch>=2.7.0",
"nlopt>=2.6.2",
"pin>=2.7.0",
"cmeel-urdfdom<5",
"cmeel-tinyxml2<11",
]
retargeters-lite = [
"scipy>=1.15.0",
]
grounding = [
"scipy>=1.15.0",
"torch>=2.7.0",
"trimesh",
"viser",
"pin>=2.7.0",
"pin-pink>=4.0.0",
"loop-rate-limiters>=1.0.0",
"daqp>=0.5.0",
"cmeel-urdfdom<5",
"cmeel-tinyxml2<11",
]
wuji = [
"wuji-sdk[retarget]==2026.7.14",
"pin>=2.7.0",
"cmeel-urdfdom<5",
"cmeel-tinyxml2<11",
]
cloudxr = [
"cryptography>=3.0",
"websockets>=14.0",
]
# Derive the version from the VERSION file (MAJOR.MINOR.x) as MAJOR.MINOR+local,
# matching what the classic flow (cmake/IsaacTeleopVersion.cmake) emits for a
# non-CI/local build. The pip path is a from-source/dev build, so it is always
# tagged `+local`; release versioning (tags, a1/rc1/.devN) stays with the classic
# flow. scikit-build-core finalizes metadata before CMake runs, so it cannot reuse
# the CMake-computed version directly.
[[tool.dynamic-metadata]]
provider = "scikit_build_core.metadata.regex"
field = "version"
input = "VERSION"
regex = '^(?P<major>\d+)\.(?P<minor>\d+)'
result = "{major}.{minor}+local"
# uv-only: don't let `uv run` / `uv sync` implicitly build + install this project
# into their managed environment. Without this, every `uv run` executed from the
# repo (e.g. CI steps that just want a downloaded wheel) triggers a full
# scikit-build-core source build. Explicit builds -- pip install ., pip install -e .,
# python -m build, uv build, uv pip install -- are unaffected (they use
# [build-system], not [tool.uv]).
[tool.uv]
package = false
[tool.uv.sources]
isaacteleop = { path = "src/compat" }
[tool.scikit-build]
# Floor matches CMakeLists' cmake_minimum_required (3.24, for `cmake --fresh`).
# Ubuntu 22.04's apt CMake is 3.22 and no longer satisfies it, so scikit-build-core
# fetches CMake from PyPI there; the <4 cap keeps that fetch on the 3.x line rather
# than silently jumping to 4.x.
cmake.version = ">=3.24,<4"
cmake.build-type = "Release"
# Keep the CMake build tree under build-wheel/<cache-tag>/ (e.g.
# build-wheel/cpython-312/) rather than a temp dir: re-installs are incremental,
# and different Python versions never share one configured CMake cache (which
# would silently reuse the wrong interpreter). It sits outside build/ so it never
# collides with a classic `cmake -B build` tree. Both are gitignored.
build-dir = "build-wheel/{cache_tag}"
# No cmake.define overrides: BUILD_EXAMPLES, BUILD_TESTING, BUILD_PLUGINS and the
# Linux clang-format gate all stay at their CMake defaults. So a `pip install`
# builds the full default (ALL) target -- every extension, the staged
# python_package, examples, tests, and plugins (plugins without their SDK skip
# gracefully). It also ENFORCES clang-format: the build fails if clang-format-14
# is missing or any C++ file is unformatted. The classic python_wheel ALL target
# is gated to non-SKBUILD (src/core/python/CMakeLists.txt) so ALL doesn't trigger a
# nested `uv build`; python_stubs isn't part of ALL, so the pip wheel omits .pyi.
# Install the staged Python tree (isaacteleop_wheel component) plus every built
# executable -- examples, C++ test binaries, plugin tools -- on the venv PATH
# (isaacteleop_binaries -> the venv's bin/ via SKBUILD_SCRIPTS_DIR; see the
# executable-install loop in the root CMakeLists.txt). Plugin/extension .so are not
# executables and are not placed in bin/. Restricting to these two components keeps
# the project's C++ library/header install() rules out of the wheel.
install.components = ["isaacteleop_wheel", "isaacteleop_binaries"]
# Ownership rule: `wheel.packages` owns every authored .py; the `isaacteleop_wheel`
# install component owns only build-produced files. Their intersection must stay
# empty -- the editable finder consults `known_wheel_files` BEFORE
# `known_source_files`, so a stray .py in the component silently shadows this
# mapping. Hence the *.py exclusion on install(DIRECTORY) in src/core/python.
# Both import names ship in this wheel, matching the classic flow: `pip install .`
# and `pip install -e .` must agree about whether `import isaacteleop` resolves.
# TODO(1.9): drop the isaacteleop entry.
[tool.scikit-build.wheel]
packages = { isaaccapture = "src/python/isaaccapture", "isaacteleop.py" = "src/compat/isaacteleop.py" }
# `rebuild = false`: no recompile on import, so build products (.so, .pyi, py.typed,
# the vendored CloudXR runtime) are frozen until a rebuild + re-install. Authored .py
# is the exception -- `mode = "redirect"` resolves it live from src/python/isaaccapture.
[tool.scikit-build.editable]
mode = "redirect"
rebuild = false
# ==============================================================================
# Ruff
# ==============================================================================
# The ruff + ruff-format pre-commit hooks previously ran with no configuration at
# all, i.e. only ruff's built-in default rules (E4/E7/E9 + F). The `select` below
# widens that to the correctness-oriented rule groups; formatting stays on
# ruff-format's defaults (88 cols), which is what the tree is already formatted to.
#
# Everything in `select` is currently clean, so the hook is enforceable as-is.
# Each `ignore` is a deliberate call, not a backlog marker -- see its comment.
[tool.ruff]
target-version = "py311"
[tool.ruff.lint]
select = [
"E4", "E7", "E9", # pycodestyle errors (ruff's default subset)
"F", # pyflakes
"B", # flake8-bugbear -- real bug shapes
"C4", # flake8-comprehensions
"PIE", # flake8-pie
"PERF", # perflint
"PLE", "PLW", # pylint errors + warnings
"LOG", "G", # logging correctness
"ASYNC", # async pitfalls
"RUF", # ruff-specific
]
ignore = [
# Adding strict= to a zip() converts a silent truncation into a runtime
# exception, so it is a behaviour change per call site, not a mechanical fix.
# Worth adopting deliberately (15 sites) rather than in a lint sweep.
"B905",
# Style-only rewrites of code that is already correct and readable:
# RUF005 turns `a + [b]` into `[*a, b]`, C408 turns dict(a=1) into {"a": 1},
# and RUF007 turns zip(x[:-1], x[1:]) into itertools.pairwise(x). Enforcing
# any of them means churning working call sites for no behaviour change, so
# they are left to author preference.
"RUF005", "C408", "RUF007",
# Sorting __all__ alphabetically destroys the semantic grouping comments the
# package __init__ files use ("# Hand types.", "# Controller types.", ...).
"RUF022",
# RUF100 is evaluated against `select` above, so it flags every noqa written
# for a rule this config does not (yet) enable -- BLE001, PLC0415, N803 and
# friends. Re-enable once those groups are adopted.
"RUF100",
# The tree deliberately uses en/em dashes and arrows in prose and comments.
"RUF001", "RUF002", "RUF003",
# Module-level singletons (EnvConfig, the CloudXR runtime handles) are an
# intentional design choice here.
"PLW0603",
# Rebinding a loop variable to its normalized form, and small wrapper lambdas,
# both read better than the suggested rewrites in the places they occur.
"PLW2901", "PLW0108",
# The suggested comprehensions inline filtering logic that is clearer as an
# explicit loop (see EnvConfig._merge_env).
"PERF401", "PERF403",
# Targets trio/anyio. The one flagged call is a sub-millisecond os.path.isfile
# in an asyncio poll loop that already sleeps between iterations; routing it
# through an executor would cost more than the stat it replaces.
"ASYNC240",
# Flags any async def taking a `timeout` parameter; that is the established
# signature for the adb/runtime helpers and their callers.
"ASYNC109",
]
[tool.ruff.lint.per-file-ignores]
# Tests legitimately assert on private state and re-import inside test bodies.
"**/tests/**" = ["SLF001"]