14
14
Generic ,
15
15
Literal ,
16
16
TypeVar ,
17
+ final ,
17
18
overload ,
18
19
)
19
20
import warnings
37
38
is_string_dtype ,
38
39
)
39
40
from pandas .core .dtypes .dtypes import PeriodDtype
40
- from pandas .core .dtypes .generic import ABCIndex
41
41
42
42
from pandas import (
43
43
ArrowDtype ,
44
44
DataFrame ,
45
+ Index ,
45
46
MultiIndex ,
46
47
Series ,
47
48
isna ,
@@ -1119,10 +1120,11 @@ class Parser:
1119
1120
"us" : 31536000000000 ,
1120
1121
"ns" : 31536000000000000 ,
1121
1122
}
1123
+ json : str
1122
1124
1123
1125
def __init__ (
1124
1126
self ,
1125
- json ,
1127
+ json : str ,
1126
1128
orient ,
1127
1129
dtype : DtypeArg | None = None ,
1128
1130
convert_axes : bool = True ,
@@ -1157,7 +1159,8 @@ def __init__(
1157
1159
self .obj : DataFrame | Series | None = None
1158
1160
self .dtype_backend = dtype_backend
1159
1161
1160
- def check_keys_split (self , decoded ) -> None :
1162
+ @final
1163
+ def check_keys_split (self , decoded : dict ) -> None :
1161
1164
"""
1162
1165
Checks that dict has only the appropriate keys for orient='split'.
1163
1166
"""
@@ -1166,6 +1169,7 @@ def check_keys_split(self, decoded) -> None:
1166
1169
bad_keys_joined = ", " .join (bad_keys )
1167
1170
raise ValueError (f"JSON data had unexpected key(s): { bad_keys_joined } " )
1168
1171
1172
+ @final
1169
1173
def parse (self ):
1170
1174
self ._parse ()
1171
1175
@@ -1179,34 +1183,41 @@ def parse(self):
1179
1183
def _parse (self ):
1180
1184
raise AbstractMethodError (self )
1181
1185
1186
+ @final
1182
1187
def _convert_axes (self ) -> None :
1183
1188
"""
1184
1189
Try to convert axes.
1185
1190
"""
1186
1191
obj = self .obj
1187
1192
assert obj is not None # for mypy
1188
1193
for axis_name in obj ._AXIS_ORDERS :
1189
- new_axis , result = self ._try_convert_data (
1194
+ ax = obj ._get_axis (axis_name )
1195
+ ser = Series (ax , dtype = ax .dtype , copy = False )
1196
+ new_ser , result = self ._try_convert_data (
1190
1197
name = axis_name ,
1191
- data = obj . _get_axis ( axis_name ) ,
1198
+ data = ser ,
1192
1199
use_dtypes = False ,
1193
1200
convert_dates = True ,
1201
+ is_axis = True ,
1194
1202
)
1195
1203
if result :
1204
+ new_axis = Index (new_ser , dtype = new_ser .dtype , copy = False )
1196
1205
setattr (self .obj , axis_name , new_axis )
1197
1206
1198
1207
def _try_convert_types (self ):
1199
1208
raise AbstractMethodError (self )
1200
1209
1210
+ @final
1201
1211
def _try_convert_data (
1202
1212
self ,
1203
1213
name : Hashable ,
1204
- data ,
1214
+ data : Series ,
1205
1215
use_dtypes : bool = True ,
1206
1216
convert_dates : bool | list [str ] = True ,
1207
- ):
1217
+ is_axis : bool = False ,
1218
+ ) -> tuple [Series , bool ]:
1208
1219
"""
1209
- Try to parse a ndarray like into a column by inferring dtype.
1220
+ Try to parse a Series into a column by inferring dtype.
1210
1221
"""
1211
1222
# don't try to coerce, unless a force conversion
1212
1223
if use_dtypes :
@@ -1242,7 +1253,7 @@ def _try_convert_data(
1242
1253
if result :
1243
1254
return new_data , True
1244
1255
1245
- if self .dtype_backend is not lib .no_default and not isinstance ( data , ABCIndex ) :
1256
+ if self .dtype_backend is not lib .no_default and not is_axis :
1246
1257
# Fall through for conversion later on
1247
1258
return data , True
1248
1259
elif is_string_dtype (data .dtype ):
@@ -1285,7 +1296,8 @@ def _try_convert_data(
1285
1296
1286
1297
return data , True
1287
1298
1288
- def _try_convert_to_date (self , data ):
1299
+ @final
1300
+ def _try_convert_to_date (self , data : Series ) -> tuple [Series , bool ]:
1289
1301
"""
1290
1302
Try to parse a ndarray like into a date column.
1291
1303
@@ -1335,13 +1347,11 @@ def _try_convert_to_date(self, data):
1335
1347
return new_data , True
1336
1348
return data , False
1337
1349
1338
- def _try_convert_dates (self ):
1339
- raise AbstractMethodError (self )
1340
-
1341
1350
1342
1351
class SeriesParser (Parser ):
1343
1352
_default_orient = "index"
1344
1353
_split_keys = ("name" , "index" , "data" )
1354
+ obj : Series | None
1345
1355
1346
1356
def _parse (self ) -> None :
1347
1357
data = ujson_loads (self .json , precise_float = self .precise_float )
@@ -1366,6 +1376,7 @@ def _try_convert_types(self) -> None:
1366
1376
class FrameParser (Parser ):
1367
1377
_default_orient = "columns"
1368
1378
_split_keys = ("columns" , "index" , "data" )
1379
+ obj : DataFrame | None
1369
1380
1370
1381
def _parse (self ) -> None :
1371
1382
json = self .json
@@ -1403,20 +1414,24 @@ def _parse(self) -> None:
1403
1414
ujson_loads (json , precise_float = self .precise_float ), dtype = None
1404
1415
)
1405
1416
1406
- def _process_converter (self , f , filt = None ) -> None :
1417
+ def _process_converter (
1418
+ self ,
1419
+ f : Callable [[Hashable , Series ], tuple [Series , bool ]],
1420
+ filt : Callable [[Hashable ], bool ] | None = None ,
1421
+ ) -> None :
1407
1422
"""
1408
1423
Take a conversion function and possibly recreate the frame.
1409
1424
"""
1410
1425
if filt is None :
1411
- filt = lambda col , c : True
1426
+ filt = lambda col : True
1412
1427
1413
1428
obj = self .obj
1414
1429
assert obj is not None # for mypy
1415
1430
1416
1431
needs_new_obj = False
1417
1432
new_obj = {}
1418
1433
for i , (col , c ) in enumerate (obj .items ()):
1419
- if filt (col , c ):
1434
+ if filt (col ):
1420
1435
new_data , result = f (col , c )
1421
1436
if result :
1422
1437
c = new_data
@@ -1453,6 +1468,10 @@ def is_ok(col) -> bool:
1453
1468
"""
1454
1469
Return if this col is ok to try for a date parse.
1455
1470
"""
1471
+ if col in convert_dates :
1472
+ return True
1473
+ if not self .keep_default_dates :
1474
+ return False
1456
1475
if not isinstance (col , str ):
1457
1476
return False
1458
1477
@@ -1467,9 +1486,4 @@ def is_ok(col) -> bool:
1467
1486
return True
1468
1487
return False
1469
1488
1470
- self ._process_converter (
1471
- lambda col , c : self ._try_convert_to_date (c ),
1472
- lambda col , c : (
1473
- (self .keep_default_dates and is_ok (col )) or col in convert_dates
1474
- ),
1475
- )
1489
+ self ._process_converter (lambda col , c : self ._try_convert_to_date (c ), filt = is_ok )
0 commit comments