22
33from __future__ import annotations
44
5+ import io
56import json
67import plistlib
78from collections .abc import Mapping
1112_T = TypeVar ("_T" , bound = Mapping )
1213
1314
14- def save_and_return_json (data : _T , dst : str | Path | None ) -> _T :
15+ def save_and_return_json (data : _T , dst : str | Path | io . TextIOBase | None ) -> _T :
1516 """Save and return a JSON-serializable data structure."""
1617 if dst is None :
1718 return data
1819
1920 if isinstance (dst , str ):
2021 dst = Path (dst )
2122
22- dst .write_text (json .dumps (data , indent = 4 ))
23+ if isinstance (dst , io .IOBase ):
24+ json .dump (data , dst , indent = 4 )
25+ elif isinstance (dst , Path ):
26+ dst .write_text (json .dumps (data , indent = 4 ))
2327
2428 return data
2529
2630
27- def read_data_json (val : str | Path | _T ) -> _T :
31+ def read_data_json (val : str | Path | io . TextIOBase | io . BufferedIOBase | _T ) -> _T :
2832 """Read JSON data from a file if a path is passed, or return the argument itself."""
2933 if isinstance (val , str ):
3034 val = Path (val )
3135
3236 if isinstance (val , Path ):
3337 val = cast ("_T" , json .loads (val .read_text ()))
3438
39+ if isinstance (val , io .IOBase ):
40+ val = cast ("_T" , json .load (val ))
41+
3542 return val
3643
3744
38- def save_and_return_plist (data : _T , dst : str | Path | None ) -> _T :
45+ def save_and_return_plist (data : _T , dst : str | Path | io . BufferedIOBase | None ) -> _T :
3946 """Save and return a Plist file."""
4047 if dst is None :
4148 return data
4249
4350 if isinstance (dst , str ):
4451 dst = Path (dst )
4552
46- dst .write_bytes (plistlib .dumps (data ))
53+ if isinstance (dst , io .IOBase ):
54+ dst .write (plistlib .dumps (data ))
55+ elif isinstance (dst , Path ):
56+ dst .write_bytes (plistlib .dumps (data ))
4757
4858 return data
4959
5060
51- def read_data_plist (val : str | Path | _T | bytes ) -> _T :
61+ def read_data_plist (val : str | Path | io . BufferedIOBase | _T | bytes ) -> _T :
5262 """Read Plist data from a file if a path is passed, or return the argument itself."""
5363 if isinstance (val , str ):
5464 val = Path (val )
@@ -59,4 +69,7 @@ def read_data_plist(val: str | Path | _T | bytes) -> _T:
5969 if isinstance (val , bytes ):
6070 val = cast ("_T" , plistlib .loads (val ))
6171
72+ if isinstance (val , io .IOBase ):
73+ val = cast ("_T" , plistlib .loads (val .read ()))
74+
6275 return val
0 commit comments