2
2
3
3
from six import string_types
4
4
import json
5
-
5
+ from pathlib import Path
6
6
7
7
from plotly .io ._utils import validate_coerce_fig_to_dict , validate_coerce_output_type
8
8
@@ -68,7 +68,7 @@ def write_json(fig, file, validate=True, pretty=False, remove_uids=True):
68
68
69
69
file: str or writeable
70
70
A string representing a local file path or a writeable object
71
- (e.g. an open file descriptor)
71
+ (e.g. a pathlib.Path object or an open file descriptor)
72
72
73
73
pretty: bool (default False)
74
74
True if JSON representation should be pretty-printed, False if
@@ -87,17 +87,40 @@ def write_json(fig, file, validate=True, pretty=False, remove_uids=True):
87
87
# Pass through validate argument and let to_json handle validation logic
88
88
json_str = to_json (fig , validate = validate , pretty = pretty , remove_uids = remove_uids )
89
89
90
- # Check if file is a string
91
- # -------------------------
92
- file_is_str = isinstance (file , string_types )
90
+ # Try to cast `file` as a pathlib object `path`.
91
+ # ----------------------------------------------
92
+ if isinstance (file , string_types ):
93
+ # Use the standard Path constructor to make a pathlib object.
94
+ path = Path (file )
95
+ elif isinstance (file , Path ):
96
+ # `file` is already a Path object.
97
+ path = file
98
+ else :
99
+ # We could not make a Path object out of file. Either `file` is an open file
100
+ # descriptor with a `write()` method or it's an invalid object.
101
+ path = None
93
102
94
103
# Open file
95
104
# ---------
96
- if file_is_str :
97
- with open (file , "w" ) as f :
98
- f .write (json_str )
105
+ if path is None :
106
+ # We previously failed to make sense of `file` as a pathlib object.
107
+ # Attempt to write to `file` as an open file descriptor.
108
+ try :
109
+ file .write (json_str )
110
+ return
111
+ except AttributeError :
112
+ pass
113
+ raise ValueError (
114
+ """
115
+ The 'file' argument '{file}' is not a string, pathlib.Path object, or file descriptor.
116
+ """ .format (
117
+ file = file
118
+ )
119
+ )
99
120
else :
100
- file .write (json_str )
121
+ # We previously succeeded in interpreting `file` as a pathlib object.
122
+ # Now we can use `write_bytes()`.
123
+ path .write_text (json_str )
101
124
102
125
103
126
def from_json (value , output_type = "Figure" , skip_invalid = False ):
@@ -162,7 +185,7 @@ def read_json(file, output_type="Figure", skip_invalid=False):
162
185
----------
163
186
file: str or readable
164
187
A string containing the path to a local file or a read-able Python
165
- object (e.g. an open file descriptor)
188
+ object (e.g. a pathlib.Path object or an open file descriptor)
166
189
167
190
output_type: type or str (default 'Figure')
168
191
The output figure type or type name.
@@ -177,17 +200,25 @@ def read_json(file, output_type="Figure", skip_invalid=False):
177
200
Figure or FigureWidget
178
201
"""
179
202
180
- # Check if file is a string
203
+ # Try to cast ` file` as a pathlib object `path`.
181
204
# -------------------------
182
- # If it's a string we assume it's a local file path. If it's not a string
183
- # then we assume it's a read-able Python object
205
+ # ----------------------------------------------
184
206
file_is_str = isinstance (file , string_types )
207
+ if isinstance (file , string_types ):
208
+ # Use the standard Path constructor to make a pathlib object.
209
+ path = Path (file )
210
+ elif isinstance (file , Path ):
211
+ # `file` is already a Path object.
212
+ path = file
213
+ else :
214
+ # We could not make a Path object out of file. Either `file` is an open file
215
+ # descriptor with a `write()` method or it's an invalid object.
216
+ path = None
185
217
186
218
# Read file contents into JSON string
187
219
# -----------------------------------
188
- if file_is_str :
189
- with open (file , "r" ) as f :
190
- json_str = f .read ()
220
+ if path is not None :
221
+ json_str = path .read_text ()
191
222
else :
192
223
json_str = file .read ()
193
224
0 commit comments