@@ -969,7 +969,7 @@ def read(self) -> DataFrame | Series:
969
969
else :
970
970
return obj
971
971
972
- def _get_object_parser (self , json ) -> DataFrame | Series :
972
+ def _get_object_parser (self , json : str ) -> DataFrame | Series :
973
973
"""
974
974
Parses a json document into a pandas object.
975
975
"""
@@ -985,16 +985,14 @@ def _get_object_parser(self, json) -> DataFrame | Series:
985
985
"date_unit" : self .date_unit ,
986
986
"dtype_backend" : self .dtype_backend ,
987
987
}
988
- obj = None
989
988
if typ == "frame" :
990
- obj = FrameParser (json , ** kwargs ).parse ()
991
-
992
- if typ == "series" or obj is None :
989
+ return FrameParser (json , ** kwargs ).parse ()
990
+ elif typ == "series" :
993
991
if not isinstance (dtype , bool ):
994
992
kwargs ["dtype" ] = dtype
995
- obj = SeriesParser (json , ** kwargs ).parse ()
996
-
997
- return obj
993
+ return SeriesParser (json , ** kwargs ).parse ()
994
+ else :
995
+ raise ValueError ( f" { typ = } must be 'frame' or 'series'." )
998
996
999
997
def close (self ) -> None :
1000
998
"""
@@ -1107,7 +1105,6 @@ def __init__(
1107
1105
self .convert_dates = convert_dates
1108
1106
self .date_unit = date_unit
1109
1107
self .keep_default_dates = keep_default_dates
1110
- self .obj : DataFrame | Series | None = None
1111
1108
self .dtype_backend = dtype_backend
1112
1109
1113
1110
@final
@@ -1121,26 +1118,22 @@ def check_keys_split(self, decoded: dict) -> None:
1121
1118
raise ValueError (f"JSON data had unexpected key(s): { bad_keys_joined } " )
1122
1119
1123
1120
@final
1124
- def parse (self ):
1125
- self ._parse ()
1121
+ def parse (self ) -> DataFrame | Series :
1122
+ obj = self ._parse ()
1126
1123
1127
- if self .obj is None :
1128
- return None
1129
1124
if self .convert_axes :
1130
- self ._convert_axes ()
1131
- self ._try_convert_types ()
1132
- return self . obj
1125
+ obj = self ._convert_axes (obj )
1126
+ obj = self ._try_convert_types (obj )
1127
+ return obj
1133
1128
1134
- def _parse (self ) -> None :
1129
+ def _parse (self ) -> DataFrame | Series :
1135
1130
raise AbstractMethodError (self )
1136
1131
1137
1132
@final
1138
- def _convert_axes (self ) -> None :
1133
+ def _convert_axes (self , obj : DataFrame | Series ) -> DataFrame | Series :
1139
1134
"""
1140
1135
Try to convert axes.
1141
1136
"""
1142
- obj = self .obj
1143
- assert obj is not None # for mypy
1144
1137
for axis_name in obj ._AXIS_ORDERS :
1145
1138
ax = obj ._get_axis (axis_name )
1146
1139
ser = Series (ax , dtype = ax .dtype , copy = False )
@@ -1153,9 +1146,10 @@ def _convert_axes(self) -> None:
1153
1146
)
1154
1147
if result :
1155
1148
new_axis = Index (new_ser , dtype = new_ser .dtype , copy = False )
1156
- setattr (self .obj , axis_name , new_axis )
1149
+ setattr (obj , axis_name , new_axis )
1150
+ return obj
1157
1151
1158
- def _try_convert_types (self ) -> None :
1152
+ def _try_convert_types (self , obj : DataFrame | Series ) -> DataFrame | Series :
1159
1153
raise AbstractMethodError (self )
1160
1154
1161
1155
@final
@@ -1292,42 +1286,31 @@ def _try_convert_to_date(self, data: Series) -> tuple[Series, bool]:
1292
1286
class SeriesParser (Parser ):
1293
1287
_default_orient = "index"
1294
1288
_split_keys = ("name" , "index" , "data" )
1295
- obj : Series | None
1296
1289
1297
- def _parse (self ) -> None :
1290
+ def _parse (self ) -> Series :
1298
1291
data = ujson_loads (self .json , precise_float = self .precise_float )
1299
1292
1300
1293
if self .orient == "split" :
1301
1294
decoded = {str (k ): v for k , v in data .items ()}
1302
1295
self .check_keys_split (decoded )
1303
- self . obj = Series (** decoded )
1296
+ return Series (** decoded )
1304
1297
else :
1305
- self . obj = Series (data )
1298
+ return Series (data )
1306
1299
1307
- def _try_convert_types (self ) -> None :
1308
- if self .obj is None :
1309
- return
1310
- obj , result = self ._try_convert_data (
1311
- "data" , self .obj , convert_dates = self .convert_dates
1312
- )
1313
- if result :
1314
- self .obj = obj
1300
+ def _try_convert_types (self , obj : Series ) -> Series :
1301
+ obj , _ = self ._try_convert_data ("data" , obj , convert_dates = self .convert_dates )
1302
+ return obj
1315
1303
1316
1304
1317
1305
class FrameParser (Parser ):
1318
1306
_default_orient = "columns"
1319
1307
_split_keys = ("columns" , "index" , "data" )
1320
- obj : DataFrame | None
1321
1308
1322
- def _parse (self ) -> None :
1309
+ def _parse (self ) -> DataFrame :
1323
1310
json = self .json
1324
1311
orient = self .orient
1325
1312
1326
- if orient == "columns" :
1327
- self .obj = DataFrame (
1328
- ujson_loads (json , precise_float = self .precise_float ), dtype = None
1329
- )
1330
- elif orient == "split" :
1313
+ if orient == "split" :
1331
1314
decoded = {
1332
1315
str (k ): v
1333
1316
for k , v in ujson_loads (json , precise_float = self .precise_float ).items ()
@@ -1341,34 +1324,34 @@ def _parse(self) -> None:
1341
1324
orig_names ,
1342
1325
is_potential_multi_index (orig_names , None ),
1343
1326
)
1344
- self . obj = DataFrame (dtype = None , ** decoded )
1327
+ return DataFrame (dtype = None , ** decoded )
1345
1328
elif orient == "index" :
1346
- self . obj = DataFrame .from_dict (
1329
+ return DataFrame .from_dict (
1347
1330
ujson_loads (json , precise_float = self .precise_float ),
1348
1331
dtype = None ,
1349
1332
orient = "index" ,
1350
1333
)
1351
1334
elif orient == "table" :
1352
- self . obj = parse_table_schema (json , precise_float = self .precise_float )
1335
+ return parse_table_schema (json , precise_float = self .precise_float )
1353
1336
else :
1354
- self .obj = DataFrame (
1337
+ # includes orient == "columns"
1338
+ return DataFrame (
1355
1339
ujson_loads (json , precise_float = self .precise_float ), dtype = None
1356
1340
)
1357
1341
1342
+ @final
1358
1343
def _process_converter (
1359
1344
self ,
1345
+ obj : DataFrame ,
1360
1346
f : Callable [[Hashable , Series ], tuple [Series , bool ]],
1361
1347
filt : Callable [[Hashable ], bool ] | None = None ,
1362
- ) -> None :
1348
+ ) -> DataFrame :
1363
1349
"""
1364
1350
Take a conversion function and possibly recreate the frame.
1365
1351
"""
1366
1352
if filt is None :
1367
1353
filt = lambda col : True
1368
1354
1369
- obj = self .obj
1370
- assert obj is not None # for mypy
1371
-
1372
1355
needs_new_obj = False
1373
1356
new_obj = {}
1374
1357
for i , (col , c ) in enumerate (obj .items ()):
@@ -1383,48 +1366,43 @@ def _process_converter(
1383
1366
# possibly handle dup columns
1384
1367
new_frame = DataFrame (new_obj , index = obj .index )
1385
1368
new_frame .columns = obj .columns
1386
- self .obj = new_frame
1369
+ return new_frame
1370
+ return obj
1387
1371
1388
- def _try_convert_types (self ) -> None :
1389
- if self .obj is None :
1390
- return
1372
+ def _try_convert_types (self , obj : DataFrame ) -> DataFrame :
1391
1373
if self .convert_dates :
1392
- self ._try_convert_dates ()
1393
-
1394
- self ._process_converter (
1395
- lambda col , c : self ._try_convert_data (col , c , convert_dates = False )
1396
- )
1397
-
1398
- def _try_convert_dates (self ) -> None :
1399
- if self .obj is None :
1400
- return
1401
-
1402
- # our columns to parse
1403
- convert_dates_list_bool = self .convert_dates
1404
- if isinstance (convert_dates_list_bool , bool ):
1405
- convert_dates_list_bool = []
1406
- convert_dates = set (convert_dates_list_bool )
1407
-
1408
- def is_ok (col ) -> bool :
1409
- """
1410
- Return if this col is ok to try for a date parse.
1411
- """
1412
- if col in convert_dates :
1413
- return True
1414
- if not self .keep_default_dates :
1415
- return False
1416
- if not isinstance (col , str ):
1374
+ # our columns to parse
1375
+ convert_dates_list_bool = self .convert_dates
1376
+ if isinstance (convert_dates_list_bool , bool ):
1377
+ convert_dates_list_bool = []
1378
+ convert_dates = set (convert_dates_list_bool )
1379
+
1380
+ def is_ok (col ) -> bool :
1381
+ """
1382
+ Return if this col is ok to try for a date parse.
1383
+ """
1384
+ if col in convert_dates :
1385
+ return True
1386
+ if not self .keep_default_dates :
1387
+ return False
1388
+ if not isinstance (col , str ):
1389
+ return False
1390
+
1391
+ col_lower = col .lower ()
1392
+ if (
1393
+ col_lower .endswith (("_at" , "_time" ))
1394
+ or col_lower == "modified"
1395
+ or col_lower == "date"
1396
+ or col_lower == "datetime"
1397
+ or col_lower .startswith ("timestamp" )
1398
+ ):
1399
+ return True
1417
1400
return False
1418
1401
1419
- col_lower = col .lower ()
1420
- if (
1421
- col_lower .endswith (("_at" , "_time" ))
1422
- or col_lower == "modified"
1423
- or col_lower == "date"
1424
- or col_lower == "datetime"
1425
- or col_lower .startswith ("timestamp" )
1426
- ):
1427
- return True
1428
- return False
1429
-
1430
- self ._process_converter (lambda col , c : self ._try_convert_to_date (c ), filt = is_ok )
1402
+ obj = self ._process_converter (
1403
+ obj , lambda col , c : self ._try_convert_to_date (c ), filt = is_ok
1404
+ )
1405
+
1406
+ return self ._process_converter (
1407
+ obj , lambda col , c : self ._try_convert_data (col , c , convert_dates = False )
1408
+ )
0 commit comments