@@ -53,7 +53,7 @@ def to_scalar_or_list(v):
5353 return v
5454
5555
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 ):
5757 """
5858 Convert an array-like value into a read-only numpy array
5959
@@ -89,7 +89,7 @@ def copy_to_readonly_numpy_array(v, kind=None, force_numeric=False):
8989
9090 # u: unsigned int, i: signed int, f: float
9191 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" }
9393
9494 # Handle pandas Series and Index objects
9595 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):
113113 if not isinstance (v , np .ndarray ):
114114 # v has its own logic on how to convert itself into a numpy array
115115 if is_numpy_convertable (v ):
116- return copy_to_readonly_numpy_array (
116+ return copy_to_readonly_numpy_array_or_list (
117117 np .array (v ), kind = kind , force_numeric = force_numeric
118118 )
119119 else :
120120 # 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 ]
128122 elif v .dtype .kind in numeric_kinds :
129123 # v is a homogenous numeric array
130124 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):
135129 else :
136130 # Either no kind was requested or requested kind is satisfied
137131 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 ()
138138 else :
139139 # v is a non-numeric homogenous array
140140 new_v = v .copy ()
@@ -149,12 +149,12 @@ def copy_to_readonly_numpy_array(v, kind=None, force_numeric=False):
149149 if "U" not in kind :
150150 # Force non-numeric arrays to have object type
151151 # --------------------------------------------
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
154154 # numpy converts the integers to strings and returns array of dtype
155155 # '<U21'
156156 if new_v .dtype .kind not in ["u" , "i" , "f" , "O" , "M" ]:
157- new_v = np . array ( v , dtype = "object" )
157+ return v . tolist ( )
158158
159159 # Set new array to be read-only
160160 # -----------------------------
@@ -191,7 +191,7 @@ def is_homogeneous_array(v):
191191 if v_numpy .shape == ():
192192 return False
193193 else :
194- return True
194+ return True # v_numpy.dtype.kind in ["u", "i", "f", "M", "U"]
195195 return False
196196
197197
@@ -393,7 +393,7 @@ def validate_coerce(self, v):
393393 # Pass None through
394394 pass
395395 elif is_homogeneous_array (v ):
396- v = copy_to_readonly_numpy_array (v )
396+ v = copy_to_readonly_numpy_array_or_list (v )
397397 elif is_simple_array (v ):
398398 v = to_scalar_or_list (v )
399399 else :
@@ -598,7 +598,7 @@ def validate_coerce(self, v):
598598 self .raise_invalid_elements (invalid_els [:10 ])
599599
600600 if is_homogeneous_array (v ):
601- v = copy_to_readonly_numpy_array (v )
601+ v = copy_to_readonly_numpy_array_or_list (v )
602602 else :
603603 v = to_scalar_or_list (v )
604604 else :
@@ -754,7 +754,7 @@ def validate_coerce(self, v):
754754 elif self .array_ok and is_homogeneous_array (v ):
755755 np = get_module ("numpy" )
756756 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 )
758758 except (ValueError , TypeError , OverflowError ):
759759 self .raise_invalid_val (v )
760760
@@ -881,7 +881,7 @@ def validate_coerce(self, v):
881881 pass
882882 elif self .array_ok and is_homogeneous_array (v ):
883883 np = get_module ("numpy" )
884- v_array = copy_to_readonly_numpy_array (
884+ v_array = copy_to_readonly_numpy_array_or_list (
885885 v , kind = ("i" , "u" ), force_numeric = True
886886 )
887887
@@ -1042,26 +1042,7 @@ def validate_coerce(self, v):
10421042 if invalid_els :
10431043 self .raise_invalid_elements (invalid_els )
10441044
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 ):
10651046 if not self .strict :
10661047 v = [StringValidator .to_str_or_unicode_or_none (e ) for e in v ]
10671048
@@ -1338,8 +1319,8 @@ def validate_coerce(self, v, should_raise=True):
13381319 # Pass None through
13391320 pass
13401321 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" ]:
13431324 # Numbers are allowed and we have an array of numbers.
13441325 # All good
13451326 pass
@@ -1353,9 +1334,9 @@ def validate_coerce(self, v, should_raise=True):
13531334
13541335 # ### Check that elements have valid colors types ###
13551336 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" )
13571338 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" )
13591340 elif self .array_ok and is_simple_array (v ):
13601341 validated_v = [self .validate_coerce (e , should_raise = False ) for e in v ]
13611342
@@ -1870,7 +1851,7 @@ def validate_coerce(self, v):
18701851 self .raise_invalid_elements (invalid_els )
18711852
18721853 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" )
18741855 else :
18751856 v = to_scalar_or_list (v )
18761857 else :
@@ -1918,7 +1899,7 @@ def validate_coerce(self, v):
19181899 # Pass None through
19191900 pass
19201901 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" )
19221903 elif self .array_ok and is_simple_array (v ):
19231904 v = to_scalar_or_list (v )
19241905 return v
0 commit comments