22
33from six import string_types
44import json
5-
5+ from pathlib import Path
66
77from plotly .io ._utils import validate_coerce_fig_to_dict , validate_coerce_output_type
88
@@ -68,7 +68,7 @@ def write_json(fig, file, validate=True, pretty=False, remove_uids=True):
6868
6969 file: str or writeable
7070 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)
7272
7373 pretty: bool (default False)
7474 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):
8787 # Pass through validate argument and let to_json handle validation logic
8888 json_str = to_json (fig , validate = validate , pretty = pretty , remove_uids = remove_uids )
8989
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
93102
94103 # Open file
95104 # ---------
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+ )
99120 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 )
101124
102125
103126def from_json (value , output_type = "Figure" , skip_invalid = False ):
@@ -162,7 +185,7 @@ def read_json(file, output_type="Figure", skip_invalid=False):
162185 ----------
163186 file: str or readable
164187 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)
166189
167190 output_type: type or str (default 'Figure')
168191 The output figure type or type name.
@@ -177,17 +200,25 @@ def read_json(file, output_type="Figure", skip_invalid=False):
177200 Figure or FigureWidget
178201 """
179202
180- # Check if file is a string
203+ # Try to cast ` file` as a pathlib object `path`.
181204 # -------------------------
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+ # ----------------------------------------------
184206 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
185217
186218 # Read file contents into JSON string
187219 # -----------------------------------
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 ()
191222 else :
192223 json_str = file .read ()
193224
0 commit comments