dataspecs package#
- class ID(*segments: str | PathLike[str])[source]#
Bases:
PurePosixPathIdentifier (ID) for data specs.
It is based on
PurePosixPath, however, the differences are an ID must start with the root (/) and thematchmethod full-matches a regular expression.- Parameters:
*segments (str | PathLike[str]) – Path segments to create an ID.
- Raises:
ValueError – Raised if it does not start with the root.
- Return type:
Self
- property children: Self#
Return the regular expression that matches the child IDs.
- property descendants: Self#
Return the regular expression that matches the descendant IDs.
- class Spec(id: ~dataspecs.core.specs.ID, tags: tuple[~dataspecs.core.typing.TagBase, ...], type: ~typing.Any, data: ~dataspecs.core.typing.TAny, meta: tuple[~typing.Any, ...] = <factory>)[source]#
Bases:
Generic[TAny]Data specification (data spec).
- Parameters:
- type: Any#
Type hint for the data of the data spec.
- data: TAny#
Default or final data of the data spec.
- meta: tuple[Any, ...]#
Other metadata of the data spec.
- class Specs(initlist=None)[source]#
Bases:
UserList[TSpec]Data specifications (data specs).
- property first: TSpec | None#
Return the first data spec if it exists (
Noneotherwise).
- property last: TSpec | None#
Return the last data spec if it exists (
Noneotherwise).
- property unique: TSpec | None#
Return the data spec if it is unique (
Noneotherwise).
- replace(old: TSpec, new: TSpec, /) Self[source]#
Return data specs with old data spec replaced by new one.
- Parameters:
old (TSpec)
new (TSpec)
- Return type:
Self
- __getitem__(index: None, /) Self[source]#
- __getitem__(index: TagBase, /) Self
- __getitem__(index: type[Any], /) Self
- __getitem__(index: str | PathLike[str], /) Self
- __getitem__(index: slice, /) Self
- __getitem__(index: SupportsIndex, /) TSpec
Select data specs with given index.
In addition to a normal index (i.e. an object that has
__index__method), it also accepts the following extended index for the advanced selection: (1) a tag to select data specs that contain it, (2) a tag type to select data specs that contain its tags, (3) an any type to select data specs that contain it, (4) a string path to select data specs that match it, or (5)Noneto return all data specs (shallow copy).- Parameters:
index – Normal or extended index for the selection of the data specs.
- Returns:
Selected data specs with given index.
- class TagBase(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]#
Bases:
EnumBase enum of tag for data specs.
Since
TagBaseitself does not have any members, users should create their own tags by inheriting it:from enum import auto from dataspecs import TagBase class Tag(TagBase): ATTR = auto() DATA = auto() NAME = auto()
- from_dataclass(obj: ~dataspecs.core.typing.DataClassObject | type[~dataspecs.core.typing.DataClassObject], /, *, parent_id: str | ~os.PathLike[str] = ID('/'), spec_factory: ~typing.Any = <class 'dataspecs.core.specs.Spec'>) Any[source]#
Create data specs from a dataclass (object).
- Parameters:
obj (DataClassObject | type[DataClassObject]) – Dataclass (object) to be parsed.
parent_id (str | PathLike[str]) – ID of the parent data spec.
spec_factory (Any) – Factory for creating each data spec.
- Returns:
Data specs created from the dataclass (object).
- Return type:
Any
Examples
from enum import auto from dataclasses import dataclass from dataspecs import TagBase, from_dataclass from typing import Annotated as Ann class Tag(TagBase): ATTR = auto() DATA = auto() DTYPE = auto() @dataclass class Weather: temp: Ann[list[Ann[float, Tag.DTYPE]], Tag.DATA] humid: Ann[list[Ann[float, Tag.DTYPE]], Tag.DATA] location: Ann[str, Tag.ATTR] from_dataclass(Weather([20.0, 25.0], [50.0, 55.0], "Tokyo"))
Specs([ Spec( id=ID('/'), tags=(), type=<class '__main__.Weather'>, data=Weather(temp=[20.0, 25.0], humid=[50.0, 55.0], location='Tokyo'), ), Spec( id=ID('/temp'), tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0], ), Spec( id=ID('/temp/0'), tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None, ), Spec( id=ID('/humid'), tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0], ), Spec( id=ID('/humid/0'), tags=(<Tag.DTYPE: 3>,), type=<class 'float'>, data=None, ), Spec( id=ID('/location'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Tokyo', ), ])
- from_typehint(obj: ~typing.Any, /, *, parent_id: str | ~os.PathLike[str] = ID('/'), parent_data: ~typing.Any = None, spec_factory: ~typing.Any = <class 'dataspecs.core.specs.Spec'>) Any[source]#
Create data specs from a type hint.
- Parameters:
obj (Any) – Type hint to be parsed.
parent_id (str | PathLike[str]) – ID of the parent data spec.
parent_data (Any) – Data of the parent data spec.
spec_factory (Any) – Factory for creating each data spec.
- Returns:
Data specs created from the type hint.
- Return type:
Any
Examples
from enum import auto from dataspecs import TagBase, from_typehint from typing import Annotated as Ann class Tag(TagBase): DATA = auto() DTYPE = auto() from_typehint(Ann[list[Ann[float, Tag.DTYPE]], Tag.DATA])
Specs([ Spec( id=ID('/'), tags=(<Tag.DATA: 1>,), type=list[float], data=None, ), Spec( id=ID('/0'), tags=(<Tag.DTYPE: 2>,), type=<class 'float'>, data=None, ), ])
- class Format(id: ~typing.Annotated[str | ~os.PathLike[str], <Tag.ID: 1>], of: ~typing.Annotated[str, <Tag.OF: 2>] = 'data', skipif: ~typing.Annotated[~typing.Any, <Tag.SKIPIF: 3>] = None)[source]#
Bases:
objectAnnotation for formatter specs.
- Parameters:
id (Annotated[str | PathLike[str], <Tag.ID: 1>]) – ID of data spec(s) to be formatted.
of (Annotated[str, <Tag.OF: 2>]) – Name of data spec attribute to be formatted.
skipif (Annotated[Any, <Tag.SKIPIF: 3>]) – Sentinel value for which formatting is skipped.
- id: ID: 1>]#
ID of data spec(s) to be formatted.
- of: OF: 2>] = 'data'#
Name of data spec attribute to be formatted.
- skipif: SKIPIF: 3>] = None#
Sentinel value for which formatting is skipped.
- class Replace(id: ~typing.Annotated[str | ~os.PathLike[str], <Tag.ID: 1>], of: ~typing.Annotated[str, <Tag.OF: 2>] = 'data', skipif: ~typing.Annotated[~typing.Any, <Tag.SKIPIF: 3>] = None)[source]#
Bases:
objectAnnotation for replacer specs.
- Parameters:
id (Annotated[str | PathLike[str], <Tag.ID: 1>]) – ID of data spec(s) to be replaced.
of (Annotated[str, <Tag.OF: 2>]) – Name of data spec attribute to be replaced.
skipif (Annotated[Any, <Tag.SKIPIF: 3>]) – Sentinel value for which replacing is skipped.
- id: ID: 1>]#
ID of data spec(s) to be replaced.
- of: OF: 2>] = 'data'#
Name of data spec attribute to be replaced.
- skipif: SKIPIF: 3>] = None#
Sentinel value for which replacing is skipped.
- format(specs: Specs[TSpec], /) Specs[TSpec][source]#
Format data spec attributes by formatter specs.
- Parameters:
specs (Specs[TSpec]) – Input data specs.
- Returns:
Data specs whose attributes are formatted.
- Return type:
Specs[TSpec]
Examples
from enum import auto from dataclasses import dataclass from dataspecs import TagBase, Format, from_dataclass, format from typing import Annotated as Ann class Tag(TagBase): ATTR = auto() @dataclass class Attrs: name: Ann[str, Tag.ATTR] units: Ann[str, Tag.ATTR] @dataclass class Weather: temp: Ann[list[float], Attrs("Temperature ({0})", "{0}")] units: Ann[str, Format("/temp/attrs/[a-z]+")] = "degC" format(from_dataclass(Weather([20.0, 25.0], "K")))
Specs([ Spec( id=ID('/'), tags=(), type=<class '__main__.Weather'>, data=Weather(temp=[20.0, 25.0], units='K'), ), Spec( id=ID('/temp'), tags=(), type=list[float], data=[20.0, 25.0], ), Spec( id=ID('/temp/0'), tags=(), type=<class 'float'>, data=None, ), Spec( id=ID('/temp/attrs'), tags=(), type=<class '__main__.Attrs'>, data=Attrs(name='Temperature ({0})', units='{0}'), ), Spec( id=ID('/temp/attrs/name'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='Temperature (K)', # <- formatted ), Spec( id=ID('/temp/attrs/units'), tags=(<Tag.ATTR: 1>,), type=<class 'str'>, data='K', # <- formatted ), Spec( id=ID('/units'), tags=(), type=<class 'str'>, data='K', ), Spec( id=ID('/units/format'), tags=(), type=<class 'dataspecs.extras.formatting.Format'>, data=Format(id='/temp/attrs/[a-z]+', of='data', skipif=None), ), Spec( id=ID('/units/format/id'), tags=(<Tag.ID: 1>,), type=<class 'str'>, data='/temp/attrs/[a-z]+', ), Spec( id=ID('/units/format/of'), tags=(<Tag.OF: 2>,), type=<class 'str'>, data='data', ), Spec( id=ID('/units/format/skipif'), tags=(<Tag.SKIPIF: 3>,), type=typing.Any, data=None, ), ])
- replace(specs: Specs[TSpec], /) Specs[TSpec][source]#
Replace data spec attributes by replacer specs.
- Parameters:
specs (Specs[TSpec]) – Input data specs.
- Returns:
Data specs whose attributes are replaced.
- Return type:
Specs[TSpec]
Examples
from enum import auto from dataclasses import dataclass from dataspecs import Replace, TagBase, from_dataclass, replace from typing import Annotated as Ann class Tag(TagBase): ATTR = auto() DATA = auto() DTYPE = auto() @dataclass class Weather: temp: Ann[list[Ann[float, Tag.DTYPE]], Tag.DATA] humid: Ann[list[Ann[float, Tag.DTYPE]], Tag.DATA] dtype: Ann[type, Replace("/[a-z]+/0", "type")] = None replace(from_dataclass(Weather([20.0, 25.0], [50.0, 55.0], int)))
Specs([ Spec( id=ID('/'), tags=(), type=<class '__main__.Weather'>, data=Weather(temp=[20.0, 25.0], humid=[50.0, 55.0], dtype=<class 'int'>), ), Spec( id=ID('/temp'), tags=(<Tag.DATA: 2>,), type=list[float], data=[20.0, 25.0], ), Spec( id=ID('/temp/0'), tags=(<Tag.DTYPE: 3>,), type=<class 'int'>, # <- replaced data=None, ), Spec( id=ID('/humid'), tags=(<Tag.DATA: 2>,), type=list[float], data=[50.0, 55.0], ), Spec( id=ID('/humid/0'), tags=(<Tag.DTYPE: 3>,), type=<class 'int'>, # <- replaced data=None, ), Spec( id=ID('/dtype'), tags=(), type=<class 'type'>, data=<class 'int'>, ), Spec( id=ID('/dtype/replace'), tags=(), type=<class 'dataspecs.extras.replacing.Replace'>, data=Replace(id='/[a-z]+/0', of='type', skipif=None), ), Spec( id=ID('/dtype/replace/id'), tags=(<Tag.ID: 1>,), type=<class 'str'>, data='/(temp|humid)/0', ), Spec( id=ID('/dtype/replace/of'), tags=(<Tag.OF: 2>,), type=<class 'str'>, data='type', ), Spec( id=ID('/dtype/replace/skipif'), tags=(<Tag.SKIPIF: 3>,), type=typing.Any, data=None, ), ])