turbo_broccoli.custom.external
External data. Embeds data from another file (decodable using
turbo_broccoli.native.load
) into a JSON document. The data is wrapped in a
ExternalData
objects. Note that the path of a ExternalData
is relative to
the path of the JSON file containing it. Therefore, it is not possible to
serialize/deserialize a ExternalData
object without a context that points to
an actual JSON file.
Warning:
The data is read-only. Modifying ExternalData.data
will not affect the
data file.
1""" 2External data. Embeds data from another file (decodable using 3`turbo_broccoli.native.load`) into a JSON document. The data is wrapped in a 4`ExternalData` objects. Note that the path of a `ExternalData` is relative to 5the path of the JSON file containing it. Therefore, it is not possible to 6serialize/deserialize a `ExternalData` object without a context that points to 7an actual JSON file. 8 9Warning: 10 The data is read-only. Modifying `ExternalData.data` will not affect the 11 data file. 12""" 13 14from pathlib import Path 15from typing import Any 16 17from ..context import Context 18from ..exceptions import DeserializationError, TypeNotSupported 19 20 21class ExternalData: 22 """Encapsulate the data of a file""" 23 24 path: Path 25 data: Any 26 27 def __init__(self, path: Path | str, ctx: Context) -> None: 28 """ 29 Args: 30 path (Path | str): Path of the data file. Either absolute or 31 relative to `ctx.file_path` 32 ctx (Context): 33 """ 34 from turbo_broccoli.native import load as native_load 35 36 if ctx.file_path is None: 37 raise ValueError("Context must have a file path") 38 path = Path(path) if isinstance(path, str) else path 39 if path.is_absolute(): 40 self.path = Path(path).relative_to(ctx.file_path.parent.absolute()) 41 else: 42 self.path = path 43 self.data = native_load(ctx.file_path.parent / self.path) 44 45 46def _json_to_externaldata(dct: dict, ctx: Context) -> ExternalData: 47 decoders = { 48 1: _json_to_externaldata_v1, 49 2: _json_to_externaldata_v2, 50 } 51 return decoders[dct["__version__"]](dct, ctx) 52 53 54def _json_to_externaldata_v1(dct: dict, ctx: Context) -> ExternalData: 55 return ExternalData(dct["path"], ctx) 56 57 58def _json_to_externaldata_v2(dct: dict, ctx: Context) -> ExternalData: 59 ctx.raise_if_nodecode("pathlib.path") 60 return ExternalData(dct["path"], ctx) 61 62 63def from_json(dct: dict, ctx: Context) -> ExternalData: 64 decoders = { 65 "external": _json_to_externaldata, 66 } 67 try: 68 type_name = dct["__type__"] 69 return decoders[type_name](dct, ctx) 70 except KeyError as exc: 71 raise DeserializationError() from exc 72 73 74def to_json(obj: Any, ctx: Context) -> dict: 75 """ 76 Serializes an `ExternalData` object into JSON. The return dict has the 77 following structure 78 79 ```py 80 { 81 "__type__": "external", 82 "__version__": 2, 83 "path": {...}, 84 } 85 ``` 86 87 where `path` is a (serialized) `pathlib.Path` object, and relative to the 88 path of the input/output JSON file. 89 """ 90 if not isinstance(obj, ExternalData): 91 raise TypeNotSupported() 92 return {"__type__": "external", "__version__": 2, "path": obj.path}
22class ExternalData: 23 """Encapsulate the data of a file""" 24 25 path: Path 26 data: Any 27 28 def __init__(self, path: Path | str, ctx: Context) -> None: 29 """ 30 Args: 31 path (Path | str): Path of the data file. Either absolute or 32 relative to `ctx.file_path` 33 ctx (Context): 34 """ 35 from turbo_broccoli.native import load as native_load 36 37 if ctx.file_path is None: 38 raise ValueError("Context must have a file path") 39 path = Path(path) if isinstance(path, str) else path 40 if path.is_absolute(): 41 self.path = Path(path).relative_to(ctx.file_path.parent.absolute()) 42 else: 43 self.path = path 44 self.data = native_load(ctx.file_path.parent / self.path)
Encapsulate the data of a file
28 def __init__(self, path: Path | str, ctx: Context) -> None: 29 """ 30 Args: 31 path (Path | str): Path of the data file. Either absolute or 32 relative to `ctx.file_path` 33 ctx (Context): 34 """ 35 from turbo_broccoli.native import load as native_load 36 37 if ctx.file_path is None: 38 raise ValueError("Context must have a file path") 39 path = Path(path) if isinstance(path, str) else path 40 if path.is_absolute(): 41 self.path = Path(path).relative_to(ctx.file_path.parent.absolute()) 42 else: 43 self.path = path 44 self.data = native_load(ctx.file_path.parent / self.path)
Args:
path (Path | str): Path of the data file. Either absolute or
relative to ctx.file_path
ctx (Context):
75def to_json(obj: Any, ctx: Context) -> dict: 76 """ 77 Serializes an `ExternalData` object into JSON. The return dict has the 78 following structure 79 80 ```py 81 { 82 "__type__": "external", 83 "__version__": 2, 84 "path": {...}, 85 } 86 ``` 87 88 where `path` is a (serialized) `pathlib.Path` object, and relative to the 89 path of the input/output JSON file. 90 """ 91 if not isinstance(obj, ExternalData): 92 raise TypeNotSupported() 93 return {"__type__": "external", "__version__": 2, "path": obj.path}
Serializes an ExternalData
object into JSON. The return dict has the
following structure
{
"__type__": "external",
"__version__": 2,
"path": {...},
}
where path
is a (serialized) pathlib.Path
object, and relative to the
path of the input/output JSON file.