Skip to content

Fix get_arg_type to preserve Any on Python <3.11#1569

Open
shi-eric wants to merge 1 commit into
NVIDIA:mainfrom
shi-eric:shi-eric/fix-generic-any-arg-type
Open

Fix get_arg_type to preserve Any on Python <3.11#1569
shi-eric wants to merge 1 commit into
NVIDIA:mainfrom
shi-eric:shi-eric/fix-generic-any-arg-type

Conversation

@shi-eric

@shi-eric shi-eric commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Description

While developing Callable function parameters (GH-1424), the Python 3.10 CI job (test-warp-gpu-linux-mgpu-python310) failed across ~200 tests — most of the warp.fem suite plus a few others — with:

RuntimeError: Failed to determine type code for argument 'coords' of function
element_inner_weight_linear_...: Unrecognized type '<class 'typing._SpecialForm'>'

The root cause is in get_arg_type and is independent of that feature, so it is fixed here on its own.

get_arg_type returns the type used for a function argument during signature and overload computation. An unspecialized generic parameter has type typing.Any, which should be returned unchanged so downstream logic treats the parameter as generic.

On Python 3.11+ Any is a class and satisfied the isinstance(arg, type) check, so it was returned as-is. Before 3.11 Any is a typing._SpecialForm instance rather than a type, so get_arg_type fell through to type(arg) and returned typing._SpecialForm. get_type_code has no mapping for that and raises Unrecognized type, so any path that feeds a generic parameter type into signature computation fails on Python 3.10 while succeeding on newer versions.

Why fix this now, and separately

The bug is latent on main: no current code path feeds a generic (Any) parameter's type into get_signature/get_type_code, so there is no user-facing impact today (hence no CHANGELOG entry). The Callable-parameters work adds the first such path — it scans every call's arguments during module hashing to discover Callable targets, which routes a generic parameter's type into signature computation. Since warp.fem defines generic device functions with Any-typed parameters (e.g. coords: Any) that forward those arguments to other functions, the entire FEM suite breaks on the Python 3.10 lane.

Because the fix is independent of the feature, landing it as a standalone PR keeps it reviewable in isolation and lets it merge first; the feature branch then only needs a rebase to pick it up.

Changes

  • get_arg_type (warp/_src/codegen.py): return Any early so the result is consistent across Python versions, instead of falling through to type(arg) and yielding typing._SpecialForm on Python <3.11.

Checklist

  • I am familiar with the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.
  • CHANGELOG.md is updated for any user-facing changes under the Unreleased section.

No CHANGELOG entry: the bug is not reachable through any code path on main, so there is no user-facing behavior change on this branch.

Validation summary

  • Added TestCodeGen.test_get_arg_type_preserves_any, which asserts get_arg_type returns Any both when passed Any directly and when passed a Var whose type is Any.
  • Verified the new test fails on Python 3.10 without this change (AssertionError: <class 'typing._SpecialForm'> is not typing.Any) and passes with it.
  • Verified the new test passes on Python 3.12.
  • Ran the full warp/tests/test_codegen.py suite on CPU under Python 3.10 (81 tests) — all passing.
  • pre-commit (ruff, ruff-format, typos, generated-file checks) clean on the changed files.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

get_arg_type() in codegen.py receives an early-return guard: if the argument type is typing.Any, it is returned immediately without entering the existing type-dispatch path. A new unit test test_get_arg_type_preserves_any covers both the bare Any case and a Var-wrapped case.

Changes

Fix: Preserve typing.Any in get_arg_type

Layer / File(s) Summary
Early-return guard for Any and regression test
warp/_src/codegen.py, warp/tests/test_codegen.py
get_arg_type() now returns typing.Any unchanged before the existing type-dispatch logic, preventing misclassification as a typing._SpecialForm. The new test test_get_arg_type_preserves_any asserts identity for direct Any and Var("coords", Any), with an explicit note covering Python 3.11+ behavior.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main fix: preserving Any in get_arg_type across Python versions, which is the core change in the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@greptile-apps

greptile-apps Bot commented Jun 18, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes a Python-version portability bug in get_arg_type where passing typing.Any as an argument type would return typing._SpecialForm instead of Any on Python <3.11, causing downstream get_type_code to raise Unrecognized type. The fix adds an early identity check (arg is Any) before the isinstance(arg, type) path.

  • warp/_src/codegen.py: adds a four-line early-return guard in get_arg_type so Any is returned unchanged regardless of Python version, with a clear comment explaining the cross-version behavioral difference.
  • warp/tests/test_codegen.py: adds test_get_arg_type_preserves_any covering both the bare Any and the Var("coords", Any) code paths.

Confidence Score: 5/5

Safe to merge — the change is a single identity check inserted before any existing logic, with no side effects on other code paths.

The fix is surgical: one if arg is Any: return Any guard that only fires for the exact typing.Any singleton. strip_reference leaves Any untouched, so the identity check is reliable. All other branches in get_arg_type are unaffected. The accompanying test directly reproduces the regression scenario on Python <3.11 by asserting identity with assertIs, and the PR author confirmed it fails without the fix and passes with it. There is nothing here that could regress existing behavior.

No files require special attention.

Important Files Changed

Filename Overview
warp/_src/codegen.py Adds a minimal, correct early-return guard for Any in get_arg_type; strip_reference safely passes Any through unchanged, so the identity check fires reliably.
warp/tests/test_codegen.py New test covers both call shapes (bare Any and Var-wrapped Any) and is structured to catch a regression on Python <3.11.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["get_arg_type(arg)"] --> B["strip_reference(arg)"]
    B --> C{arg is Any?}
    C -- Yes --> D["return Any ✓\n(consistent on all Python versions)"]
    C -- No --> E{isinstance arg, str?}
    E -- Yes --> F["return str"]
    E -- No --> G{is_struct?}
    G -- Yes --> H["return arg._cls"]
    G -- No --> I{isinstance arg, type\nor other known types?}
    I -- Yes --> J["return arg"]
    I -- No --> K["return type(arg)"]

    style D fill:#22c55e,color:#fff
    style C fill:#f59e0b,color:#fff
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["get_arg_type(arg)"] --> B["strip_reference(arg)"]
    B --> C{arg is Any?}
    C -- Yes --> D["return Any ✓\n(consistent on all Python versions)"]
    C -- No --> E{isinstance arg, str?}
    E -- Yes --> F["return str"]
    E -- No --> G{is_struct?}
    G -- Yes --> H["return arg._cls"]
    G -- No --> I{isinstance arg, type\nor other known types?}
    I -- Yes --> J["return arg"]
    I -- No --> K["return type(arg)"]

    style D fill:#22c55e,color:#fff
    style C fill:#f59e0b,color:#fff
Loading

Reviews (2): Last reviewed commit: "Fix get_arg_type to preserve Any on Pyth..." | Re-trigger Greptile

@shi-eric shi-eric self-assigned this Jun 18, 2026
`get_arg_type` returns the type used for a function argument during
signature and overload computation. An unspecialized generic parameter
has type `typing.Any`, which should be returned unchanged so downstream
logic treats the parameter as generic.

On Python 3.11+ `Any` is a class and satisfied the
`isinstance(arg, type)` check, so it was returned as-is. Before 3.11
`Any` is a `typing._SpecialForm` instance rather than a `type`, so the
function fell through to `type(arg)` and returned `typing._SpecialForm`.
`get_type_code` has no mapping for that and raises "Unrecognized type",
so any path that feeds a generic parameter type into signature
computation fails on Python 3.10 while succeeding on newer versions.

Return `Any` early so the behavior is consistent across versions.

Signed-off-by: Eric Shi <ershi@nvidia.com>
@shi-eric shi-eric force-pushed the shi-eric/fix-generic-any-arg-type branch from 1cd28a8 to c90369c Compare June 18, 2026 09:14
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