Repository: scikit-hep/awkward

Issue:
`NotImplementedError` from `TypeTracerArray.nan_to_num`
### Description of new feature

I'm trying to use `dask-awkward` and `vector` to do vector addition. It works fine for Cartesian coordinates but not spherical:

```python
>>> import awkward as ak, dask_awkward as dak, vector
>>> vector.register_awkward()
>>> a = ak.Array([1.0])
>>> da = dak.from_awkward(a, 1)
>>> dv1 = dak.with_name(dak.zip({'x': da, 'y': da, 'z': da}), 'Vector3D')
>>> (dv1 + dv1).compute()
<VectorArray3D [{x: 2, y: 2, z: 2}] type='1 * Vector3D[x: float64, y: float...'>
>>> dv2 = dak.with_name(dak.zip({'rho': da, 'phi': da, 'theta': da}), 'Vector3D')
>>> (dv2 + dv2).compute()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/miniconda3/envs/func_adl_uproot_rc/lib/python3.10/site-packages/numpy/lib/mixins.py", line 21, in func
    return ufunc(self, other)
  File "/home/user/iris-hep/src/dask-awkward/src/dask_awkward/lib/core.py", line 1027, in __array_ufunc__
    new_meta = ufunc(*inputs_meta)
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/highlevel.py", line 1373, in __array_ufunc__
    return ak._connect.numpy.array_ufunc(ufunc, method, inputs, kwargs)
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/_connect/numpy.py", line 291, in array_ufunc
    out = ak._broadcasting.broadcast_and_apply(
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/_broadcasting.py", line 1063, in broadcast_and_apply
    out = apply_step(
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/_broadcasting.py", line 1042, in apply_step
    return continuation()
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/_broadcasting.py", line 759, in continuation
    outcontent = apply_step(
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/_broadcasting.py", line 1028, in apply_step
    result = action(
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/_connect/numpy.py", line 193, in action
    return _array_ufunc_adjust(custom, inputs, kwargs, behavior)
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/_connect/numpy.py", line 130, in _array_ufunc_adjust
    out = custom(*args, **kwargs)
  File "/home/user/miniconda3/envs/func_adl_uproot_rc/lib/python3.10/site-packages/vector/backends/awkward.py", line 1514, in <lambda>
    behavior[numpy.add, left, right] = lambda v1, v2: v1.add(v2)
  File "/home/user/miniconda3/envs/func_adl_uproot_rc/lib/python3.10/site-packages/vector/_methods.py", line 2068, in add
    return module.add.dispatch(self, other)
  File "/home/user/miniconda3/envs/func_adl_uproot_rc/lib/python3.10/site-packages/vector/_compute/spatial/add.py", line 593, in dispatch
    function(
  File "/home/user/miniconda3/envs/func_adl_uproot_rc/lib/python3.10/site-packages/vector/_compute/spatial/add.py", line 310, in rhophi_theta_rhophi_theta
    z1 = z.rhophi_theta(lib, rho1, phi1, theta1)
  File "/home/user/miniconda3/envs/func_adl_uproot_rc/lib/python3.10/site-packages/vector/_compute/spatial/z.py", line 52, in rhophi_theta
    return lib.nan_to_num(rho / lib.tan(theta), nan=0.0, posinf=inf, neginf=-inf)
  File "<__array_function__ internals>", line 200, in nan_to_num
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/highlevel.py", line 1392, in __array_function__
    return ak._connect.numpy.array_function(
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/_connect/numpy.py", line 75, in array_function
    return function(*args, **kwargs)
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/_connect/numpy.py", line 96, in ensure_valid_args
    return function(*args, **kwargs)
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/operations/ak_nan_to_num.py", line 136, in _nep_18_impl
    return nan_to_num(x, copy=copy, nan=nan, posinf=posinf, neginf=neginf)
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/operations/ak_nan_to_num.py", line 51, in nan_to_num
    return _impl(array, copy, nan, posinf, neginf, highlevel, behavior)
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/operations/ak_nan_to_num.py", line 95, in _impl
    out = ak._do.recursively_apply(layout, action, behavior)
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/_do.py", line 34, in recursively_apply
    return layout._recursively_apply(
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/contents/numpyarray.py", line 1301, in _recursively_apply
    result = action(
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/operations/ak_nan_to_num.py", line 85, in action
    nplike.nan_to_num(
  File "/home/user/iris-hep/src/awkward-1.0/src/awkward/_nplikes/typetracer.py", line 1190, in nan_to_num
    raise ak._errors.wrap_error(NotImplementedError)
NotImplementedError:

See if this has been reported at https://github.com/scikit-hep/awkward-1.0/issues
```


Discussion:

Resolving patch:
diff --git a/src/awkward/_nplikes/typetracer.py b/src/awkward/_nplikes/typetracer.py
--- a/src/awkward/_nplikes/typetracer.py
+++ b/src/awkward/_nplikes/typetracer.py
@@ -1187,7 +1187,7 @@ def nan_to_num(
         neginf: int | float | None = None,
     ) -> TypeTracerArray:
         try_touch_data(x)
-        raise ak._errors.wrap_error(NotImplementedError)
+        return TypeTracerArray._new(x.dtype, shape=x.shape)
 
     def isclose(
         self,


Test patch:
diff --git a/tests/test_2266_fix_nan_to_num.py b/tests/test_2266_fix_nan_to_num.py
new file mode 100644
--- /dev/null
+++ b/tests/test_2266_fix_nan_to_num.py
@@ -0,0 +1,26 @@
+# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE
+
+import pytest
+
+import awkward as ak
+
+dak = pytest.importorskip("dask_awkward")
+vector = pytest.importorskip("vector")
+vector.register_awkward()
+
+
+def test():
+    a = ak.Array([1.0])
+    da = dak.from_awkward(a, 1)
+    dv1 = dak.with_name(dak.zip({"x": da, "y": da, "z": da}), "Vector3D")
+
+    result1 = (dv1 + dv1).compute()
+    assert result1.tolist() == [{"x": 2, "y": 2, "z": 2}]
+    assert str(result1.type).startswith("1 * Vector3D[")
+    assert type(result1).__name__ == "VectorArray3D"
+
+    dv2 = dak.with_name(dak.zip({"rho": da, "phi": da, "theta": da}), "Vector3D")
+    result2 = (dv2 + dv2).compute()
+    assert result2.tolist() == [{"rho": 2, "phi": 1, "theta": 1}]
+    assert str(result2.type).startswith("1 * Vector3D[")
+    assert type(result2).__name__ == "VectorArray3D"