@@ -53,7 +53,7 @@ def to_scalar_or_list(v):
53
53
return v
54
54
55
55
56
- def copy_to_readonly_numpy_array (v , kind = None , force_numeric = False ):
56
+ def copy_to_readonly_numpy_array_or_list (v , kind = None , force_numeric = False ):
57
57
"""
58
58
Convert an array-like value into a read-only numpy array
59
59
@@ -89,7 +89,7 @@ def copy_to_readonly_numpy_array(v, kind=None, force_numeric=False):
89
89
90
90
# u: unsigned int, i: signed int, f: float
91
91
numeric_kinds = {"u" , "i" , "f" }
92
- kind_default_dtypes = {"u" : "uint32" , "i" : "int32" , "f" : "float64" , "O" : "object" }
92
+ kind_default_dtypes = {"u" : "uint32" , "i" : "int32" , "f" : "float64" , "O" : "object" , "U" : "U" }
93
93
94
94
# Handle pandas Series and Index objects
95
95
if pd and isinstance (v , (pd .Series , pd .Index )):
@@ -113,18 +113,12 @@ def copy_to_readonly_numpy_array(v, kind=None, force_numeric=False):
113
113
if not isinstance (v , np .ndarray ):
114
114
# v has its own logic on how to convert itself into a numpy array
115
115
if is_numpy_convertable (v ):
116
- return copy_to_readonly_numpy_array (
116
+ return copy_to_readonly_numpy_array_or_list (
117
117
np .array (v ), kind = kind , force_numeric = force_numeric
118
118
)
119
119
else :
120
120
# v is not homogenous array
121
- v_list = [to_scalar_or_list (e ) for e in v ]
122
-
123
- # Lookup dtype for requested kind, if any
124
- dtype = kind_default_dtypes .get (first_kind , None )
125
-
126
- # construct new array from list
127
- new_v = np .array (v_list , order = "C" , dtype = dtype )
121
+ return [to_scalar_or_list (e ) for e in v ]
128
122
elif v .dtype .kind in numeric_kinds :
129
123
# v is a homogenous numeric array
130
124
if kind and v .dtype .kind not in kind :
@@ -135,6 +129,12 @@ def copy_to_readonly_numpy_array(v, kind=None, force_numeric=False):
135
129
else :
136
130
# Either no kind was requested or requested kind is satisfied
137
131
new_v = np .ascontiguousarray (v .copy ())
132
+ elif v .dtype .kind == "O" :
133
+ if kind :
134
+ dtype = kind_default_dtypes .get (first_kind , None )
135
+ return np .array (v , dtype = dtype )
136
+ else :
137
+ return v .tolist ()
138
138
else :
139
139
# v is a non-numeric homogenous array
140
140
new_v = v .copy ()
@@ -149,12 +149,12 @@ def copy_to_readonly_numpy_array(v, kind=None, force_numeric=False):
149
149
if "U" not in kind :
150
150
# Force non-numeric arrays to have object type
151
151
# --------------------------------------------
152
- # Here we make sure that non-numeric arrays have the object
153
- # datatype. This works around cases like np.array([1, 2, '3']) where
152
+ # Here we make sure that non-numeric arrays become lists
153
+ # This works around cases like np.array([1, 2, '3']) where
154
154
# numpy converts the integers to strings and returns array of dtype
155
155
# '<U21'
156
156
if new_v .dtype .kind not in ["u" , "i" , "f" , "O" , "M" ]:
157
- new_v = np . array ( v , dtype = "object" )
157
+ return v . tolist ( )
158
158
159
159
# Set new array to be read-only
160
160
# -----------------------------
@@ -191,7 +191,7 @@ def is_homogeneous_array(v):
191
191
if v_numpy .shape == ():
192
192
return False
193
193
else :
194
- return True
194
+ return True # v_numpy.dtype.kind in ["u", "i", "f", "M", "U"]
195
195
return False
196
196
197
197
@@ -393,7 +393,7 @@ def validate_coerce(self, v):
393
393
# Pass None through
394
394
pass
395
395
elif is_homogeneous_array (v ):
396
- v = copy_to_readonly_numpy_array (v )
396
+ v = copy_to_readonly_numpy_array_or_list (v )
397
397
elif is_simple_array (v ):
398
398
v = to_scalar_or_list (v )
399
399
else :
@@ -598,7 +598,7 @@ def validate_coerce(self, v):
598
598
self .raise_invalid_elements (invalid_els [:10 ])
599
599
600
600
if is_homogeneous_array (v ):
601
- v = copy_to_readonly_numpy_array (v )
601
+ v = copy_to_readonly_numpy_array_or_list (v )
602
602
else :
603
603
v = to_scalar_or_list (v )
604
604
else :
@@ -754,7 +754,7 @@ def validate_coerce(self, v):
754
754
elif self .array_ok and is_homogeneous_array (v ):
755
755
np = get_module ("numpy" )
756
756
try :
757
- v_array = copy_to_readonly_numpy_array (v , force_numeric = True )
757
+ v_array = copy_to_readonly_numpy_array_or_list (v , force_numeric = True )
758
758
except (ValueError , TypeError , OverflowError ):
759
759
self .raise_invalid_val (v )
760
760
@@ -881,7 +881,7 @@ def validate_coerce(self, v):
881
881
pass
882
882
elif self .array_ok and is_homogeneous_array (v ):
883
883
np = get_module ("numpy" )
884
- v_array = copy_to_readonly_numpy_array (
884
+ v_array = copy_to_readonly_numpy_array_or_list (
885
885
v , kind = ("i" , "u" ), force_numeric = True
886
886
)
887
887
@@ -1042,26 +1042,7 @@ def validate_coerce(self, v):
1042
1042
if invalid_els :
1043
1043
self .raise_invalid_elements (invalid_els )
1044
1044
1045
- if is_homogeneous_array (v ):
1046
- np = get_module ("numpy" )
1047
-
1048
- # If not strict, let numpy cast elements to strings
1049
- v = copy_to_readonly_numpy_array (v , kind = "U" )
1050
-
1051
- # Check no_blank
1052
- if self .no_blank :
1053
- invalid_els = v [v == "" ][:10 ].tolist ()
1054
- if invalid_els :
1055
- self .raise_invalid_elements (invalid_els )
1056
-
1057
- # Check values
1058
- if self .values :
1059
- invalid_inds = np .logical_not (np .isin (v , self .values ))
1060
- invalid_els = v [invalid_inds ][:10 ].tolist ()
1061
- if invalid_els :
1062
- self .raise_invalid_elements (invalid_els )
1063
-
1064
- elif is_simple_array (v ):
1045
+ if is_simple_array (v ) or is_homogeneous_array (v ):
1065
1046
if not self .strict :
1066
1047
v = [StringValidator .to_str_or_unicode_or_none (e ) for e in v ]
1067
1048
@@ -1338,8 +1319,8 @@ def validate_coerce(self, v, should_raise=True):
1338
1319
# Pass None through
1339
1320
pass
1340
1321
elif self .array_ok and is_homogeneous_array (v ):
1341
- v = copy_to_readonly_numpy_array (v )
1342
- if self .numbers_allowed () and v .dtype .kind in ["u" , "i" , "f" ]:
1322
+ v = copy_to_readonly_numpy_array_or_list (v )
1323
+ if not isinstance ( v , list ) and self .numbers_allowed () and v .dtype .kind in ["u" , "i" , "f" ]:
1343
1324
# Numbers are allowed and we have an array of numbers.
1344
1325
# All good
1345
1326
pass
@@ -1353,9 +1334,9 @@ def validate_coerce(self, v, should_raise=True):
1353
1334
1354
1335
# ### Check that elements have valid colors types ###
1355
1336
elif self .numbers_allowed () or invalid_els :
1356
- v = copy_to_readonly_numpy_array (validated_v , kind = "O" )
1337
+ v = copy_to_readonly_numpy_array_or_list (validated_v , kind = "O" )
1357
1338
else :
1358
- v = copy_to_readonly_numpy_array (validated_v , kind = "U" )
1339
+ v = copy_to_readonly_numpy_array_or_list (validated_v , kind = "U" )
1359
1340
elif self .array_ok and is_simple_array (v ):
1360
1341
validated_v = [self .validate_coerce (e , should_raise = False ) for e in v ]
1361
1342
@@ -1870,7 +1851,7 @@ def validate_coerce(self, v):
1870
1851
self .raise_invalid_elements (invalid_els )
1871
1852
1872
1853
if is_homogeneous_array (v ):
1873
- v = copy_to_readonly_numpy_array (validated_v , kind = "U" )
1854
+ v = copy_to_readonly_numpy_array_or_list (validated_v , kind = "U" )
1874
1855
else :
1875
1856
v = to_scalar_or_list (v )
1876
1857
else :
@@ -1918,7 +1899,7 @@ def validate_coerce(self, v):
1918
1899
# Pass None through
1919
1900
pass
1920
1901
elif self .array_ok and is_homogeneous_array (v ):
1921
- v = copy_to_readonly_numpy_array (v , kind = "O" )
1902
+ v = copy_to_readonly_numpy_array_or_list (v , kind = "O" )
1922
1903
elif self .array_ok and is_simple_array (v ):
1923
1904
v = to_scalar_or_list (v )
1924
1905
return v
0 commit comments