Skip to content

Comments

Fix stub generation issues and enable full Pyright validation in CI/CD#1171

Merged
shi-eric merged 5 commits intoNVIDIA:mainfrom
shi-eric:ershi/fix-more-stub-issues
Jan 13, 2026
Merged

Fix stub generation issues and enable full Pyright validation in CI/CD#1171
shi-eric merged 5 commits intoNVIDIA:mainfrom
shi-eric:ershi/fix-more-stub-issues

Conversation

@shi-eric
Copy link
Contributor

@shi-eric shi-eric commented Jan 13, 2026

Description

1. Hide reversed built-in from stubs

Mark reversed as hidden (similar to range and iter_next) to remove it from generated stubs and documentation.

2. Fix RST template docstring indentation

Apply Jinja's indent filter with first=True so multi-line docstrings render with consistent margins in the documentation.

3. Merge overlapping wp.tid() overloads

Resolve type checker warnings about overlapping function signatures by:

  • Unifying wp.tid() docstrings across all overloads
  • Adding add_merged_builtin_function_stub() to auto-detect and merge overloads with identical input types into a single stub with union return type
  • Fixing quaternion type parameters (ScalarFloat) for isfinite/isnan/isinf/length_sq
  • Refactoring scalar type definitions in types.py for earlier availability

4. Enable Pyright stubs job

Remove allow_failure from the Pyright stubs validation job in both GitHub Actions and GitLab CI.

5. Fix Scalar TypeVar consistency and add bool vector/matrix overloads

Address CodeRabbit feedback about misaligned Scalar generics:

  • Remove bool and builtins.bool from the Scalar TypeVar constraints—Scalar now represents "numeric scalar" types only (int/float variants)
  • Update scalars_equal_generic() in types_match() to use scalar_types instead of scalar_and_bool_types, aligning with type_matches_template() behavior
  • This prevents potential StopIteration crashes in value_func helpers like scalar_mul_create_value_func() that search only scalar_types

Since bool vectors and matrices are a valid feature (distinct from numeric vectors), add explicit overloads for:

  • expect_eq / expect_neq for vector(dtype=bool) and matrix(dtype=bool)
  • extract for vector(dtype=bool) and matrix(dtype=bool) (1D and 2D indexing)
  • index / indexref for vector(dtype=bool) and matrix(dtype=bool)

6. Harden stub generation against value_func errors

Wrap f.value_func(None, None) calls in get_return_type_str() with try-except to gracefully fall back to f.value_type when the function doesn't support None arguments. This prevents stub generation crashes and ensures all return types (including None) are correctly emitted in stubs.

Files Changed

Commit Files
Hide reversed builtins.py, __init__.pyi, builtins.rst
RST indent fix docs/_templates/builtins.rst
tid() overloads context.py, builtins.py, types.py, __init__.pyi
Enable Pyright CI .github/workflows/ci.yml, .gitlab-ci.yml
Scalar/bool fixes types.py, builtins.py

Before your PR is "Ready for review"

  • All commits are signed-off to indicate that your contribution adheres to the Developer Certificate of Origin requirements
  • Necessary tests have been added
  • Documentation is up-to-date
  • Auto-generated files modified by compiling Warp and building the documentation have been updated (e.g. __init__.pyi, docs/api_reference/, docs/language_reference/)
  • Code passes formatting and linting checks with pre-commit run -a

Summary by CodeRabbit

  • New Features

    • Added block_dim() utility and merged-stub emission for identical overloads.
    • Introduced a refined scalar type system and a public Vector type.
  • Improvements

    • Standardized quaternion/transformation APIs to Float-centric typing.
    • CI stricter: pyright-stubs now fail the pipeline on errors.
  • Documentation

    • Reorganized and reformatted builtins docs and moved Utility autosummary entries.

✏️ Tip: You can customize this high-level summary in your review settings.

Behavior is similar to range and iter_next, both of which are already hidden

Signed-off-by: Eric Shi <ershi@nvidia.com>
Previously multi-line docstrings rendered with inconsistent margins
because only the first line was indented within the function directive.

Signed-off-by: Eric Shi <ershi@nvidia.com>
@coderabbitai
Copy link

coderabbitai bot commented Jan 13, 2026

📝 Walkthrough

Walkthrough

Refactors the scalar/type system, moves Quaternion/Transformation typings to Float, merges identical builtin overloads into single stubs, exposes a new block_dim() builtin and tid clarifications, adjusts doc rendering, and tightens CI by removing permissive pyright failure flags. (33 words)

Changes

Cohort / File(s) Summary
CI/CD configuration
\.github/workflows/ci.yml`, `.gitlab-ci.yml``
Removed permissive failure flags for pyright jobs (continue-on-error: true, allow_failure: true), so pyright-stubs/pyright failures will now fail CI.
Documentation templates & pages
\docs/_templates/builtins.rst`, `docs/language_reference/builtins.rst``
Adjusted overload doc rendering to indent overload docs and relocated the Utility autosummary block (moved from Geometry to Random); purely documentation/formatting changes.
Stub generation / context
\warp/_src/context.py``
Added get_return_type_str(f) and add_merged_builtin_function_stub(overloads); refactored stub emission to compute return-type strings and emit merged stubs when multiple non-hidden overloads share identical input signatures.
Scalar type system
\warp/_src/types.py``
Replaced bare TypeVars with a scalar hierarchy: introduced scalar_base, concrete scalar classes (float16/32/64, int8/16/32/64, unsigned variants, bool), Vector(Generic[Length, Scalar]), type tuples (int_types, float_types, scalar_types, scalar_and_bool_types), and constrained Int/Float/Scalar TypeVars.
Public API signatures & builtins
\warp/init.pyi`, `warp/_src/builtins.py``
Converted many quaternion/transform/vector/matrix overloads from ScalarFloat, made numerous in-place setters/ops return None, consolidated/clarified tid() overloads and added block_dim() -> int, and updated docstrings/dispatch/value helpers to match new typing and overload semantics.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 72.95% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix stub generation issues and enable full Pyright validation in CI/CD' accurately summarizes the main objectives of the PR: addressing stub generation problems and enabling comprehensive Pyright validation in continuous integration.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@shi-eric shi-eric self-assigned this Jan 13, 2026
@shi-eric shi-eric requested a review from daedalus5 January 13, 2026 00:05
@shi-eric shi-eric added this to the 1.11.1 milestone Jan 13, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In @warp/_src/context.py:
- Around line 8657-8673: get_return_type_str currently skips explicit None and
unguardedly calls f.value_func(None, None); change it to first set return_type =
f.value_type, then if f.value_func is present attempt to call it inside a
try/except (catch TypeError/Exception) and only overwrite return_type if the
call succeeds, falling back to f.value_type on error; finally, return the
literal "None" when return_type is None, otherwise return type_str(return_type).
Update references in add_builtin_function_stub usage of get_return_type_str so
stubs will emit "-> None" and stub generation won't crash from unsafe
f.value_func calls.
🧹 Nitpick comments (2)
warp/_src/context.py (1)

8921-8941: Prefer comparing Function.signature over input_types for “identical overload” detection.
Using tuple(sorted(f.input_types.items())) ignores default values/kw-only/varargs semantics that are already captured by Function.signature. This risks merging overloads that look “same” by dict contents but differ in callable signature.

Proposed refactor
-                first = non_hidden_overloads[0]
-                first_inputs = tuple(sorted(first.input_types.items()))
-                all_same_inputs = all(
-                    tuple(sorted(f.input_types.items())) == first_inputs for f in non_hidden_overloads
-                )
+                first = non_hidden_overloads[0]
+                all_same_inputs = all(f.signature == first.signature for f in non_hidden_overloads)
warp/_src/builtins.py (1)

28-28: Ruff F405 noise from from warp._src.types import * is now hitting many changed lines.

If Ruff is enforced in CI for this repo, consider either adding a targeted # noqa: F403,F405 on the star import line, or switching to explicit imports (bigger change). Otherwise, these warnings will keep growing as more typed overloads are added.

Also applies to: 427-429, 475-478, 524-527, 742-744, 8828-8840, 9063-9076, 9101-9116, 9134-9142, 9176-9185, 9788-9792, 9803-9807, 9830-9841, 10034-10051, 10161-10179, 10236-10294, 11763-11766

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 41a1421 and d8e40aa.

📒 Files selected for processing (8)
  • .github/workflows/ci.yml
  • .gitlab-ci.yml
  • docs/_templates/builtins.rst
  • docs/language_reference/builtins.rst
  • warp/__init__.pyi
  • warp/_src/builtins.py
  • warp/_src/context.py
  • warp/_src/types.py
💤 Files with no reviewable changes (2)
  • .gitlab-ci.yml
  • .github/workflows/ci.yml
🧰 Additional context used
🧬 Code graph analysis (3)
warp/__init__.pyi (5)
warp/_src/types.py (2)
  • Quaternion (264-265)
  • Transformation (268-269)
warp/native/tile.h (1)
  • len (1757-1760)
warp/native/array.h (1)
  • len (2218-2218)
warp/native/mat.h (1)
  • len (5516-5519)
warp/native/vec.h (1)
  • len (2264-2264)
warp/_src/context.py (2)
warp/_src/utils.py (1)
  • warn (70-84)
warp/__init__.pyi (6)
  • add (5689-5691)
  • add (5694-5696)
  • add (5699-5701)
  • add (5704-5706)
  • add (5709-5711)
  • add (5714-5716)
warp/_src/types.py (2)
exts/omni.warp/omni/warp/nodes/_impl/kernel.py (1)
  • is_array (254-255)
warp/__init__.pyi (6)
  • add (5689-5691)
  • add (5694-5696)
  • add (5699-5701)
  • add (5704-5706)
  • add (5709-5711)
  • add (5714-5716)
🪛 Ruff (0.14.10)
warp/_src/builtins.py

428-428: quaternion may be undefined, or defined from star imports

(F405)


428-428: Float may be undefined, or defined from star imports

(F405)


477-477: quaternion may be undefined, or defined from star imports

(F405)


477-477: Float may be undefined, or defined from star imports

(F405)


526-526: quaternion may be undefined, or defined from star imports

(F405)


526-526: Float may be undefined, or defined from star imports

(F405)


743-743: quaternion may be undefined, or defined from star imports

(F405)


743-743: Float may be undefined, or defined from star imports

(F405)


8829-8829: quaternion may be undefined, or defined from star imports

(F405)


8829-8829: Float may be undefined, or defined from star imports

(F405)


8838-8838: transformation may be undefined, or defined from star imports

(F405)


8838-8838: Float may be undefined, or defined from star imports

(F405)


9065-9065: quaternion may be undefined, or defined from star imports

(F405)


9065-9065: Float may be undefined, or defined from star imports

(F405)


9075-9075: transformation may be undefined, or defined from star imports

(F405)


9075-9075: Float may be undefined, or defined from star imports

(F405)


9103-9103: quaternion may be undefined, or defined from star imports

(F405)


9103-9103: Float may be undefined, or defined from star imports

(F405)


9114-9114: transformation may be undefined, or defined from star imports

(F405)


9114-9114: Float may be undefined, or defined from star imports

(F405)


9136-9136: quaternion may be undefined, or defined from star imports

(F405)


9136-9136: Float may be undefined, or defined from star imports

(F405)


9179-9179: quaternion may be undefined, or defined from star imports

(F405)


9179-9179: Float may be undefined, or defined from star imports

(F405)


9790-9790: quaternion may be undefined, or defined from star imports

(F405)


9790-9790: Float may be undefined, or defined from star imports

(F405)


9790-9790: quaternion may be undefined, or defined from star imports

(F405)


9790-9790: Float may be undefined, or defined from star imports

(F405)


9791-9791: quaternion may be undefined, or defined from star imports

(F405)


9791-9791: Float may be undefined, or defined from star imports

(F405)


9805-9805: transformation may be undefined, or defined from star imports

(F405)


9805-9805: Float may be undefined, or defined from star imports

(F405)


9805-9805: transformation may be undefined, or defined from star imports

(F405)


9805-9805: Float may be undefined, or defined from star imports

(F405)


9806-9806: transformation may be undefined, or defined from star imports

(F405)


9806-9806: Float may be undefined, or defined from star imports

(F405)


9832-9832: quaternion may be undefined, or defined from star imports

(F405)


9832-9832: Float may be undefined, or defined from star imports

(F405)


9832-9832: quaternion may be undefined, or defined from star imports

(F405)


9832-9832: Float may be undefined, or defined from star imports

(F405)


9833-9833: quaternion may be undefined, or defined from star imports

(F405)


9833-9833: Float may be undefined, or defined from star imports

(F405)


9839-9839: transformation may be undefined, or defined from star imports

(F405)


9839-9839: Float may be undefined, or defined from star imports

(F405)


9839-9839: transformation may be undefined, or defined from star imports

(F405)


9839-9839: Float may be undefined, or defined from star imports

(F405)


9840-9840: transformation may be undefined, or defined from star imports

(F405)


9840-9840: Float may be undefined, or defined from star imports

(F405)


10035-10035: quaternion may be undefined, or defined from star imports

(F405)


10035-10035: Float may be undefined, or defined from star imports

(F405)


10035-10035: Scalar may be undefined, or defined from star imports

(F405)


10036-10036: quaternion may be undefined, or defined from star imports

(F405)


10036-10036: Float may be undefined, or defined from star imports

(F405)


10042-10042: Scalar may be undefined, or defined from star imports

(F405)


10042-10042: quaternion may be undefined, or defined from star imports

(F405)


10042-10042: Float may be undefined, or defined from star imports

(F405)


10043-10043: quaternion may be undefined, or defined from star imports

(F405)


10043-10043: Float may be undefined, or defined from star imports

(F405)


10049-10049: quaternion may be undefined, or defined from star imports

(F405)


10049-10049: Float may be undefined, or defined from star imports

(F405)


10049-10049: quaternion may be undefined, or defined from star imports

(F405)


10049-10049: Float may be undefined, or defined from star imports

(F405)


10050-10050: quaternion may be undefined, or defined from star imports

(F405)


10050-10050: Float may be undefined, or defined from star imports

(F405)


10163-10163: transformation may be undefined, or defined from star imports

(F405)


10163-10163: Float may be undefined, or defined from star imports

(F405)


10163-10163: transformation may be undefined, or defined from star imports

(F405)


10163-10163: Float may be undefined, or defined from star imports

(F405)


10164-10164: transformation may be undefined, or defined from star imports

(F405)


10164-10164: Float may be undefined, or defined from star imports

(F405)


10170-10170: Scalar may be undefined, or defined from star imports

(F405)


10170-10170: transformation may be undefined, or defined from star imports

(F405)


10170-10170: Float may be undefined, or defined from star imports

(F405)


10171-10171: transformation may be undefined, or defined from star imports

(F405)


10171-10171: Float may be undefined, or defined from star imports

(F405)


10177-10177: transformation may be undefined, or defined from star imports

(F405)


10177-10177: Float may be undefined, or defined from star imports

(F405)


10177-10177: Scalar may be undefined, or defined from star imports

(F405)


10178-10178: transformation may be undefined, or defined from star imports

(F405)


10178-10178: Float may be undefined, or defined from star imports

(F405)


10238-10238: quaternion may be undefined, or defined from star imports

(F405)


10238-10238: Float may be undefined, or defined from star imports

(F405)


10238-10238: Scalar may be undefined, or defined from star imports

(F405)


10239-10239: quaternion may be undefined, or defined from star imports

(F405)


10239-10239: Float may be undefined, or defined from star imports

(F405)


10245-10245: Scalar may be undefined, or defined from star imports

(F405)


10245-10245: quaternion may be undefined, or defined from star imports

(F405)


10245-10245: Float may be undefined, or defined from star imports

(F405)


10246-10246: quaternion may be undefined, or defined from star imports

(F405)


10246-10246: Float may be undefined, or defined from star imports

(F405)


10270-10270: quaternion may be undefined, or defined from star imports

(F405)


10270-10270: Float may be undefined, or defined from star imports

(F405)


10271-10271: quaternion may be undefined, or defined from star imports

(F405)


10271-10271: Float may be undefined, or defined from star imports

(F405)


10292-10292: quaternion may be undefined, or defined from star imports

(F405)


10292-10292: Float may be undefined, or defined from star imports

(F405)


10293-10293: quaternion may be undefined, or defined from star imports

(F405)


10293-10293: Float may be undefined, or defined from star imports

(F405)


11765-11765: quaternion may be undefined, or defined from star imports

(F405)


11765-11765: Float may be undefined, or defined from star imports

(F405)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: ci / test-warp (windows-2025, windows)
  • GitHub Check: ci / test-warp (ubuntu-24.04, ubuntu-x86_64)
  • GitHub Check: ci / test-warp (ubuntu-24.04-arm, ubuntu-aarch64)
  • GitHub Check: ci / build-docs
  • GitHub Check: ci / test-warp (macos-latest, macos)
  • GitHub Check: cppcheck
🔇 Additional comments (17)
docs/_templates/builtins.rst (1)

20-20: LGTM! Docstring indentation fix applied correctly.

Adding first=True ensures the first line of multi-line docstrings is also indented, producing consistent margins within RST function directives.

docs/language_reference/builtins.rst (1)

319-349: LGTM! Documentation reorganization improves structure.

The Utility section is logically placed after Random and before Other. The included items are appropriate for a utility category, and the format is consistent with other sections. The new block_dim builtin mentioned in the PR objectives is properly documented here.

warp/_src/types.py (4)

63-126: LGTM: Forward reference to is_array is safe due to Python's late binding.

The scalar_base class uses is_array(y) in arithmetic methods to delegate to array operations when the operand is an array. Since Python resolves names at call time (not definition time), and is_array is defined in this same module before any scalar operations can occur, this works correctly.

The pattern of returning NotImplemented when the operand is an array allows proper delegation to the array's reflected methods (e.g., __radd__).


147-168: LGTM: Custom bool type correctly shadows the builtin.

The custom bool class intentionally shadows Python's built-in bool within this module. The code correctly uses builtins.bool for return type annotations (e.g., line 67, 154) to distinguish between the Warp type and Python's native boolean. The class appropriately does not inherit from scalar_base since boolean arithmetic operations aren't semantically meaningful in this context.


170-223: LGTM: Concrete scalar type hierarchy is well-structured.

The scalar types are correctly defined with:

  • Appropriate inheritance (float_base for floats, int_base for integers)
  • Consistent _length_ = 1 for scalar indication
  • Correct ctypes mappings for each type
  • float16 correctly using ctypes.c_uint16 for half-precision bit storage

225-253: LGTM: TypeVars with explicit constraints align with Pyright requirements.

The scalar type tuples provide a canonical source of truth, and the TypeVars are correctly defined with explicit constraints as required by Pyright (which doesn't support tuple unpacking in TypeVar definitions). Including both Python builtins (int, float, builtins.bool) and Warp types ensures proper type inference across the codebase.

The comment on line 232-233 is helpful for future maintainers when adding new scalar types.

warp/__init__.pyi (6)

2004-2011: Quaternion type parameter corrections look correct.

The change from Quaternion[Scalar] to Quaternion[Float] aligns with the type definition in warp/_src/types.py where Quaternion is defined as Generic[Float]. This ensures type consistency across the codebase.

Also applies to: 2040-2047, 2076-2083


2143-2146: Consistent type update for length_sq.

The return type Float is appropriate since the squared length of a Quaternion[Float] naturally produces a Float result.


4571-4587: Consolidated tid() signature with union return type is acceptable.

The merge of multiple overloads into a single signature with a union return type follows the PR's approach for handling overloads with identical input types. The docstring clearly documents the unpacking-based behavior.

Note that Python type checkers cannot infer the specific return type based on unpacking syntax (e.g., i, j = wp.tid() will still type as the full union). This is a known limitation, but acceptable given:

  1. This is primarily for IDE autocomplete
  2. Warp's codegen handles the actual dispatch
  3. Separate no-argument overloads would conflict anyway

5699-5711: Arithmetic operations correctly use Float type parameter.

The add and sub overloads for Quaternion[Float] and Transformation[Float] are consistent with the generic type definitions.

Also applies to: 5734-5742


5869-5921: Multiplication, division, and unary operations are correctly typed.

The mixed-type operations (e.g., Quaternion[Float] * Scalar) appropriately use Scalar for the scalar operand while maintaining Float for the quaternion/transformation types. This correctly models scalar multiplication on Float-parameterized types.

Also applies to: 5969-5976, 5993-5996, 6013-6016


6302-6304: len overload for Quaternion is correctly typed.

warp/_src/builtins.py (5)

427-437: Quaternion predicates now correctly constrain dtype to Float.

Switching isfinite/isnan/isinf quaternion overloads to quaternion(dtype=Float) aligns with the “no integers” direction and avoids odd Scalar quaternions showing up in stubs.

Also applies to: 475-486, 524-535


742-747: length_sq(quaternion) returning Float-precision is consistent with length(quaternion).

Using float_sametypes_value_func here looks right for quaternion-only float dtypes and keeps return-type inference consistent.


6925-6935: Hiding reversed(range_t) matches the “don’t expose built-in reversed” objective.

hidden=True + export=False should keep it out of generated stubs/docs while preserving internal availability.


7726-7735: Native binding and codegen wiring are properly implemented.

The C++ implementation exists in warp/native/exports.h (line 1102) and is wired through codegen via macros in warp/_src/codegen.py. The block_dim= parameter in launch APIs uses a different naming context, so no collision occurs.


7629-7724: The tid() stub correctly includes all return types, including int.

The generated .pyi stub file defines tid() with the return type int | tuple[int, int] | tuple[int, int, int] | tuple[int, int, int, int], confirming that the export=False flag on the value_type=int overload does not prevent the plain int return case from being included in the merged stub. The stub generation properly handles the union of all overloads.

@greptile-apps
Copy link

greptile-apps bot commented Jan 13, 2026

Greptile Overview

Greptile Summary

This PR successfully resolves Pyright type checker warnings and enables strict validation in CI/CD pipelines. The changes address four key areas:

1. Hidden reversed built-in - Marked reversed as hidden=True to exclude it from generated stubs and documentation, consistent with similar built-ins like range and iter_next.

2. Fixed RST docstring indentation - Applied Jinja's indent(3, first=True) filter to ensure multi-line docstrings render with consistent 3-space margins in documentation.

3. Merged overlapping wp.tid() overloads - Implemented intelligent stub merging for functions with context-dependent return types:

  • Unified all four wp.tid() docstrings to consistently document unpacking behavior
  • Added add_merged_builtin_function_stub() helper that auto-detects overloads with identical input signatures and generates a single stub with union return type (int | tuple[int, int] | tuple[int, int, int] | tuple[int, int, int, int])
  • This resolves Pyright's overlapping overload warnings for functions where return type depends on usage context (unpacking syntax) rather than input parameters
  • Fixed quaternion type constraints from overly-broad Scalar to appropriate Float for isfinite, isnan, isinf, length_sq, and related operations
  • Refactored types.py to define scalar type classes before TypeVar declarations, enabling proper constraint resolution

4. Enabled strict CI/CD validation - Removed continue-on-error (GitHub Actions) and allow_failure (GitLab CI) flags from Pyright validation jobs, ensuring type errors now fail the build.

All changes are well-structured with proper error handling (exception catching in get_return_type_str(), None handling in type_str()). The generated stubs and documentation have been correctly regenerated.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • Score reflects well-designed implementation with proper error handling, consistent type corrections, and successfully passing CI/CD validation. The changes solve legitimate type checking issues without breaking existing functionality. All auto-generated files have been properly regenerated.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
.github/workflows/ci.yml 5/5 Removed continue-on-error flag from pyright-stubs job to enforce type checking
.gitlab-ci.yml 5/5 Removed allow_failure flag from pyright stubs job to enforce validation
warp/_src/context.py 5/5 Added add_merged_builtin_function_stub() to merge overloads with identical inputs into union return types
warp/_src/builtins.py 5/5 Unified wp.tid() docstrings, marked reversed as hidden, and fixed quaternion type constraints from Scalar to Float
warp/_src/types.py 5/5 Moved scalar type class definitions before TypeVar declarations for proper constraint resolution
warp/init.pyi 5/5 Auto-generated stub with merged wp.tid() signature, corrected quaternion types, and added missing return type annotations

Sequence Diagram

sequenceDiagram
    participant Dev as Developer
    participant Build as build_lib.py
    participant Context as context.py::export_stubs()
    participant Builtins as builtins.py
    participant Stubs as __init__.pyi
    participant CI as CI/CD Pyright
    
    Dev->>Builtins: Define wp.tid() overloads (1D-4D)
    Dev->>Builtins: Mark reversed as hidden=True
    Dev->>Builtins: Fix quaternion types (Scalar→Float)
    
    Build->>Context: Call export_stubs()
    Context->>Builtins: Read builtin_functions
    
    Note over Context: Check overloads with<br/>identical input_types
    
    Context->>Context: Detect wp.tid() has same<br/>input_types ({}) across 4 overloads
    Context->>Context: Call add_merged_builtin_function_stub()
    Context->>Context: Generate union return type:<br/>int | tuple[int,int] | ...
    
    Context->>Stubs: Write merged wp.tid() signature
    Context->>Stubs: Skip reversed (hidden=True)
    Context->>Stubs: Write Quaternion[Float] types
    
    Stubs->>CI: Validate with Pyright
    
    alt Validation passes
        CI->>Dev: ✓ Build succeeds
    else Validation fails
        CI->>Dev: ✗ Build fails (no allow_failure)
    end
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@shi-eric
Copy link
Contributor Author

Reminding myself of a concern that CodeRabbit raised and is worth looking more into tomorrow:

In @warp/_src/types.py around lines 225 - 253, The Scalar TypeVar is constrained
to include bool, but the type_matches_template function uses scalar_types
(which excludes bool) in its Scalar branch, causing a mismatch between static
typing and runtime dispatch; resolve this by either removing bool from Scalar’s
constraints or updating the Scalar case in type_matches_template to check
against scalar_and_bool_types instead of scalar_types so the generic
matching aligns with the intended contract.

@shi-eric shi-eric force-pushed the ershi/fix-more-stub-issues branch from d8e40aa to b0e1f18 Compare January 13, 2026 17:14
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
warp/_src/types.py (1)

2251-2254: Potential typing/runtime mismatch in scalars_equal_generic.

Lines 2251-2254 check scalar_and_bool_types (which includes bool) when matching against Scalar, but the Scalar TypeVar (lines 236-251) explicitly excludes bool. This creates an inconsistency:

  • Static typing: bool is not a valid Scalar (TypeVar excludes it)
  • scalars_equal_generic: bool matches Scalar (uses scalar_and_bool_types)

This could cause confusing behavior where code passes runtime checks but fails static type checking, or vice versa.

Consider updating to use scalar_types instead of scalar_and_bool_types for consistency with the Scalar TypeVar definition, or document this as intentional behavior.

-        if a is Scalar and b in scalar_and_bool_types:
+        if a is Scalar and b in scalar_types:
             return True
-        if b is Scalar and a in scalar_and_bool_types:
+        if b is Scalar and a in scalar_types:
             return True
warp/_src/builtins.py (1)

7635-7724: The builtin_tid{1,2,3,4}d symbols are properly defined; verify documentation covers excess unpacking.

The native function symbols exist as C++ macros in warp/_src/codegen.py. However, the docstring should clarify what happens when callers unpack more indices than the launch dimensionality: excess indices return 0. For example, calling i, j = wp.tid() on a 1D launch will return (i_actual, 0).

warp/_src/context.py (1)

8919-8941: Merge-detection should preserve parameter order (don’t sort input_types.items()).

tuple(sorted(f.input_types.items())) can treat overloads with the same keys/types but different parameter order as identical, then emit a merged stub using the first overload’s order. Since order matters for signatures, comparing tuple(f.input_types.items()) directly is safer and simpler.

Proposed fix
-                first_inputs = tuple(sorted(first.input_types.items()))
+                first_inputs = tuple(first.input_types.items())
                 all_same_inputs = all(
-                    tuple(sorted(f.input_types.items())) == first_inputs for f in non_hidden_overloads
+                    tuple(f.input_types.items()) == first_inputs for f in non_hidden_overloads
                 )
🤖 Fix all issues with AI agents
In @warp/_src/builtins.py:
- Around line 7726-7735: The docstring for the block_dim builtin is too minimal
and should state kernel-context restrictions like tid() does; update the
"block_dim" builtin registration so its doc string (for the builtin named
"block_dim" mapped to native_func "builtin_block_dim") includes whether it may
or may not be called from user-defined Warp functions or only inside
kernels—mirror tid()'s phrasing if the same restriction applies, or explicitly
document any difference in allowed usage and context.
- Around line 10033-10053: The scalar_mul_create_value_func currently uses
next(...) over scalar_types (which excludes bool) and can raise StopIteration
when type matching allowed bool via scalar_and_bool_types; change the next(...)
call inside scalar_mul_create_value_func to supply a sentinel default (e.g.,
None) and then explicitly raise a clear RuntimeError if the result is the
sentinel, so you return a controlled error instead of letting StopIteration
propagate; ensure the error message references the offending input types and
keep the rest of the matching logic unchanged.

In @warp/_src/context.py:
- Around line 8657-8664: The function get_return_type_str calls
f.value_func(None, None) unsafely which can raise and abort stub generation;
change it to first try calling f.value_func with f.input_types (e.g.,
f.value_func(f.input_types, None)) if available, and wrap the call in a
try/except that falls back to using f.value_type (or None) on any exception;
ensure you still convert a resolved return_type via type_str before returning.

In @warp/_src/types.py:
- Around line 225-251: The runtime matching in scalars_equal_generic incorrectly
treats bool as a valid match for the TypeVar Scalar; update the matching logic
so it uses scalar_types (which excludes bool) instead of scalar_and_bool_types
when checking "if a is Scalar and b in ..." and "if b is Scalar and a in ...",
ensuring runtime behavior matches the Scalar TypeVar, or alternatively add bool
to the Scalar TypeVar declaration if you intend bool to be a valid Scalar—prefer
the first option to preserve the current static typing contract.
🧹 Nitpick comments (4)
warp/_src/builtins.py (2)

10161-10181: Transformation mul overloads updated to Float — good; same Scalar/bool hazard applies to scalar multiply.
If Scalar can match bool, the same scalar_mul_create_value_func() StopIteration risk exists for Scalar * transformation and transformation * Scalar.


10236-10249: Quaternion div overloads updated to Float — good; same Scalar/bool hazard applies.

warp/_src/context.py (2)

8666-8679: Consider _builtins.bool normalization for builtin stubs (avoid warp.bool shadowing).

You already import builtins as _builtins and normalize bool in format_annotation(), but builtin stub emission uses type_str() directly, which can emit bool and end up referring to warp.bool in the stub module (not Python’s bool). If Pyright is treating these stubs as the public surface, this can create avoidable typing friction.

Suggestion: apply the same re.sub(r"\bbool\b", "_builtins.bool", ...) normalization to args and return_str (or introduce a stub_type_str() wrapper used only by stub generation).
(confirm desired semantics: should stub signatures accept _builtins.bool or warp.bool?)


8681-8713: Merged return type uses |: verify supported Python/Pyright target, or emit Union[...].

return_str = " -> " + " | ".join(return_types) is great for readability, but it assumes PEP 604 unions are valid for the configured type-checking target. If the project still supports Python < 3.10 for type checking, this will break parsing.

Options:

  • Ensure Pyright config targets 3.10+ for stubs, or
  • Emit Union[...] (and add from typing import Union in the stub header), or
  • Emit typing_extensions.TypeAlias/compat strategy if needed.
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d8e40aa and b0e1f18.

📒 Files selected for processing (6)
  • .github/workflows/ci.yml
  • .gitlab-ci.yml
  • warp/__init__.pyi
  • warp/_src/builtins.py
  • warp/_src/context.py
  • warp/_src/types.py
💤 Files with no reviewable changes (2)
  • .gitlab-ci.yml
  • .github/workflows/ci.yml
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: shi-eric
Repo: NVIDIA/warp PR: 1167
File: warp/tests/test_static.py:776-781
Timestamp: 2026-01-13T06:46:08.692Z
Learning: In the NVIDIA/warp repository, star imports like `from warp.tests.unittest_utils import *` in test files are acceptable per the project's Ruff configuration, and F405 warnings should not be flagged if pre-commit checks pass.
🧬 Code graph analysis (3)
warp/_src/types.py (2)
exts/omni.warp/omni/warp/nodes/_impl/kernel.py (1)
  • is_array (254-255)
warp/__init__.pyi (12)
  • add (5689-5691)
  • add (5694-5696)
  • add (5699-5701)
  • add (5704-5706)
  • add (5709-5711)
  • add (5714-5716)
  • sub (5719-5721)
  • sub (5724-5726)
  • sub (5729-5731)
  • sub (5734-5736)
  • sub (5739-5741)
  • sub (5744-5746)
warp/__init__.pyi (6)
warp/native/crt.h (3)
  • isfinite (341-341)
  • isnan (343-343)
  • isinf (345-345)
warp/_src/types.py (2)
  • Quaternion (262-263)
  • Transformation (266-267)
warp/native/tile.h (1)
  • len (1757-1760)
warp/native/array.h (1)
  • len (2218-2218)
warp/native/mat.h (1)
  • len (5516-5519)
warp/native/vec.h (1)
  • len (2264-2264)
warp/_src/builtins.py (2)
warp/__init__.pyi (6)
  • quaternion (2332-2336)
  • quaternion (2339-2341)
  • quaternion (2344-2346)
  • quaternion (2349-2351)
  • transformation (2412-2414)
  • transformation (2417-2419)
warp/_src/types.py (3)
  • quaternion (1222-1235)
  • dtype (4972-4978)
  • transformation (1250-1327)
🪛 Ruff (0.14.10)
warp/_src/builtins.py

428-428: quaternion may be undefined, or defined from star imports

(F405)


428-428: Float may be undefined, or defined from star imports

(F405)


477-477: quaternion may be undefined, or defined from star imports

(F405)


477-477: Float may be undefined, or defined from star imports

(F405)


526-526: quaternion may be undefined, or defined from star imports

(F405)


526-526: Float may be undefined, or defined from star imports

(F405)


743-743: quaternion may be undefined, or defined from star imports

(F405)


743-743: Float may be undefined, or defined from star imports

(F405)


8829-8829: quaternion may be undefined, or defined from star imports

(F405)


8829-8829: Float may be undefined, or defined from star imports

(F405)


8838-8838: transformation may be undefined, or defined from star imports

(F405)


8838-8838: Float may be undefined, or defined from star imports

(F405)


9065-9065: quaternion may be undefined, or defined from star imports

(F405)


9065-9065: Float may be undefined, or defined from star imports

(F405)


9075-9075: transformation may be undefined, or defined from star imports

(F405)


9075-9075: Float may be undefined, or defined from star imports

(F405)


9103-9103: quaternion may be undefined, or defined from star imports

(F405)


9103-9103: Float may be undefined, or defined from star imports

(F405)


9114-9114: transformation may be undefined, or defined from star imports

(F405)


9114-9114: Float may be undefined, or defined from star imports

(F405)


9136-9136: quaternion may be undefined, or defined from star imports

(F405)


9136-9136: Float may be undefined, or defined from star imports

(F405)


9179-9179: quaternion may be undefined, or defined from star imports

(F405)


9179-9179: Float may be undefined, or defined from star imports

(F405)


9790-9790: quaternion may be undefined, or defined from star imports

(F405)


9790-9790: Float may be undefined, or defined from star imports

(F405)


9790-9790: quaternion may be undefined, or defined from star imports

(F405)


9790-9790: Float may be undefined, or defined from star imports

(F405)


9791-9791: quaternion may be undefined, or defined from star imports

(F405)


9791-9791: Float may be undefined, or defined from star imports

(F405)


9805-9805: transformation may be undefined, or defined from star imports

(F405)


9805-9805: Float may be undefined, or defined from star imports

(F405)


9805-9805: transformation may be undefined, or defined from star imports

(F405)


9805-9805: Float may be undefined, or defined from star imports

(F405)


9806-9806: transformation may be undefined, or defined from star imports

(F405)


9806-9806: Float may be undefined, or defined from star imports

(F405)


9832-9832: quaternion may be undefined, or defined from star imports

(F405)


9832-9832: Float may be undefined, or defined from star imports

(F405)


9832-9832: quaternion may be undefined, or defined from star imports

(F405)


9832-9832: Float may be undefined, or defined from star imports

(F405)


9833-9833: quaternion may be undefined, or defined from star imports

(F405)


9833-9833: Float may be undefined, or defined from star imports

(F405)


9839-9839: transformation may be undefined, or defined from star imports

(F405)


9839-9839: Float may be undefined, or defined from star imports

(F405)


9839-9839: transformation may be undefined, or defined from star imports

(F405)


9839-9839: Float may be undefined, or defined from star imports

(F405)


9840-9840: transformation may be undefined, or defined from star imports

(F405)


9840-9840: Float may be undefined, or defined from star imports

(F405)


10035-10035: quaternion may be undefined, or defined from star imports

(F405)


10035-10035: Float may be undefined, or defined from star imports

(F405)


10035-10035: Scalar may be undefined, or defined from star imports

(F405)


10036-10036: quaternion may be undefined, or defined from star imports

(F405)


10036-10036: Float may be undefined, or defined from star imports

(F405)


10042-10042: Scalar may be undefined, or defined from star imports

(F405)


10042-10042: quaternion may be undefined, or defined from star imports

(F405)


10042-10042: Float may be undefined, or defined from star imports

(F405)


10043-10043: quaternion may be undefined, or defined from star imports

(F405)


10043-10043: Float may be undefined, or defined from star imports

(F405)


10049-10049: quaternion may be undefined, or defined from star imports

(F405)


10049-10049: Float may be undefined, or defined from star imports

(F405)


10049-10049: quaternion may be undefined, or defined from star imports

(F405)


10049-10049: Float may be undefined, or defined from star imports

(F405)


10050-10050: quaternion may be undefined, or defined from star imports

(F405)


10050-10050: Float may be undefined, or defined from star imports

(F405)


10163-10163: transformation may be undefined, or defined from star imports

(F405)


10163-10163: Float may be undefined, or defined from star imports

(F405)


10163-10163: transformation may be undefined, or defined from star imports

(F405)


10163-10163: Float may be undefined, or defined from star imports

(F405)


10164-10164: transformation may be undefined, or defined from star imports

(F405)


10164-10164: Float may be undefined, or defined from star imports

(F405)


10170-10170: Scalar may be undefined, or defined from star imports

(F405)


10170-10170: transformation may be undefined, or defined from star imports

(F405)


10170-10170: Float may be undefined, or defined from star imports

(F405)


10171-10171: transformation may be undefined, or defined from star imports

(F405)


10171-10171: Float may be undefined, or defined from star imports

(F405)


10177-10177: transformation may be undefined, or defined from star imports

(F405)


10177-10177: Float may be undefined, or defined from star imports

(F405)


10177-10177: Scalar may be undefined, or defined from star imports

(F405)


10178-10178: transformation may be undefined, or defined from star imports

(F405)


10178-10178: Float may be undefined, or defined from star imports

(F405)


10238-10238: quaternion may be undefined, or defined from star imports

(F405)


10238-10238: Float may be undefined, or defined from star imports

(F405)


10238-10238: Scalar may be undefined, or defined from star imports

(F405)


10239-10239: quaternion may be undefined, or defined from star imports

(F405)


10239-10239: Float may be undefined, or defined from star imports

(F405)


10245-10245: Scalar may be undefined, or defined from star imports

(F405)


10245-10245: quaternion may be undefined, or defined from star imports

(F405)


10245-10245: Float may be undefined, or defined from star imports

(F405)


10246-10246: quaternion may be undefined, or defined from star imports

(F405)


10246-10246: Float may be undefined, or defined from star imports

(F405)


10270-10270: quaternion may be undefined, or defined from star imports

(F405)


10270-10270: Float may be undefined, or defined from star imports

(F405)


10271-10271: quaternion may be undefined, or defined from star imports

(F405)


10271-10271: Float may be undefined, or defined from star imports

(F405)


10292-10292: quaternion may be undefined, or defined from star imports

(F405)


10292-10292: Float may be undefined, or defined from star imports

(F405)


10293-10293: quaternion may be undefined, or defined from star imports

(F405)


10293-10293: Float may be undefined, or defined from star imports

(F405)


11765-11765: quaternion may be undefined, or defined from star imports

(F405)


11765-11765: Float may be undefined, or defined from star imports

(F405)

🔇 Additional comments (25)
warp/_src/types.py (6)

63-126: LGTM - Well-structured scalar base class.

The scalar_base class provides a clean foundation for the scalar type hierarchy. The arithmetic operations correctly return NotImplemented when the other operand is an array, allowing Python's operator dispatch to handle mixed-type operations properly.


128-145: LGTM - Proper intermediate base classes.

The float_base and int_base classes appropriately extend scalar_base with type-specific behavior. The __index__ method in int_base correctly uses ctypes conversion for proper integer truncation semantics.


147-168: LGTM - Intentional design for bool type.

The bool class intentionally does not inherit from scalar_base, which prevents arithmetic operations on boolean values. This is appropriate since boolean arithmetic semantics differ from numeric scalars. The class correctly shadows builtins.bool, and the code consistently uses builtins.bool where Python's native bool type is needed.


170-223: LGTM - Consistent scalar type definitions.

The concrete scalar types correctly inherit from their respective base classes and define appropriate ctypes mappings. The use of ctypes.c_uint16 for float16 is correct since half-precision floats are stored as their bit representation.


2148-2153: LGTM - Correct value type handling.

The value_types tuple appropriately includes both Python's builtins.bool and Warp's bool type through scalar_and_bool_types, ensuring proper value detection at runtime.


5920-5927: LGTM - Consistent Scalar template matching.

The type_matches_template function correctly checks arg_type in scalar_types for Scalar template types, which is consistent with the Scalar TypeVar definition that excludes bool.

warp/_src/builtins.py (15)

427-437: Quaternion isfinite() overload to quaternion(dtype=Float) looks consistent with “float-only” direction.
This aligns the quaternion overload with the deprecation messaging about integer inputs.


475-486: Quaternion isnan() overload to quaternion(dtype=Float) looks consistent.


524-535: Quaternion isinf() overload to quaternion(dtype=Float) looks consistent.


742-747: length_sq() quaternion overload switching to Float + float-type inference is correct.
Using float_sametypes_value_func here matches the “quaternion is float-like” model and avoids integer return typing.


6925-6935: Hiding reversed from stubs/docs is sensible (matches range/iter_next treatment).


8828-8844: Updating extract() overloads to quaternion(dtype=Float) / transformation(dtype=Float) is consistent with the new typing model.


9063-9081: assign_inplace overloads for quaternion/transformation updated consistently to Float.


9100-9120: assign_copy overloads for quaternion/transformation updated consistently to Float.


9133-9142: add_inplace quaternion overload updated consistently to Float.


9176-9185: sub_inplace quaternion overload updated consistently to Float.


9776-9809: Operator add overloads updated to Float for quaternion/transformation — looks correct.


9811-9843: Operator sub overloads updated to Float for quaternion/transformation — looks correct.


10268-10274: Unary pos quaternion overload updated to Float — looks correct.


10290-10296: Unary neg quaternion overload updated to Float — looks correct.


11763-11771: len(quaternion) overload updated to Float — looks correct.

warp/__init__.pyi (4)

2004-2011: Type parameter correction looks good.

The change from Quaternion[Scalar] to Quaternion[Float] for isfinite, isnan, isinf, and length_sq correctly aligns with the Quaternion class definition (Generic[Float]) in types.py. These mathematical operations are only meaningful for floating-point types.

Also applies to: 2040-2047, 2076-2083, 2143-2146


4571-4587: Consolidated tid() signature with clear documentation.

The merged overload using a union return type effectively communicates the function's behavior. The docstring clearly explains how the return type depends on the unpacking syntax used at the call site, which is helpful for users understanding the dynamic nature of this kernel intrinsic.


5699-5700: Quaternion arithmetic operators correctly updated to Float.

The quaternion arithmetic operations now consistently use Quaternion[Float], matching the generic class definition. The scalar operands in mul and div appropriately remain Scalar to allow numeric flexibility while ensuring the quaternion container type is constrained to floating-point.

Also applies to: 5734-5735, 5869-5880, 5969-5975, 5993-5994, 6013-6014


5709-5710: Transformation and len() changes are consistent.

The Transformation operations and len() overload for quaternions are correctly updated to use Float, consistent with their generic class definitions in types.py.

Also applies to: 5739-5740, 5909-5920, 6302-6303

- Unify wp.tid() docstrings across all overloads in builtins.py
- Add add_merged_builtin_function_stub() to detect and merge overloads
  with identical input_types into a single stub with union return type
- Fix quaternion type parameters for isfinite/isnan/isinf/length_sq
  (Scalar -> Float)
- Refactor scalar type definitions in types.py for earlier availability

Resolves type checker warnings about overlapping function signatures
where return type depends on usage context rather than input parameters.

Signed-off-by: Eric Shi <ershi@nvidia.com>
Signed-off-by: Eric Shi <ershi@nvidia.com>
Use scalar_types instead of scalar_and_bool_types when matching the
Scalar TypeVar in types_match(). This aligns with type_matches_template()
and prevents potential StopIteration crashes in value_func helpers like
scalar_mul_create_value_func() that search only scalar_types.

Signed-off-by: Eric Shi <ershi@nvidia.com>
@shi-eric shi-eric force-pushed the ershi/fix-more-stub-issues branch from b0e1f18 to ac40cec Compare January 13, 2026 17:54
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
warp/_src/builtins.py (1)

7628-7724: Add test coverage for tid() kernel-only enforcement and block_dim() in user functions.

The compiler correctly enforces that tid() cannot be called from user-defined Warp functions via check_tid_in_func_error() in codegen.py (lines 2607–2613), and block_dim() is properly registered as a public builtin with no such restrictions. However, test coverage explicitly verifying this distinction is missing—add tests confirming tid() raises WarpCodegenError when called in @wp.func and block_dim() works correctly in user-defined functions.

🧹 Nitpick comments (2)
warp/_src/context.py (2)

8922-8937: Don’t ignore parameter order when deciding “identical input_types” merges.

The merge predicate uses tuple(sorted(f.input_types.items())), which treats the same params in a different order as “identical”. But order is part of the effective signature (and Warp’s Function.signature is built from input_types.keys() order). Safer: compare tuple(f.input_types.items()) directly (order-preserving), so you only merge truly identical signatures.

Proposed diff
                 first = non_hidden_overloads[0]
-                first_inputs = tuple(sorted(first.input_types.items()))
-                all_same_inputs = all(
-                    tuple(sorted(f.input_types.items())) == first_inputs for f in non_hidden_overloads
-                )
+                first_inputs = tuple(first.input_types.items())
+                all_same_inputs = all(tuple(f.input_types.items()) == first_inputs for f in non_hidden_overloads)

                 if all_same_inputs:
                     add_merged_builtin_function_stub(non_hidden_overloads)
                     continue

Also applies to: 8938-8942


8682-8714: PEP 604 union syntax is currently compatible with your Pyright setup; however, consider explicitly setting pythonVersion if 3.9 type-checking support is desired.

The code uses " | ".join(return_types) which generates PEP 604 syntax (A | B). While this is only valid in Python 3.10+, Pyright currently has no explicit pythonVersion configured in pyproject.toml, so it infers from the running Python version in CI (3.11+) and will accept this syntax.

However, since the project declares requires-python = ">=3.9", if you want strict type-checking compatibility with Python 3.9, add pythonVersion = "3.10" (or higher) to the [tool.pyright] section, or switch to Union[...] syntax with from typing import Union in the stub header for broader 3.9 compatibility.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b0e1f18 and ac40cec.

📒 Files selected for processing (6)
  • .github/workflows/ci.yml
  • .gitlab-ci.yml
  • warp/__init__.pyi
  • warp/_src/builtins.py
  • warp/_src/context.py
  • warp/_src/types.py
💤 Files with no reviewable changes (2)
  • .gitlab-ci.yml
  • .github/workflows/ci.yml
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: shi-eric
Repo: NVIDIA/warp PR: 1167
File: warp/tests/test_static.py:776-781
Timestamp: 2026-01-13T06:46:08.692Z
Learning: In the NVIDIA/warp repository, star imports like `from warp.tests.unittest_utils import *` in test files are acceptable per the project's Ruff configuration, and F405 warnings should not be flagged if pre-commit checks pass.
📚 Learning: 2026-01-13T17:29:07.264Z
Learnt from: shi-eric
Repo: NVIDIA/warp PR: 1171
File: warp/_src/builtins.py:7726-7735
Timestamp: 2026-01-13T17:29:07.264Z
Learning: In warp/_src/builtins.py (NVIDIA/warp), enforce that block_dim() may be called from user-defined Warp functions, while tid() is kernel-only and must not be called from Warp function bodies. Ensure the builtins registration and related usage enforce this distinction, and add tests to verify allowed vs disallowed calls in user-defined Warp functions.

Applied to files:

  • warp/_src/builtins.py
📚 Learning: 2025-09-28T18:45:45.955Z
Learnt from: StafaH
Repo: NVIDIA/warp PR: 925
File: warp/native/bvh.h:359-369
Timestamp: 2025-09-28T18:45:45.955Z
Learning: StafaH prefers to defer the BVH shared stack stride issue (hardcoded WP_BVH_BLOCK_DIM vs runtime blockDim.x) for a future update rather than implementing the dynamic shared memory solution now.

Applied to files:

  • warp/_src/builtins.py
📚 Learning: 2026-01-13T17:29:07.264Z
Learnt from: shi-eric
Repo: NVIDIA/warp PR: 1171
File: warp/_src/builtins.py:7726-7735
Timestamp: 2026-01-13T17:29:07.264Z
Learning: In NVIDIA/warp (PR #1171), block_dim() may be called from user-defined Warp functions, while tid() may not; tid() is kernel-only. File context: warp/_src/builtins.py builtins registration.

Applied to files:

  • warp/__init__.pyi
🧬 Code graph analysis (4)
warp/_src/context.py (1)
warp/_src/utils.py (1)
  • warn (70-84)
warp/_src/types.py (2)
exts/omni.warp/omni/warp/nodes/_impl/kernel.py (1)
  • is_array (254-255)
warp/__init__.pyi (12)
  • add (5689-5691)
  • add (5694-5696)
  • add (5699-5701)
  • add (5704-5706)
  • add (5709-5711)
  • add (5714-5716)
  • sub (5719-5721)
  • sub (5724-5726)
  • sub (5729-5731)
  • sub (5734-5736)
  • sub (5739-5741)
  • sub (5744-5746)
warp/_src/builtins.py (2)
warp/_src/types.py (5)
  • quaternion (1222-1235)
  • dtype (4972-4978)
  • vector (527-736)
  • transformation (1250-1327)
  • matrix (740-1160)
warp/__init__.pyi (11)
  • quaternion (2332-2336)
  • quaternion (2339-2341)
  • quaternion (2344-2346)
  • quaternion (2349-2351)
  • vector (2224-2226)
  • length (2129-2131)
  • length (2134-2136)
  • transformation (2412-2414)
  • transformation (2417-2419)
  • matrix (2229-2240)
  • matrix (2243-2245)
warp/__init__.pyi (2)
warp/_src/types.py (6)
  • dtype (4972-4978)
  • Array (270-360)
  • Quaternion (262-263)
  • Vector (254-255)
  • Transformation (266-267)
  • Tile (363-364)
warp/native/vec.h (1)
  • expect_near (1295-1312)
🪛 Ruff (0.14.11)
warp/_src/context.py

8663-8664: try-except-pass detected, consider logging the exception

(S110)


8663-8663: Do not catch blind exception: Exception

(BLE001)

warp/_src/builtins.py

428-428: quaternion may be undefined, or defined from star imports

(F405)


428-428: Float may be undefined, or defined from star imports

(F405)


477-477: quaternion may be undefined, or defined from star imports

(F405)


477-477: Float may be undefined, or defined from star imports

(F405)


526-526: quaternion may be undefined, or defined from star imports

(F405)


526-526: Float may be undefined, or defined from star imports

(F405)


743-743: quaternion may be undefined, or defined from star imports

(F405)


743-743: Float may be undefined, or defined from star imports

(F405)


8830-8830: vector may be undefined, or defined from star imports

(F405)


8839-8839: quaternion may be undefined, or defined from star imports

(F405)


8839-8839: Float may be undefined, or defined from star imports

(F405)


8848-8848: transformation may be undefined, or defined from star imports

(F405)


8848-8848: Float may be undefined, or defined from star imports

(F405)


8921-8921: matrix may be undefined, or defined from star imports

(F405)


8930-8930: matrix may be undefined, or defined from star imports

(F405)


8981-8981: vector may be undefined, or defined from star imports

(F405)


9025-9025: vector may be undefined, or defined from star imports

(F405)


9047-9047: matrix may be undefined, or defined from star imports

(F405)


9127-9127: quaternion may be undefined, or defined from star imports

(F405)


9127-9127: Float may be undefined, or defined from star imports

(F405)


9137-9137: transformation may be undefined, or defined from star imports

(F405)


9137-9137: Float may be undefined, or defined from star imports

(F405)


9165-9165: quaternion may be undefined, or defined from star imports

(F405)


9165-9165: Float may be undefined, or defined from star imports

(F405)


9176-9176: transformation may be undefined, or defined from star imports

(F405)


9176-9176: Float may be undefined, or defined from star imports

(F405)


9198-9198: quaternion may be undefined, or defined from star imports

(F405)


9198-9198: Float may be undefined, or defined from star imports

(F405)


9241-9241: quaternion may be undefined, or defined from star imports

(F405)


9241-9241: Float may be undefined, or defined from star imports

(F405)


9694-9694: vector may be undefined, or defined from star imports

(F405)


9694-9694: vector may be undefined, or defined from star imports

(F405)


9704-9704: vector may be undefined, or defined from star imports

(F405)


9704-9704: vector may be undefined, or defined from star imports

(F405)


9715-9715: matrix may be undefined, or defined from star imports

(F405)


9715-9715: matrix may be undefined, or defined from star imports

(F405)


9725-9725: matrix may be undefined, or defined from star imports

(F405)


9725-9725: matrix may be undefined, or defined from star imports

(F405)


9896-9896: quaternion may be undefined, or defined from star imports

(F405)


9896-9896: Float may be undefined, or defined from star imports

(F405)


9896-9896: quaternion may be undefined, or defined from star imports

(F405)


9896-9896: Float may be undefined, or defined from star imports

(F405)


9897-9897: quaternion may be undefined, or defined from star imports

(F405)


9897-9897: Float may be undefined, or defined from star imports

(F405)


9911-9911: transformation may be undefined, or defined from star imports

(F405)


9911-9911: Float may be undefined, or defined from star imports

(F405)


9911-9911: transformation may be undefined, or defined from star imports

(F405)


9911-9911: Float may be undefined, or defined from star imports

(F405)


9912-9912: transformation may be undefined, or defined from star imports

(F405)


9912-9912: Float may be undefined, or defined from star imports

(F405)


9938-9938: quaternion may be undefined, or defined from star imports

(F405)


9938-9938: Float may be undefined, or defined from star imports

(F405)


9938-9938: quaternion may be undefined, or defined from star imports

(F405)


9938-9938: Float may be undefined, or defined from star imports

(F405)


9939-9939: quaternion may be undefined, or defined from star imports

(F405)


9939-9939: Float may be undefined, or defined from star imports

(F405)


9945-9945: transformation may be undefined, or defined from star imports

(F405)


9945-9945: Float may be undefined, or defined from star imports

(F405)


9945-9945: transformation may be undefined, or defined from star imports

(F405)


9945-9945: Float may be undefined, or defined from star imports

(F405)


9946-9946: transformation may be undefined, or defined from star imports

(F405)


9946-9946: Float may be undefined, or defined from star imports

(F405)


10141-10141: quaternion may be undefined, or defined from star imports

(F405)


10141-10141: Float may be undefined, or defined from star imports

(F405)


10141-10141: Scalar may be undefined, or defined from star imports

(F405)


10142-10142: quaternion may be undefined, or defined from star imports

(F405)


10142-10142: Float may be undefined, or defined from star imports

(F405)


10148-10148: Scalar may be undefined, or defined from star imports

(F405)


10148-10148: quaternion may be undefined, or defined from star imports

(F405)


10148-10148: Float may be undefined, or defined from star imports

(F405)


10149-10149: quaternion may be undefined, or defined from star imports

(F405)


10149-10149: Float may be undefined, or defined from star imports

(F405)


10155-10155: quaternion may be undefined, or defined from star imports

(F405)


10155-10155: Float may be undefined, or defined from star imports

(F405)


10155-10155: quaternion may be undefined, or defined from star imports

(F405)


10155-10155: Float may be undefined, or defined from star imports

(F405)


10156-10156: quaternion may be undefined, or defined from star imports

(F405)


10156-10156: Float may be undefined, or defined from star imports

(F405)


10269-10269: transformation may be undefined, or defined from star imports

(F405)


10269-10269: Float may be undefined, or defined from star imports

(F405)


10269-10269: transformation may be undefined, or defined from star imports

(F405)


10269-10269: Float may be undefined, or defined from star imports

(F405)


10270-10270: transformation may be undefined, or defined from star imports

(F405)


10270-10270: Float may be undefined, or defined from star imports

(F405)


10276-10276: Scalar may be undefined, or defined from star imports

(F405)


10276-10276: transformation may be undefined, or defined from star imports

(F405)


10276-10276: Float may be undefined, or defined from star imports

(F405)


10277-10277: transformation may be undefined, or defined from star imports

(F405)


10277-10277: Float may be undefined, or defined from star imports

(F405)


10283-10283: transformation may be undefined, or defined from star imports

(F405)


10283-10283: Float may be undefined, or defined from star imports

(F405)


10283-10283: Scalar may be undefined, or defined from star imports

(F405)


10284-10284: transformation may be undefined, or defined from star imports

(F405)


10284-10284: Float may be undefined, or defined from star imports

(F405)


10344-10344: quaternion may be undefined, or defined from star imports

(F405)


10344-10344: Float may be undefined, or defined from star imports

(F405)


10344-10344: Scalar may be undefined, or defined from star imports

(F405)


10345-10345: quaternion may be undefined, or defined from star imports

(F405)


10345-10345: Float may be undefined, or defined from star imports

(F405)


10351-10351: Scalar may be undefined, or defined from star imports

(F405)


10351-10351: quaternion may be undefined, or defined from star imports

(F405)


10351-10351: Float may be undefined, or defined from star imports

(F405)


10352-10352: quaternion may be undefined, or defined from star imports

(F405)


10352-10352: Float may be undefined, or defined from star imports

(F405)


10376-10376: quaternion may be undefined, or defined from star imports

(F405)


10376-10376: Float may be undefined, or defined from star imports

(F405)


10377-10377: quaternion may be undefined, or defined from star imports

(F405)


10377-10377: Float may be undefined, or defined from star imports

(F405)


10398-10398: quaternion may be undefined, or defined from star imports

(F405)


10398-10398: Float may be undefined, or defined from star imports

(F405)


10399-10399: quaternion may be undefined, or defined from star imports

(F405)


10399-10399: Float may be undefined, or defined from star imports

(F405)


11871-11871: quaternion may be undefined, or defined from star imports

(F405)


11871-11871: Float may be undefined, or defined from star imports

(F405)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: ci / test-warp (macos-latest, macos)
  • GitHub Check: ci / test-warp (ubuntu-24.04, ubuntu-x86_64)
  • GitHub Check: ci / test-warp (windows-2025, windows)
  • GitHub Check: ci / test-warp (ubuntu-24.04-arm, ubuntu-aarch64)
  • GitHub Check: ci / build-docs
🔇 Additional comments (19)
warp/_src/types.py (4)

63-145: LGTM - Well-designed base classes for scalar types.

The scalar_base, float_base, and int_base hierarchy properly handles:

  • Arithmetic operator delegation to warp.add, warp.sub, etc.
  • Correct NotImplemented return for array operands to enable proper operator dispatch
  • __index__ implementation in int_base for proper integer conversion through ctypes

147-168: LGTM - Bool class correctly excludes arithmetic operators.

The bool class intentionally does not inherit from scalar_base, which means it doesn't have arithmetic operators. This is semantically correct for boolean types and aligns with the separation of scalar_types (without bool) and scalar_and_bool_types (with bool).


225-251: LGTM - Consistent type system definitions with good maintainability comments.

The canonical tuple definitions (int_types, float_types, scalar_types, scalar_and_bool_types) and corresponding TypeVars (Int, Float, Scalar) are now properly aligned:

  • Scalar TypeVar excludes bool, matching scalar_types
  • Comment at lines 232-233 explicitly notes the need to keep TypeVars in sync with tuples

This addresses the typing vs runtime-dispatch consistency concern mentioned in PR comments.


2251-2256: LGTM - Runtime matching now consistent with Scalar TypeVar definition.

The change from scalar_and_bool_types to scalar_types for Scalar matching ensures that runtime type dispatch aligns with the static Scalar TypeVar definition (which excludes bool). This resolves the typing vs runtime-dispatch mismatch noted in the PR comments.

warp/_src/context.py (1)

8667-8680: Nice cleanup: centralizing return-type formatting reduces divergence.

Using get_return_type_str() in add_builtin_function_stub() is a clear improvement and makes it easier to keep merged/unmerged stub paths consistent.

warp/_src/builtins.py (7)

426-437: Quaternion isfinite/isnan/isinf now float-only — looks consistent with the deprecation messaging.
Switching these overloads to quaternion(dtype=Float) prevents “integer quaternion” ambiguity while scalar/vector/matrix paths can continue the deprecation warning behavior.

Also applies to: 475-486, 524-535


734-747: length_sq(quaternion) return-type inference matches the new float-only quaternion contract.
Using float_sametypes_value_func here is a good consistency improvement vs the vector Scalar variant.


6925-6935: Hide reversed(range) from stubs/docs — aligns with range / iter_next treatment.


8827-8854: Bool-specific extract() overloads are a solid fix for “bool not part of Scalar”.
Nice to see this handled explicitly for vector/matrix, and kept hidden since it’s an implementation detail.

Also applies to: 8918-8936


9691-9733: Bool expect_eq/expect_neq overloads are consistent with the Scalar/bool split.


9124-9247: No action needed: Quaternion/Transformation dtype migration is complete.

The codebase contains zero instances of non-float quaternion or transformation usage. All type definitions (quath, quatf, quatd, transformh, transformf, transformd) are float-only, and default value functions return Float. No int/bool dtypes are used, and dispatch implementations (quaternion_dispatch_func, transformation_dispatch_func) are properly defined and consistent with the runtime code.


8978-8988: The bool index/indexref overloads are properly supported by the backend. Tests in test_bool.py confirm that bool vector and matrix element access works correctly, including reading from bool_selector_vec[0] and bool_selector_mat[0,0]. The C++ vec_t<Length, Type> template handles bool uniformly as any other scalar type, and Reference(bool) correctly generates to bool* in compiled code with proper namespace handling.

Likely an incorrect or invalid review comment.

warp/__init__.pyi (7)

1781-1789: LGTM!

The kernel-scope zeros overloads correctly return Array[Scalar] to support creating arrays of any scalar dtype.


2004-2011: LGTM!

The Quaternion type parameter changes from Scalar to Float correctly align with the Quaternion(Generic[Float]) definition in types.py, resolving type-checker warnings about overlapping overloads.

Also applies to: 2040-2047, 2076-2083, 2143-2146


4571-4587: LGTM!

The consolidated tid() signature with a union return type elegantly captures the unpacking-based semantics while avoiding overlapping overload issues. The comprehensive docstring clearly documents the behavior for each unpacking pattern. Based on retrieved learnings, the note that this function is kernel-only is correctly preserved.


2266-2266: LGTM!

The explicit -> None return type annotations for void functions improve type safety and Pyright compliance. This is best practice for stub files.

Also applies to: 2287-2287, 2307-2307, 2325-2325, 2367-2367, 2433-2437, 2540-2550, 4559-4567


5699-5699: LGTM!

The Quaternion and Transformation operator overloads correctly use Float as the type parameter, consistent with their generic definitions. The use of Scalar for scalar operands in mul and div is appropriate since multiplying/dividing a quaternion by any numeric type (int or float) should be valid.

Also applies to: 5709-5709, 5734-5734, 5739-5739, 5869-5881, 5909-5921, 5969-5975, 5993-5993, 6013-6013


6301-6304: LGTM!

Consistent with the other Quaternion type parameter updates.


2897-2897: LGTM!

The -> None return type annotations for tile operations are appropriate for in-place and void functions.

Also applies to: 2911-2911, 2917-2917, 3095-3095, 3369-3369, 6087-6088, 6132-6132, 6146-6146, 6179-6179, 6213-6213, 6245-6245, 6279-6279

@shi-eric
Copy link
Contributor Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Jan 13, 2026

✅ Actions performed

Full review triggered.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
warp/_src/builtins.py (2)

7628-7735: Add regression test for tid() kernel-only restriction and block_dim() allowed in @wp.func.

The compiler already enforces kernel-only restrictions for tid() via check_tid_in_func_error() in codegen.py, and block_dim() is properly exported (default export=True). However, add a test case to ensure:

  • @wp.func calling tid() raises WarpCodegenError
  • @wp.func calling block_dim() succeeds

9124-9258: Scalar-multiply/divide overloads use flexible Scalar input type but enforce strict type matching.

The quaternion and transformation scalar-multiply/divide operations accept Scalar in their input_types (e.g., "b": Scalar), but the scalar_mul_create_value_func constraint requires the scalar type to exactly match the compound type's dtype. For quaternion(dtype=Float), this means the scalar must be Float, not int. Users writing quat * 2 will hit a runtime error "Object and coefficient must have the same scalar type when multiplying by scalar" if Warp infers the literal 2 as int. Consider either constraining scalar factors to Float explicitly (matching the compound type's actual requirement) or documenting that numeric literals must be float-typed.

🤖 Fix all issues with AI agents
In @warp/_src/context.py:
- Around line 8657-8665: Narrow the broad except in get_return_type_str:
explicitly catch TypeError when calling f.value_func(None, None) and silently
fall back to f.value_type, and add a separate except Exception as e branch that
logs the unexpected exception when verbose mode is enabled (using the project's
existing logging/verbose facility) before falling back to f.value_type; keep the
final return as type_str(return_type) and only suppress the well-known TypeError
case.
🧹 Nitpick comments (1)
warp/_src/context.py (1)

8920-8942: Overload merging only triggers when all overloads share inputs—consider grouping by signature.

As written, you merge only if every non-hidden overload has the same input_types. If a function has mixed overload groups (some identical inputs, some not), you’ll miss the merge opportunity that the helper name/PR intent suggests.

Sketch of a grouping approach
-            if len(non_hidden_overloads) > 1:
-                first = non_hidden_overloads[0]
-                first_inputs = tuple(sorted(first.input_types.items()))
-                all_same_inputs = all(
-                    tuple(sorted(f.input_types.items())) == first_inputs for f in non_hidden_overloads
-                )
-
-                if all_same_inputs:
-                    add_merged_builtin_function_stub(non_hidden_overloads)
-                    continue
+            if len(non_hidden_overloads) > 1:
+                groups = {}
+                for f in non_hidden_overloads:
+                    key = tuple(sorted(f.input_types.items()))
+                    groups.setdefault(key, []).append(f)
+                if any(len(v) > 1 for v in groups.values()):
+                    for v in groups.values():
+                        if len(v) > 1:
+                            add_merged_builtin_function_stub(v)
+                        else:
+                            add_builtin_function_stub(v[0], use_overload=False)
+                    continue
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a12c56c and ac40cec.

📒 Files selected for processing (8)
  • .github/workflows/ci.yml
  • .gitlab-ci.yml
  • docs/_templates/builtins.rst
  • docs/language_reference/builtins.rst
  • warp/__init__.pyi
  • warp/_src/builtins.py
  • warp/_src/context.py
  • warp/_src/types.py
💤 Files with no reviewable changes (2)
  • .github/workflows/ci.yml
  • .gitlab-ci.yml
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: shi-eric
Repo: NVIDIA/warp PR: 1167
File: warp/tests/test_static.py:776-781
Timestamp: 2026-01-13T06:46:08.692Z
Learning: In the NVIDIA/warp repository, star imports like `from warp.tests.unittest_utils import *` in test files are acceptable per the project's Ruff configuration, and F405 warnings should not be flagged if pre-commit checks pass.
📚 Learning: 2026-01-13T17:29:07.264Z
Learnt from: shi-eric
Repo: NVIDIA/warp PR: 1171
File: warp/_src/builtins.py:7726-7735
Timestamp: 2026-01-13T17:29:07.264Z
Learning: In warp/_src/builtins.py (NVIDIA/warp), enforce that block_dim() may be called from user-defined Warp functions, while tid() is kernel-only and must not be called from Warp function bodies. Ensure the builtins registration and related usage enforce this distinction, and add tests to verify allowed vs disallowed calls in user-defined Warp functions.

Applied to files:

  • warp/_src/builtins.py
📚 Learning: 2025-09-28T18:45:45.955Z
Learnt from: StafaH
Repo: NVIDIA/warp PR: 925
File: warp/native/bvh.h:359-369
Timestamp: 2025-09-28T18:45:45.955Z
Learning: StafaH prefers to defer the BVH shared stack stride issue (hardcoded WP_BVH_BLOCK_DIM vs runtime blockDim.x) for a future update rather than implementing the dynamic shared memory solution now.

Applied to files:

  • warp/_src/builtins.py
📚 Learning: 2026-01-13T17:29:07.264Z
Learnt from: shi-eric
Repo: NVIDIA/warp PR: 1171
File: warp/_src/builtins.py:7726-7735
Timestamp: 2026-01-13T17:29:07.264Z
Learning: In NVIDIA/warp (PR #1171), block_dim() may be called from user-defined Warp functions, while tid() may not; tid() is kernel-only. File context: warp/_src/builtins.py builtins registration.

Applied to files:

  • warp/__init__.pyi
🧬 Code graph analysis (3)
warp/_src/types.py (1)
warp/__init__.pyi (6)
  • add (5689-5691)
  • add (5694-5696)
  • add (5699-5701)
  • add (5704-5706)
  • add (5709-5711)
  • add (5714-5716)
warp/_src/builtins.py (2)
warp/_src/types.py (4)
  • quaternion (1222-1235)
  • dtype (4972-4978)
  • vector (527-736)
  • matrix (740-1160)
warp/__init__.pyi (9)
  • quaternion (2332-2336)
  • quaternion (2339-2341)
  • quaternion (2344-2346)
  • quaternion (2349-2351)
  • vector (2224-2226)
  • length (2129-2131)
  • length (2134-2136)
  • matrix (2229-2240)
  • matrix (2243-2245)
warp/__init__.pyi (3)
warp/_src/types.py (3)
  • Quaternion (262-263)
  • Vector (254-255)
  • Transformation (266-267)
warp/native/array.h (1)
  • len (2218-2218)
warp/native/mat.h (1)
  • len (5516-5519)
🪛 Ruff (0.14.11)
warp/_src/context.py

8663-8664: try-except-pass detected, consider logging the exception

(S110)


8663-8663: Do not catch blind exception: Exception

(BLE001)

warp/_src/builtins.py

428-428: quaternion may be undefined, or defined from star imports

(F405)


428-428: Float may be undefined, or defined from star imports

(F405)


477-477: quaternion may be undefined, or defined from star imports

(F405)


477-477: Float may be undefined, or defined from star imports

(F405)


526-526: quaternion may be undefined, or defined from star imports

(F405)


526-526: Float may be undefined, or defined from star imports

(F405)


743-743: quaternion may be undefined, or defined from star imports

(F405)


743-743: Float may be undefined, or defined from star imports

(F405)


8830-8830: vector may be undefined, or defined from star imports

(F405)


8839-8839: quaternion may be undefined, or defined from star imports

(F405)


8839-8839: Float may be undefined, or defined from star imports

(F405)


8848-8848: transformation may be undefined, or defined from star imports

(F405)


8848-8848: Float may be undefined, or defined from star imports

(F405)


8921-8921: matrix may be undefined, or defined from star imports

(F405)


8930-8930: matrix may be undefined, or defined from star imports

(F405)


8981-8981: vector may be undefined, or defined from star imports

(F405)


9025-9025: vector may be undefined, or defined from star imports

(F405)


9047-9047: matrix may be undefined, or defined from star imports

(F405)


9127-9127: quaternion may be undefined, or defined from star imports

(F405)


9127-9127: Float may be undefined, or defined from star imports

(F405)


9137-9137: transformation may be undefined, or defined from star imports

(F405)


9137-9137: Float may be undefined, or defined from star imports

(F405)


9165-9165: quaternion may be undefined, or defined from star imports

(F405)


9165-9165: Float may be undefined, or defined from star imports

(F405)


9176-9176: transformation may be undefined, or defined from star imports

(F405)


9176-9176: Float may be undefined, or defined from star imports

(F405)


9198-9198: quaternion may be undefined, or defined from star imports

(F405)


9198-9198: Float may be undefined, or defined from star imports

(F405)


9241-9241: quaternion may be undefined, or defined from star imports

(F405)


9241-9241: Float may be undefined, or defined from star imports

(F405)


9694-9694: vector may be undefined, or defined from star imports

(F405)


9694-9694: vector may be undefined, or defined from star imports

(F405)


9704-9704: vector may be undefined, or defined from star imports

(F405)


9704-9704: vector may be undefined, or defined from star imports

(F405)


9715-9715: matrix may be undefined, or defined from star imports

(F405)


9715-9715: matrix may be undefined, or defined from star imports

(F405)


9725-9725: matrix may be undefined, or defined from star imports

(F405)


9725-9725: matrix may be undefined, or defined from star imports

(F405)


9896-9896: quaternion may be undefined, or defined from star imports

(F405)


9896-9896: Float may be undefined, or defined from star imports

(F405)


9896-9896: quaternion may be undefined, or defined from star imports

(F405)


9896-9896: Float may be undefined, or defined from star imports

(F405)


9897-9897: quaternion may be undefined, or defined from star imports

(F405)


9897-9897: Float may be undefined, or defined from star imports

(F405)


9911-9911: transformation may be undefined, or defined from star imports

(F405)


9911-9911: Float may be undefined, or defined from star imports

(F405)


9911-9911: transformation may be undefined, or defined from star imports

(F405)


9911-9911: Float may be undefined, or defined from star imports

(F405)


9912-9912: transformation may be undefined, or defined from star imports

(F405)


9912-9912: Float may be undefined, or defined from star imports

(F405)


9938-9938: quaternion may be undefined, or defined from star imports

(F405)


9938-9938: Float may be undefined, or defined from star imports

(F405)


9938-9938: quaternion may be undefined, or defined from star imports

(F405)


9938-9938: Float may be undefined, or defined from star imports

(F405)


9939-9939: quaternion may be undefined, or defined from star imports

(F405)


9939-9939: Float may be undefined, or defined from star imports

(F405)


9945-9945: transformation may be undefined, or defined from star imports

(F405)


9945-9945: Float may be undefined, or defined from star imports

(F405)


9945-9945: transformation may be undefined, or defined from star imports

(F405)


9945-9945: Float may be undefined, or defined from star imports

(F405)


9946-9946: transformation may be undefined, or defined from star imports

(F405)


9946-9946: Float may be undefined, or defined from star imports

(F405)


10141-10141: quaternion may be undefined, or defined from star imports

(F405)


10141-10141: Float may be undefined, or defined from star imports

(F405)


10141-10141: Scalar may be undefined, or defined from star imports

(F405)


10142-10142: quaternion may be undefined, or defined from star imports

(F405)


10142-10142: Float may be undefined, or defined from star imports

(F405)


10148-10148: Scalar may be undefined, or defined from star imports

(F405)


10148-10148: quaternion may be undefined, or defined from star imports

(F405)


10148-10148: Float may be undefined, or defined from star imports

(F405)


10149-10149: quaternion may be undefined, or defined from star imports

(F405)


10149-10149: Float may be undefined, or defined from star imports

(F405)


10155-10155: quaternion may be undefined, or defined from star imports

(F405)


10155-10155: Float may be undefined, or defined from star imports

(F405)


10155-10155: quaternion may be undefined, or defined from star imports

(F405)


10155-10155: Float may be undefined, or defined from star imports

(F405)


10156-10156: quaternion may be undefined, or defined from star imports

(F405)


10156-10156: Float may be undefined, or defined from star imports

(F405)


10269-10269: transformation may be undefined, or defined from star imports

(F405)


10269-10269: Float may be undefined, or defined from star imports

(F405)


10269-10269: transformation may be undefined, or defined from star imports

(F405)


10269-10269: Float may be undefined, or defined from star imports

(F405)


10270-10270: transformation may be undefined, or defined from star imports

(F405)


10270-10270: Float may be undefined, or defined from star imports

(F405)


10276-10276: Scalar may be undefined, or defined from star imports

(F405)


10276-10276: transformation may be undefined, or defined from star imports

(F405)


10276-10276: Float may be undefined, or defined from star imports

(F405)


10277-10277: transformation may be undefined, or defined from star imports

(F405)


10277-10277: Float may be undefined, or defined from star imports

(F405)


10283-10283: transformation may be undefined, or defined from star imports

(F405)


10283-10283: Float may be undefined, or defined from star imports

(F405)


10283-10283: Scalar may be undefined, or defined from star imports

(F405)


10284-10284: transformation may be undefined, or defined from star imports

(F405)


10284-10284: Float may be undefined, or defined from star imports

(F405)


10344-10344: quaternion may be undefined, or defined from star imports

(F405)


10344-10344: Float may be undefined, or defined from star imports

(F405)


10344-10344: Scalar may be undefined, or defined from star imports

(F405)


10345-10345: quaternion may be undefined, or defined from star imports

(F405)


10345-10345: Float may be undefined, or defined from star imports

(F405)


10351-10351: Scalar may be undefined, or defined from star imports

(F405)


10351-10351: quaternion may be undefined, or defined from star imports

(F405)


10351-10351: Float may be undefined, or defined from star imports

(F405)


10352-10352: quaternion may be undefined, or defined from star imports

(F405)


10352-10352: Float may be undefined, or defined from star imports

(F405)


10376-10376: quaternion may be undefined, or defined from star imports

(F405)


10376-10376: Float may be undefined, or defined from star imports

(F405)


10377-10377: quaternion may be undefined, or defined from star imports

(F405)


10377-10377: Float may be undefined, or defined from star imports

(F405)


10398-10398: quaternion may be undefined, or defined from star imports

(F405)


10398-10398: Float may be undefined, or defined from star imports

(F405)


10399-10399: quaternion may be undefined, or defined from star imports

(F405)


10399-10399: Float may be undefined, or defined from star imports

(F405)


11871-11871: quaternion may be undefined, or defined from star imports

(F405)


11871-11871: Float may be undefined, or defined from star imports

(F405)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: ci / test-warp (ubuntu-24.04, ubuntu-x86_64)
  • GitHub Check: ci / test-warp (windows-2025, windows)
  • GitHub Check: ci / test-warp-gpu
🔇 Additional comments (28)
docs/_templates/builtins.rst (1)

20-20: LGTM! Docstring indentation fix improves RST rendering.

The indent(3, first=True) filter ensures multi-line docstrings render with consistent margins in the generated RST documentation.

docs/language_reference/builtins.rst (1)

319-349: LGTM! Utility section relocation improves documentation organization.

The Utility section is now appropriately positioned, and the inclusion of the newly exposed block_dim() builtin aligns with the PR objectives.

warp/_src/context.py (2)

8667-8681: Centralizing return-type formatting is a good cleanup.

Using get_return_type_str() makes add_builtin_function_stub() more consistent, and emitting -> None (instead of omitting a return annotation) is generally better for type checkers.


8682-8714: Empty-list guard is unnecessary; .pyi stub files don't require Python version syntax compatibility.

The function is only called when len(non_hidden_overloads) > 1 (line 8923), so it never receives empty lists. The | union syntax in .pyi stub files is valid regardless of Python version—type checkers (mypy, pyright, etc.) parse stubs and support modern syntax independently of runtime Python version.

Likely an incorrect or invalid review comment.

warp/_src/types.py (4)

63-126: LGTM - Well-structured scalar base class.

The operator overloads correctly return NotImplemented for array operands, allowing proper delegation to array's reflected operators. The runtime references to is_array() and warp.* functions are safe since they're resolved at method invocation time.


147-168: LGTM - Intentional separation of bool from scalar_base.

The bool class not inheriting from scalar_base is consistent with the PR objective to exclude bool from the Scalar TypeVar. This ensures bool is treated as a distinct type in the type system while still being usable in boolean contexts.


225-251: LGTM - Scalar TypeVar correctly excludes bool.

The type hierarchy is well-organized:

  • scalar_types excludes bool, aligning with the Scalar TypeVar definition
  • scalar_and_bool_types is retained for contexts where bool should be included (e.g., value_types at line 2148)
  • The documentation comment at lines 231-233 is a good practice for keeping TypeVars synchronized with the tuples

2251-2254: LGTM - Runtime Scalar matching now aligns with static TypeVar definition.

This change resolves the previously identified mismatch where static typing permitted bool as a Scalar but runtime matching did not accept it. Now both are consistent: Scalar represents numeric types only (int_types + float_types), excluding bool.

The impact of this change is mitigated by the explicit bool vector/matrix overloads being added in builtins.py (lines 9691-9727) for expect_eq and expect_neq functions, as part of this PR.

warp/_src/builtins.py (4)

402-449: Quaternion float-only predicates / norms look consistent.

Switching isfinite/isnan/isinf/length_sq quaternion overloads to quaternion(dtype=Float) matches the “float-only” direction implied by special_float_dispatch_func and avoids nonsensical integer-quaternion surfaces.

Also applies to: 451-498, 500-547, 718-747


6925-6935: Hiding reversed(range_t) from stubs/docs is consistent with other hidden iterators.


11859-11877: len(quaternion) update to Float matches the rest of the quaternion typing shift.


8827-9054: Bool vector/matrix overloads are complete and consistent.

The added bool overloads for extract, index, indexref, and expect_eq/expect_neq are comprehensive. Bool matrices correctly use only indexref overloads (not index), which matches the pattern for Scalar matrices—neither Scalar nor bool matrix types have index overloads. This is consistent: index is reserved for vectors (returning scalars), while indexref handles reference returns for both vectors and matrices. All indexing paths are properly covered.

warp/__init__.pyi (16)

1781-1789: LGTM!

The kernel-scope zeros overloads correctly provide signatures for both tuple and scalar shape arguments, returning Array[Scalar]. The empty docstrings are consistent with other kernel builtin stubs in this file.


2004-2011: LGTM!

The quaternion type parameter correction from Scalar to Float is consistent with class Quaternion(Generic[Float]) in types.py. This ensures type checker accuracy for these math functions.

Also applies to: 2040-2047, 2076-2083, 2143-2146


2263-2270: LGTM!

The in-place variants of svd3, svd2, qr3, and eig3 correctly return None since they write results to output parameters rather than returning them. This follows Python conventions and improves type checker accuracy.

Also applies to: 2281-2291, 2303-2311, 2322-2329


2366-2369: LGTM!

The in-place quat_to_axis_angle overload correctly returns None since it writes results to the axis and angle output parameters.


2433-2438: LGTM!

The transform setter functions correctly return None as they mutate the transform in-place rather than returning a new value.


2532-2551: LGTM!

The spatial_jacobian and spatial_mass functions correctly return None as they write results to output array parameters (J_out and M).


2896-2917: LGTM!

The tile_store and tile_store_indexed functions correctly return None as they are write operations to global memory arrays.


3095-3102: LGTM!

The tile_assign function correctly returns None as it assigns values to the destination tile in-place.


3369-3400: LGTM!

The tile_sort function correctly returns None as it sorts both tiles in-place, which is clearly documented in the docstring.


3559-3569: LGTM!

The printf, print, and breakpoint functions correctly return None as they are side-effect-only operations (output and debugging).


3571-3587: LGTM!

The tid() return type annotation int | tuple[int, int] | tuple[int, int, int] | tuple[int, int, int, int] accurately reflects that the return type depends on the unpacking context used at the call site. The comprehensive docstring clearly explains this behavior. This is an appropriate approach since the return semantics depend on assignment unpacking rather than function arguments.


4299-4301: LGTM!

The volume store functions (volume_store, volume_store_f, volume_store_v, volume_store_i) consistently return None as they are write operations that store values to voxels.

Also applies to: 4324-4326, 4342-4344, 4357-4359


5658-5676: LGTM!

The expect_near overloads correctly return None as they are assertion/test helper functions that print errors to stdout but don't return a meaningful value.


5698-5711: LGTM!

The arithmetic operations (add, sub, mul, div, pos, neg) and len for Quaternion and Transformation types now consistently use Float as the type parameter. This aligns with the type definitions in types.py where both Quaternion and Transformation are defined as Generic[Float].

Also applies to: 5733-5740, 5868-5921, 5968-5976, 5992-5994, 6012-6014, 6301-6303


6081-6158: LGTM!

The tile_matmul in-place variant (with out parameter) correctly returns None, while the non-in-place variant returns a tile. The tile_fft and tile_ifft functions correctly return None as they operate on the input/output tile in-place. The Float type parameter is appropriate for these floating-point operations.


6179-6196: LGTM!

The in-place variants (tile_cholesky_inplace, tile_cholesky_solve_inplace, tile_lower_solve_inplace, tile_upper_solve_inplace) correctly return None as they overwrite their input parameters rather than returning new tiles. The docstrings clearly document this behavior.

Also applies to: 6213-6227, 6245-6261, 6279-6295

Comment on lines +8657 to +8665
def get_return_type_str(f):
"""Get the return type string for a builtin function."""
return_type = f.value_type
if f.value_func:
try:
return_type = f.value_func(None, None)
except Exception:
pass # Keep f.value_type as fallback
return type_str(return_type)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, check if the file exists and read the relevant section
wc -l warp/_src/context.py

Repository: NVIDIA/warp

Length of output: 80


🏁 Script executed:

# Read the function in question
sed -n '8650,8720p' warp/_src/context.py

Repository: NVIDIA/warp

Length of output: 2694


🏁 Script executed:

# Search for value_func usage patterns to understand what exceptions might occur
rg -n 'value_func' warp/_src/context.py | head -30

Repository: NVIDIA/warp

Length of output: 1476


🏁 Script executed:

# Check for verbose warning patterns in the codebase
rg -n 'warp.config.verbose|config\.verbose' warp/ | head -20

Repository: NVIDIA/warp

Length of output: 1601


🏁 Script executed:

# Check for Python version requirements
rg -n 'pythonVersion|python_version|requires-python|tool\.pyright' . --type toml --type yaml --type json --type txt | head -20

Repository: NVIDIA/warp

Length of output: 537


🏁 Script executed:

# Search for existing exception handling patterns in export_stubs context
rg -B 3 -A 3 'except.*Exception' warp/_src/context.py | head -40

Repository: NVIDIA/warp

Length of output: 1585


🏁 Script executed:

# Look at value_func implementations to understand what exceptions they might raise
sed -n '77,90p' warp/_src/context.py

Repository: NVIDIA/warp

Length of output: 542


🏁 Script executed:

# Check the create_value_func and other value_func definitions
rg -B 5 -A 15 'def value_func\(' warp/_src/context.py | head -60

Repository: NVIDIA/warp

Length of output: 1335


🏁 Script executed:

# Check where value_func is called with (None, None) to see if this is a documented pattern
rg -B 3 -A 3 'value_func\(None, None\)' warp/_src/context.py

Repository: NVIDIA/warp

Length of output: 564


🏁 Script executed:

# Check the type_str function to see if it handles exceptions or if it's resilient
rg -B 2 -A 10 'def type_str' warp/_src/context.py

Repository: NVIDIA/warp

Length of output: 362


🏁 Script executed:

# Check if there are any docstrings or comments about expected behavior for value_func with None args
rg -B 5 -A 5 'value_func.*None|None.*value_func' warp/_src/context.py | head -40

Repository: NVIDIA/warp

Length of output: 1447


🏁 Script executed:

# Check the context around line 8287 to see the similar exception handling pattern
sed -n '8280,8295p' warp/_src/context.py

Repository: NVIDIA/warp

Length of output: 613


🏁 Script executed:

# Verify how value_func is called in actual code execution vs stub generation
rg -B 5 -A 5 'value_func\(func_args|value_func\(concrete_arg' warp/_src/context.py

Repository: NVIDIA/warp

Length of output: 1144


🏁 Script executed:

# Check if there are any known error types that value_func can raise
rg -B 10 -A 10 'def value_func' warp/_src/context.py | grep -A 15 'def value_func'

Repository: NVIDIA/warp

Length of output: 818


🏁 Script executed:

# Check pyproject.toml to see Pyright configuration for stub file generation
sed -n '212,230p' pyproject.toml

Repository: NVIDIA/warp

Length of output: 187


🏁 Script executed:

# Verify if generated stub files use PEP 604 syntax and what Python version they target
rg -n '\|' warp/ --type pyi | head -10

Repository: NVIDIA/warp

Length of output: 82


🏁 Script executed:

# Check if there are any other patterns of value_func being called with None in the codebase
rg -n 'value_func\(None' warp/_src/context.py

Repository: NVIDIA/warp

Length of output: 185


🏁 Script executed:

# Look at the broader context of where stubs are generated to understand the scope
rg -n 'export_stubs|def export_stubs' warp/_src/context.py

Repository: NVIDIA/warp

Length of output: 103


🏁 Script executed:

# Check if warp._src.utils.warn is the appropriate function to use for warnings
rg -B 5 -A 10 'def warn' warp/_src/utils.py | head -30

Repository: NVIDIA/warp

Length of output: 1117


🏁 Script executed:

# Verify the actual exceptions that might be raised from value_func implementations
rg -B 10 -A 20 'def value_func' warp/ | grep -E '(raise|except|TypeError|AttributeError)' -A 2 -B 2

Repository: NVIDIA/warp

Length of output: 383


🏁 Script executed:

# Check line 8250 context where value_func is called with actual args to understand error patterns
sed -n '8240,8260p' warp/_src/context.py

Repository: NVIDIA/warp

Length of output: 731


🏁 Script executed:

# Check all value_func implementations to understand what exceptions they might actually raise
rg -B 3 -A 15 'def value_func' warp/_src/context.py | head -80

Repository: NVIDIA/warp

Length of output: 1252


🏁 Script executed:

# Look at the actual exception being swallowed at line 8287 to see if there are patterns
sed -n '8275,8305p' warp/_src/context.py

Repository: NVIDIA/warp

Length of output: 903


🏁 Script executed:

# Check if verbose is used with stacklevel for warnings in similar contexts
rg -B 3 -A 3 'if.*verbose.*warn|warn.*stacklevel' warp/_src/context.py | head -30

Repository: NVIDIA/warp

Length of output: 37


🏁 Script executed:

# Check if there are similar broad Exception catches elsewhere for context
rg -B 2 -A 2 'except Exception:' warp/_src/context.py | head -50

Repository: NVIDIA/warp

Length of output: 1208


🏁 Script executed:

# Verify what the actual exception types might be from value_func with None args
python3 << 'EOF'
# Simulate what happens when calling value_func(None, None)
# For create_value_func pattern
def test_create_value_func():
    def value_func(arg_types, arg_values):
        hint_origin = getattr(type, "__origin__", None)
        if hint_origin is not None and issubclass(hint_origin, tuple):
            return type.__args__
        return type
    
    # Call with None, None
    try:
        result = value_func(None, None)
        print("create_value_func with None args: Success")
    except Exception as e:
        print(f"create_value_func with None args: {type(e).__name__}: {e}")

# For simple value_func pattern
def test_simple_value_func():
    value_type = int
    def value_func(arg_types, arg_values):
        return value_type
    
    try:
        result = value_func(None, None)
        print(f"simple value_func with None args: Success, returned {result}")
    except Exception as e:
        print(f"simple value_func with None args: {type(e).__name__}: {e}")

test_create_value_func()
test_simple_value_func()
EOF

Repository: NVIDIA/warp

Length of output: 141


🏁 Script executed:

# Check if the issue at line 8287 is also addressed or if it's a separate known issue
git log --oneline -20 -- warp/_src/context.py | head -20

Repository: NVIDIA/warp

Length of output: 119


Catch TypeError explicitly; log unexpected exceptions under verbose mode.

The broad Exception catch can obscure bugs in custom value_func implementations. Since value_func is a user-provided callback, implementations may raise exceptions beyond the typical TypeError from None-argument incompatibility. While the current fallback to f.value_type is safe, narrowing the exception handler and logging unexpected errors improves debuggability.

Suggested change
 def get_return_type_str(f):
     """Get the return type string for a builtin function."""
     return_type = f.value_type
     if f.value_func:
         try:
             return_type = f.value_func(None, None)
-        except Exception:
-            pass  # Keep f.value_type as fallback
+        except TypeError:
+            # Common case: value_func requires non-None args
+            pass
+        except Exception as e:
+            if warp.config.verbose:
+                warp._src.utils.warn(
+                    f"Stub generation: failed to infer return type for '{getattr(f, 'key', f)}': {e}",
+                    stacklevel=3,
+                )
     return type_str(return_type)
🧰 Tools
🪛 Ruff (0.14.11)

8663-8664: try-except-pass detected, consider logging the exception

(S110)


8663-8663: Do not catch blind exception: Exception

(BLE001)

🤖 Prompt for AI Agents
In @warp/_src/context.py around lines 8657 - 8665, Narrow the broad except in
get_return_type_str: explicitly catch TypeError when calling f.value_func(None,
None) and silently fall back to f.value_type, and add a separate except
Exception as e branch that logs the unexpected exception when verbose mode is
enabled (using the project's existing logging/verbose facility) before falling
back to f.value_type; keep the final return as type_str(return_type) and only
suppress the well-known TypeError case.

@shi-eric shi-eric merged commit e5b2259 into NVIDIA:main Jan 13, 2026
18 checks passed
@shi-eric shi-eric deleted the ershi/fix-more-stub-issues branch February 13, 2026 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant