Skip to content

Commit ae4f1b8

Browse files
committed
fix(asanyarray): handle object[] via type-promotion path
np.asanyarray(new object[]{1, 2.5, 3}) threw NotSupportedException because `case Array array` matched object[] first and `new NDArray(object[])` rejects object as an element type. object[] has no fixed dtype, so routing through the non-generic IEnumerable path (which applies NumPy-like type promotion) is the correct behavior. Added an explicit `case object[] objArr` branch that delegates to ConvertNonGenericEnumerable, which already handles: - Homogeneous object[]: detected via FindCommonNumericType, single dtype - Mixed object[]: promoted to common type (e.g. int + double -> double) - Empty object[]: returns empty double[] (matches NumPy float64 default) - Bool+int mix: promotes bool to int via Convert.ToInt32 (True=1, False=0) Regression tests added in np.asanyarray.Tests.cs covering all four cases. All 66 np.asanyarray tests pass on net8.0 and net10.0.
1 parent 4e8af8b commit ae4f1b8

2 files changed

Lines changed: 53 additions & 0 deletions

File tree

src/NumSharp.Core/Creation/np.asanyarray.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ public static NDArray asanyarray(in object a, Type dtype = null) //todo support
2626
if (dtype == null || Equals(nd.dtype, dtype))
2727
return nd;
2828
return nd.astype(dtype, true);
29+
case object[] objArr:
30+
// object[] has no fixed dtype — route through type-promotion path.
31+
// new NDArray(object[]) throws NotSupportedException since object isn't a
32+
// supported element type.
33+
ret = ConvertNonGenericEnumerable(objArr);
34+
if (ret is null)
35+
throw new NotSupportedException($"Unable to resolve asanyarray for object array of length {objArr.Length}.");
36+
break;
2937
case Array array:
3038
ret = new NDArray(array);
3139
break;

test/NumSharp.UnitTest/Creation/np.asanyarray.Tests.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,5 +747,50 @@ public void EmptyArrayList_ReturnsEmptyDoubleArray()
747747
}
748748

749749
#endregion
750+
751+
#region object[] regression
752+
753+
[TestMethod]
754+
public void ObjectArray_Homogeneous_Int()
755+
{
756+
var arr = new object[] { 1, 2, 3 };
757+
var result = np.asanyarray(arr);
758+
759+
result.dtype.Should().Be(typeof(int));
760+
result.Should().BeShaped(3).And.BeOfValues(1, 2, 3);
761+
}
762+
763+
[TestMethod]
764+
public void ObjectArray_MixedIntFloat_PromotesToDouble()
765+
{
766+
var arr = new object[] { 1, 2.5, 3 };
767+
var result = np.asanyarray(arr);
768+
769+
result.dtype.Should().Be(typeof(double));
770+
result.Should().BeShaped(3).And.BeOfValues(1.0, 2.5, 3.0);
771+
}
772+
773+
[TestMethod]
774+
public void ObjectArray_MixedBoolInt_PromotesToInt()
775+
{
776+
var arr = new object[] { true, 2, false };
777+
var result = np.asanyarray(arr);
778+
779+
result.dtype.Should().Be(typeof(int));
780+
result.Should().BeShaped(3).And.BeOfValues(1, 2, 0);
781+
}
782+
783+
[TestMethod]
784+
public void ObjectArray_Empty_ReturnsFloat64()
785+
{
786+
var arr = new object[0];
787+
var result = np.asanyarray(arr);
788+
789+
result.size.Should().Be(0);
790+
result.ndim.Should().Be(1);
791+
result.dtype.Should().Be(typeof(double));
792+
}
793+
794+
#endregion
750795
}
751796
}

0 commit comments

Comments
 (0)