fix: typetracer correctness issues affecting dask-awkward#4100
Open
henryiii wants to merge 3 commits into
Open
fix: typetracer correctness issues affecting dask-awkward#4100henryiii wants to merge 3 commits into
henryiii wants to merge 3 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files
|
Fixes several typetracer correctness issues, mostly affecting dask-awkward, found via an automated multi-agent review: - typetracer min/max/sum(axis=None) recursed with axis=None instead of axis=0, causing a RecursionError; sum now reports NumPy's promoted dtype (e.g. bool/int32 -> platform int). - typetracer.stack built the result shape incorrectly (treated the prototype tuple as data, and normalized negative axis over the input ndim rather than ndim+1); now builds the shape symbolically and uses numpy.result_type for the dtype. - searchsorted returned the input dtype instead of intp insertion indices. - asarray now honors the requested dtype for non-TypeTracerArray inputs and only rejects copy=False when an incompatible dtype is requested. - reshape now permits zero-size dimensions, matching NumPy and the concrete backends. - TypeTracerArray.__repr__ no longer reads the touching .shape property (printing mutated the report); same dead None-shape branch removed in PlaceholderArray and VirtualNDArray. - cupy reducers (all/any/min/sum/max) now forward keepdims, preserving the cupy#3819 .item() workaround only for axis=None without keepdims. - NumpyArray._pad_none and Content._combinations_axis0 now guard against unknown_length, fixing ak.pad_none and ak.combinations(axis=0) on typetracer layouts. - Removed verified-dead branches in __getitem__, derive_slice_for_length, and broadcast_arrays. Assisted-by: ClaudeCode:claude-opus-4.8
Assisted-by: ClaudeCode:claude-opus-4.8
Keep one focused test per fix and drop comments that merely restate the adjacent code. Assisted-by: ClaudeCode:claude-opus-4-8
c039be1 to
ca3df4a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 AI text below 🤖
This PR fixes several typetracer correctness issues, most of which affect dask-awkward (which runs awkward operations on shape-only typetracer arrays). They were surfaced by an automated multi-agent code review (Claude Code) and each was verified before fixing.
Fixes
TypeTracer.min/max/sum(axis=None)infinite recursion (_nplikes/typetracer.py):minrecursed withaxis=axis(stillNone) instead ofaxis=0, causing aRecursionError;max/sumdelegated to it. Additionally,sumnow reports NumPy's promoted output dtype (e.g.bool/int32→ platform int) rather than preserving the input dtype, matching the concrete backends.TypeTracer.stackwrong shape/dtype (_nplikes/typetracer.py): it treated the prototype tuple(0,) * ndimas data forempty_like, and normalized negative axes over the inputndiminstead of thendim + 1output. Now the result shape is built symbolically (insertinglen(arrays)at the normalized axis) and the dtype usesnumpy.result_type. Reachable from_broadcasting.py.searchsorteddtype (_nplikes/typetracer.py): returned the input array's dtype; it returns insertion indices, so it now reportsintp, matchingnp.searchsortedand the convention used bynonzero.asarraydtype handling (_nplikes/typetracer.py): for non-TypeTracerArrayinputs it silently dropped the requested dtype and mis-fired thecopy=Falsedtype check whendtype is None. It now honors the requested dtype and only raises forcopy=Falsewhen an incompatible dtype is explicitly requested.reshapewith zero-size dimensions (_nplikes/typetracer.py): rejected any0, but zero-size reshapes are valid in NumPy and the concrete path. Now permitted (with the-1placeholder handled consistently for zero size).__repr__mutating the report (_nplikes/typetracer.py,_nplikes/placeholder.py,_nplikes/virtual.py):__repr__read the touching.shapeproperty, so merely printing an array mutated theTypeTracerReport. Now usesself._shape, and the impossibleif shape is Nonedead branch is removed in all three.keepdims(_nplikes/cupy.py): the five overridden reducers (all/any/min/sum/max) acceptedkeepdimsbut never forwarded it. They now forward it, and the cupy#3819.item()workaround is applied only foraxis=Nonewithoutkeepdimsso thataxis=None, keepdims=Truereturns the1×…×1array NumPy produces.ak.pad_noneon 1D typetracer arrays (contents/numpyarray.py):_pad_nonewithclip=Falsedidtarget < self.lengthwithout anunknown_lengthguard, raisingTypeErrorunder dask-awkward. Now uses the same guard pattern ascontent.py.ak.combinations(axis=0)on typetracer (contents/content.py):_combinations_axis0checkedsize is None, but unknown lengths areunknown_length, neverNone, so it raisedTypeError. Now checks againstunknown_length._nplikes/typetracer.py): removed a verified-unreachable integer bounds-check in__getitem__(the index is always an unknown scalar afterasarray), two deadis_unknown_scalar(length_scalar)branches inderive_slice_for_length(only reached when the length is known), and a deadhasattr(x, "shape")loop inbroadcast_arrays(every element is asserted to be aTypeTracerArray).Testing
A regression test file exercises all of the above on typetracer layouts (using
to_typetracer(forget_length=True)for the high-levelak.pad_none/ak.combinationscases). The existing typetracer suites and the relevant operation suites pass.The CuPy change is untested locally (no GPU available); it was made by inspection, mirroring the NumPy base class.
AI assistance
This PR was prepared with Claude Code via an automated multi-agent review. All findings were verified before fixing.
🤖 Generated with Claude Code