@@ -52,16 +52,32 @@ def _var_as_tuple(var: Variable) -> T_VarTuple:
52
52
return var .dims , var .data , var .attrs .copy (), var .encoding .copy ()
53
53
54
54
55
- def _infer_dtype (array , name : T_Name = None ) -> np .dtype :
56
- """Given an object array with no missing values, infer its dtype from its
57
- first element
58
- """
55
+ def _infer_dtype (array , name = None ):
56
+ """Given an object array with no missing values, infer its dtype from all elements."""
59
57
if array .dtype .kind != "O" :
60
58
raise TypeError ("infer_type must be called on a dtype=object array" )
61
59
62
60
if array .size == 0 :
63
61
return np .dtype (float )
64
62
63
+ native_dtypes = set (np .vectorize (type , otypes = [object ])(array .ravel ()))
64
+ if len (native_dtypes ) > 1 and native_dtypes != {bytes , str }:
65
+ raise ValueError (
66
+ "unable to infer dtype on variable {!r}; object array "
67
+ "contains mixed native types: {}" .format (
68
+ name , ", " .join (x .__name__ for x in native_dtypes )
69
+ )
70
+ )
71
+
72
+ native_dtypes = set (np .vectorize (type , otypes = [object ])(array .ravel ()))
73
+ if len (native_dtypes ) > 1 and native_dtypes != {bytes , str }:
74
+ raise ValueError (
75
+ "unable to infer dtype on variable {!r}; object array "
76
+ "contains mixed native types: {}" .format (
77
+ name , ", " .join (x .__name__ for x in native_dtypes )
78
+ )
79
+ )
80
+
65
81
element = array [(0 ,) * array .ndim ]
66
82
# We use the base types to avoid subclasses of bytes and str (which might
67
83
# not play nice with e.g. hdf5 datatypes), such as those from numpy
0 commit comments