@@ -2290,9 +2290,10 @@ def _legal_dtype(series):
2290
2290
else series .cat .categories .dtype )
2291
2291
legal = dtype == 'O' or (dtype == 'float' and series .isna ().all ())
2292
2292
return legal
2293
+ err_wrong_dtype = ('Can only concatenate list-likes containing only '
2294
+ 'strings (or missing values)' )
2293
2295
if any (not _legal_dtype (x ) for x in others ):
2294
- raise TypeError ('Can only concatenate list-likes containing only '
2295
- 'strings (or missing values)' )
2296
+ raise TypeError (err_wrong_dtype )
2296
2297
2297
2298
if join is None and warn :
2298
2299
warnings .warn ("A future version of pandas will perform index "
@@ -2321,23 +2322,31 @@ def _legal_dtype(series):
2321
2322
na_masks = np .array ([isna (x ) for x in all_cols ])
2322
2323
union_mask = np .logical_or .reduce (na_masks , axis = 0 )
2323
2324
2324
- if na_rep is None and union_mask .any ():
2325
- # no na_rep means NaNs for all rows where any column has a NaN
2326
- # only necessary if there are actually any NaNs
2327
- result = np .empty (len (data ), dtype = object )
2328
- np .putmask (result , union_mask , np .nan )
2329
-
2330
- not_masked = ~ union_mask
2331
- result [not_masked ] = cat_core ([x [not_masked ] for x in all_cols ],
2332
- sep )
2333
- elif na_rep is not None and union_mask .any ():
2334
- # fill NaNs with na_rep in case there are actually any NaNs
2335
- all_cols = [np .where (nm , na_rep , col )
2336
- for nm , col in zip (na_masks , all_cols )]
2337
- result = cat_core (all_cols , sep )
2338
- else :
2339
- # no NaNs - can just concatenate
2340
- result = cat_core (all_cols , sep )
2325
+ # if there are any non-string, non-null values hidden within an object
2326
+ # dtype, cat_core will fail; catch error and return better error.
2327
+ try :
2328
+ if na_rep is None and union_mask .any ():
2329
+ # no na_rep means NaNs for all rows where any column has a NaN
2330
+ # only necessary if there are actually any NaNs
2331
+ result = np .empty (len (data ), dtype = object )
2332
+ np .putmask (result , union_mask , np .nan )
2333
+
2334
+ not_masked = ~ union_mask
2335
+ result [not_masked ] = cat_core ([x [not_masked ]
2336
+ for x in all_cols ], sep )
2337
+ elif na_rep is not None and union_mask .any ():
2338
+ # fill NaNs with na_rep in case there are actually any NaNs
2339
+ all_cols = [np .where (nm , na_rep , col )
2340
+ for nm , col in zip (na_masks , all_cols )]
2341
+ result = cat_core (all_cols , sep )
2342
+ else :
2343
+ # no NaNs - can just concatenate
2344
+ result = cat_core (all_cols , sep )
2345
+ except TypeError as exc :
2346
+ if re .match (r'can only concatenate str \(not \"\w+\"\) to str' ,
2347
+ str (exc )):
2348
+ raise TypeError (err_wrong_dtype )
2349
+ raise exc
2341
2350
2342
2351
if isinstance (self ._orig , Index ):
2343
2352
# add dtype for case that result is all-NA
0 commit comments