1
+ from abc import ABC , abstractmethod
1
2
from collections import abc
2
3
import functools
3
4
from io import BytesIO , StringIO
4
5
from itertools import islice
5
6
import os
6
- from typing import IO , Any , Callable , List , Optional , Tuple , Type
7
+ from typing import IO , Any , Callable , List , Mapping , Optional , Tuple , Type , Union
7
8
8
9
import numpy as np
9
10
10
11
import pandas ._libs .json as json
11
12
from pandas ._libs .tslibs import iNaT
12
- from pandas ._typing import CompressionOptions , JSONSerializable , StorageOptions
13
+ from pandas ._typing import (
14
+ CompressionOptions ,
15
+ IndexLabel ,
16
+ JSONSerializable ,
17
+ StorageOptions ,
18
+ )
13
19
from pandas .errors import AbstractMethodError
14
20
from pandas .util ._decorators import deprecate_kwarg , deprecate_nonkeyword_arguments
15
21
16
22
from pandas .core .dtypes .common import ensure_str , is_period_dtype
17
23
18
24
from pandas import DataFrame , MultiIndex , Series , isna , to_datetime
19
25
from pandas .core .construction import create_series_with_explicit_dtype
26
+ from pandas .core .generic import NDFrame
20
27
from pandas .core .reshape .concat import concat
21
28
22
29
from pandas .io .common import get_compression_method , get_filepath_or_buffer , get_handle
33
40
# interface to/from
34
41
def to_json (
35
42
path_or_buf ,
36
- obj ,
43
+ obj : NDFrame ,
37
44
orient : Optional [str ] = None ,
38
45
date_format : str = "epoch" ,
39
46
double_precision : int = 10 ,
@@ -110,7 +117,7 @@ def to_json(
110
117
path_or_buf .close ()
111
118
112
119
113
- class Writer :
120
+ class Writer ( ABC ) :
114
121
_default_orient : str
115
122
116
123
def __init__ (
@@ -146,75 +153,52 @@ def _format_axes(self):
146
153
raise AbstractMethodError (self )
147
154
148
155
def write (self ):
149
- return self ._write (
150
- self .obj ,
151
- self .orient ,
152
- self .double_precision ,
153
- self .ensure_ascii ,
154
- self .date_unit ,
155
- self .date_format == "iso" ,
156
- self .default_handler ,
157
- self .indent ,
158
- )
159
-
160
- def _write (
161
- self ,
162
- obj ,
163
- orient : Optional [str ],
164
- double_precision : int ,
165
- ensure_ascii : bool ,
166
- date_unit : str ,
167
- iso_dates : bool ,
168
- default_handler : Optional [Callable [[Any ], JSONSerializable ]],
169
- indent : int ,
170
- ):
156
+ iso_dates = self .date_format == "iso"
171
157
return dumps (
172
- obj ,
173
- orient = orient ,
174
- double_precision = double_precision ,
175
- ensure_ascii = ensure_ascii ,
176
- date_unit = date_unit ,
158
+ self . obj_to_write ,
159
+ orient = self . orient ,
160
+ double_precision = self . double_precision ,
161
+ ensure_ascii = self . ensure_ascii ,
162
+ date_unit = self . date_unit ,
177
163
iso_dates = iso_dates ,
178
- default_handler = default_handler ,
179
- indent = indent ,
164
+ default_handler = self . default_handler ,
165
+ indent = self . indent ,
180
166
)
181
167
168
+ @property
169
+ @abstractmethod
170
+ def obj_to_write (self ) -> Union [NDFrame , Mapping [IndexLabel , Any ]]:
171
+ """Object to write in JSON format."""
172
+ pass
173
+
182
174
183
175
class SeriesWriter (Writer ):
184
176
_default_orient = "index"
185
177
178
+ @property
179
+ def obj_to_write (self ) -> Union [NDFrame , Mapping [IndexLabel , Any ]]:
180
+ if not self .index and self .orient == "split" :
181
+ return {"name" : self .obj .name , "data" : self .obj .values }
182
+ else :
183
+ return self .obj
184
+
186
185
def _format_axes (self ):
187
186
if not self .obj .index .is_unique and self .orient == "index" :
188
187
raise ValueError (f"Series index must be unique for orient='{ self .orient } '" )
189
188
190
- def _write (
191
- self ,
192
- obj ,
193
- orient : Optional [str ],
194
- double_precision : int ,
195
- ensure_ascii : bool ,
196
- date_unit : str ,
197
- iso_dates : bool ,
198
- default_handler : Optional [Callable [[Any ], JSONSerializable ]],
199
- indent : int ,
200
- ):
201
- if not self .index and orient == "split" :
202
- obj = {"name" : obj .name , "data" : obj .values }
203
- return super ()._write (
204
- obj ,
205
- orient ,
206
- double_precision ,
207
- ensure_ascii ,
208
- date_unit ,
209
- iso_dates ,
210
- default_handler ,
211
- indent ,
212
- )
213
-
214
189
215
190
class FrameWriter (Writer ):
216
191
_default_orient = "columns"
217
192
193
+ @property
194
+ def obj_to_write (self ) -> Union [NDFrame , Mapping [IndexLabel , Any ]]:
195
+ if not self .index and self .orient == "split" :
196
+ obj_to_write = self .obj .to_dict (orient = "split" )
197
+ del obj_to_write ["index" ]
198
+ else :
199
+ obj_to_write = self .obj
200
+ return obj_to_write
201
+
218
202
def _format_axes (self ):
219
203
"""
220
204
Try to format axes if they are datelike.
@@ -232,31 +216,6 @@ def _format_axes(self):
232
216
f"DataFrame columns must be unique for orient='{ self .orient } '."
233
217
)
234
218
235
- def _write (
236
- self ,
237
- obj ,
238
- orient : Optional [str ],
239
- double_precision : int ,
240
- ensure_ascii : bool ,
241
- date_unit : str ,
242
- iso_dates : bool ,
243
- default_handler : Optional [Callable [[Any ], JSONSerializable ]],
244
- indent : int ,
245
- ):
246
- if not self .index and orient == "split" :
247
- obj = obj .to_dict (orient = "split" )
248
- del obj ["index" ]
249
- return super ()._write (
250
- obj ,
251
- orient ,
252
- double_precision ,
253
- ensure_ascii ,
254
- date_unit ,
255
- iso_dates ,
256
- default_handler ,
257
- indent ,
258
- )
259
-
260
219
261
220
class JSONTableWriter (FrameWriter ):
262
221
_default_orient = "records"
@@ -331,30 +290,9 @@ def __init__(
331
290
self .orient = "records"
332
291
self .index = index
333
292
334
- def _write (
335
- self ,
336
- obj ,
337
- orient ,
338
- double_precision ,
339
- ensure_ascii ,
340
- date_unit ,
341
- iso_dates ,
342
- default_handler ,
343
- indent ,
344
- ):
345
- table_obj = {"schema" : self .schema , "data" : obj }
346
- serialized = super ()._write (
347
- table_obj ,
348
- orient ,
349
- double_precision ,
350
- ensure_ascii ,
351
- date_unit ,
352
- iso_dates ,
353
- default_handler ,
354
- indent ,
355
- )
356
-
357
- return serialized
293
+ @property
294
+ def obj_to_write (self ) -> Union [NDFrame , Mapping [IndexLabel , Any ]]:
295
+ return {"schema" : self .schema , "data" : self .obj }
358
296
359
297
360
298
@deprecate_kwarg (old_arg_name = "numpy" , new_arg_name = None )
0 commit comments