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}
class ExternalData:
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

ExternalData(path: pathlib.Path | str, ctx: turbo_broccoli.context.Context)
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):

path: pathlib.Path
data: Any
def from_json( dct: dict, ctx: turbo_broccoli.context.Context) -> ExternalData:
64def from_json(dct: dict, ctx: Context) -> ExternalData:
65    decoders = {
66        "external": _json_to_externaldata,
67    }
68    try:
69        type_name = dct["__type__"]
70        return decoders[type_name](dct, ctx)
71    except KeyError as exc:
72        raise DeserializationError() from exc
def to_json(obj: Any, ctx: turbo_broccoli.context.Context) -> dict:
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.