Fix get_arg_type to preserve Any on Python <3.11#1569
Conversation
📝 WalkthroughWalkthrough
ChangesFix: Preserve
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Greptile SummaryThis PR fixes a Python-version portability bug in
Confidence Score: 5/5Safe 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 No files require special attention. Important Files Changed
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
%%{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
Reviews (2): Last reviewed commit: "Fix get_arg_type to preserve Any on Pyth..." | Re-trigger Greptile |
`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>
1cd28a8 to
c90369c
Compare
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 thewarp.femsuite plus a few others — with:The root cause is in
get_arg_typeand is independent of that feature, so it is fixed here on its own.get_arg_typereturns the type used for a function argument during signature and overload computation. An unspecialized generic parameter has typetyping.Any, which should be returned unchanged so downstream logic treats the parameter as generic.On Python 3.11+
Anyis a class and satisfied theisinstance(arg, type)check, so it was returned as-is. Before 3.11Anyis atyping._SpecialForminstance rather than atype, soget_arg_typefell through totype(arg)and returnedtyping._SpecialForm.get_type_codehas no mapping for that and raisesUnrecognized 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 intoget_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. Sincewarp.femdefines generic device functions withAny-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): returnAnyearly so the result is consistent across Python versions, instead of falling through totype(arg)and yieldingtyping._SpecialFormon Python <3.11.Checklist
Unreleasedsection.Validation summary
TestCodeGen.test_get_arg_type_preserves_any, which assertsget_arg_typereturnsAnyboth when passedAnydirectly and when passed aVarwhose type isAny.AssertionError: <class 'typing._SpecialForm'> is not typing.Any) and passes with it.warp/tests/test_codegen.pysuite on CPU under Python 3.10 (81 tests) — all passing.pre-commit(ruff, ruff-format, typos, generated-file checks) clean on the changed files.