Skip to content

pane.field

pane.field

RenameStyle = t.Literal['snake', 'camel', 'pascal', 'kebab', 'scream'] module-attribute

List of supported field-renaming styles

Field dataclass

Represents a materialized dataclass field.

Typically instantiated from a FieldSpec.

Source code in pane/field.py
@dataclasses.dataclass
class Field:
    """
    Represents a materialized dataclass field.

    Typically instantiated from a [`FieldSpec`][pane.field.FieldSpec].
    """

    _: KW_ONLY = dataclasses.field(init=False, repr=False, compare=False)
    name: str
    """Name of field"""
    type: t.Any
    """Type of field. Must be [`Convertible`][pane.convert.Convertible]."""
    in_names: t.Sequence[str]
    """List of names which convert to this field."""
    out_name: str
    """Name this field converts into."""
    init: bool = True
    """Whether to add this field to __init__ methods (and conversion from other types)"""
    exclude: bool = False
    """Whether to exclude this field when converting to other types"""
    repr: bool = True
    """Whether to include this field in __repr__"""
    hash: bool = True
    """Whether to include this field in the generated __hash__ method"""
    compare: bool = True
    """Whether to include this field in generated comparison methods (__eq__, __gt__, etc.)"""
    default: t.Union[t.Any, _Missing] = _MISSING
    """Default value for field"""
    default_factory: t.Optional[t.Callable[[], t.Any]] = None
    """Default value factory for field"""
    kw_only: bool = False
    """Whether field is keyword only"""
    converter: t.Optional[Converter[t.Any]] = None
    """Custom converter to use for this field."""

    @classmethod
    def make(cls, name: str, ty: type,
             in_rename: t.Optional[t.Sequence[RenameStyle]] = None,
             out_rename: t.Optional[RenameStyle] = None) -> Field:
        in_names = tuple(rename_field(name, style) for style in in_rename) if in_rename is not None else (name,)
        out_name = rename_field(name, out_rename) if out_rename is not None else name
        return cls(name=name, type=ty, in_names=in_names, out_name=out_name)

    def has_default(self) -> bool:
        """Return whether this field has a default value"""
        return self.default is not _MISSING or self.default_factory is not None

name instance-attribute

Name of field

type instance-attribute

Type of field. Must be Convertible.

in_names instance-attribute

List of names which convert to this field.

out_name instance-attribute

Name this field converts into.

init = True class-attribute instance-attribute

Whether to add this field to init methods (and conversion from other types)

exclude = False class-attribute instance-attribute

Whether to exclude this field when converting to other types

repr = True class-attribute instance-attribute

Whether to include this field in repr

hash = True class-attribute instance-attribute

Whether to include this field in the generated hash method

compare = True class-attribute instance-attribute

Whether to include this field in generated comparison methods (eq, gt, etc.)

default = _MISSING class-attribute instance-attribute

Default value for field

default_factory = None class-attribute instance-attribute

Default value factory for field

kw_only = False class-attribute instance-attribute

Whether field is keyword only

converter = None class-attribute instance-attribute

Custom converter to use for this field.

make(name, ty, in_rename=None, out_rename=None) classmethod

Source code in pane/field.py
@classmethod
def make(cls, name: str, ty: type,
         in_rename: t.Optional[t.Sequence[RenameStyle]] = None,
         out_rename: t.Optional[RenameStyle] = None) -> Field:
    in_names = tuple(rename_field(name, style) for style in in_rename) if in_rename is not None else (name,)
    out_name = rename_field(name, out_rename) if out_rename is not None else name
    return cls(name=name, type=ty, in_names=in_names, out_name=out_name)

has_default()

Return whether this field has a default value

Source code in pane/field.py
def has_default(self) -> bool:
    """Return whether this field has a default value"""
    return self.default is not _MISSING or self.default_factory is not None

FieldSpec dataclass

Represents a field specification.

This hasn't been applied to a class yet, so some information is missing.

In most cases, end users should use the field() function instead.

Source code in pane/field.py
@dataclasses.dataclass
class FieldSpec:
    """
    Represents a field specification.

    This hasn't been applied to a class yet, so some information is missing.

    In most cases, end users should use the [`field()`][pane.field.field] function instead.
    """

    _: KW_ONLY = dataclasses.field(init=False, repr=False, compare=False)
    rename: t.Optional[str] = None
    """Rename this field. Affects both `in_names` and `out_name`."""
    in_names: t.Optional[t.Sequence[str]] = None
    """Complete list of names which convert to this field."""
    aliases: t.Optional[t.Sequence[str]] = None
    """Additional list of names which convert to this field (excluding the name in Python)."""
    out_name: t.Optional[str] = None
    """Name this field converts into."""
    init: bool = True
    """Whether to add this field to __init__ methods (and conversion from other types)"""
    exclude: bool = False
    """Whether to exclude this field when converting to other types"""
    repr: bool = True
    """Whether to include this field in __repr__"""
    hash: bool = True
    """Whether to include this field in the generated __hash__ method."""
    compare: bool = True
    """Whether to include this field in generated comparison methods (__eq__, __gt__, etc.)"""
    default: t.Union[t.Any, _Missing] = _MISSING
    """Default value for field"""
    default_factory: t.Optional[t.Callable[[], t.Any]] = None
    """Default value factory for field"""
    kw_only: bool = False
    """Whether field is keyword only"""
    ty: t.Union[t.Any, _Missing] = _MISSING
    """Type of field, if known. Must be Convertible."""
    converter: t.Optional[Converter[t.Any]] = None
    """Custom converter to use for this field."""

    def __post_init__(self):
        if isinstance(self.aliases, str):
            self.aliases = [self.aliases]

    def replace_typevars(self, replacements: t.Mapping[t.Union[t.TypeVar, ParamSpec], t.Type[t.Any]]) -> Self:
        """
        Apply type variable replacements to `self`.
        """
        if self.ty is _MISSING:
            return dataclasses.replace(self)
        return dataclasses.replace(self, ty=replace_typevars(t.cast(type, self.ty), replacements))

    def make_field(self, name: str,
                   in_rename: t.Optional[t.Sequence[RenameStyle]] = None,
                   out_rename: t.Optional[RenameStyle] = None) -> Field:
        """
        Make a [`Field`][pane.field.Field] from this [`FieldSpec`][pane.field.FieldSpec].
        """
        # out_name
        if self.out_name is not None:
            out_name = self.out_name
        elif self.rename is not None:
            out_name = self.rename
        else:
            out_name = rename_field(name, out_rename) if out_rename is not None else name

        if sum(p is not None for p in (self.rename, self.aliases, self.in_names)) > 1:
            raise TypeError("Can only specify one of 'rename', 'aliases', and 'in_names'")

        if self.rename is not None:
            in_names = (self.rename,)
        elif self.aliases is not None:
            in_names = (name, *(alias for alias in self.aliases if alias != name))
        elif self.in_names is not None:
            in_names = self.in_names
        else:
            in_names = tuple(rename_field(name, style) for style in in_rename) if in_rename is not None else (name,)

        ty = t.cast(type, t.Any if self.ty is _MISSING else self.ty)
        return Field(
            name=name, type=ty, out_name=out_name, in_names=in_names, init=self.init, exclude=self.exclude,
            repr=self.repr, hash=self.hash, compare=self.compare,
            default=self.default, default_factory=self.default_factory,
            kw_only=self.kw_only, converter=self.converter
        )

rename = None class-attribute instance-attribute

Rename this field. Affects both in_names and out_name.

in_names = None class-attribute instance-attribute

Complete list of names which convert to this field.

aliases = None class-attribute instance-attribute

Additional list of names which convert to this field (excluding the name in Python).

out_name = None class-attribute instance-attribute

Name this field converts into.

init = True class-attribute instance-attribute

Whether to add this field to init methods (and conversion from other types)

exclude = False class-attribute instance-attribute

Whether to exclude this field when converting to other types

repr = True class-attribute instance-attribute

Whether to include this field in repr

hash = True class-attribute instance-attribute

Whether to include this field in the generated hash method.

compare = True class-attribute instance-attribute

Whether to include this field in generated comparison methods (eq, gt, etc.)

default = _MISSING class-attribute instance-attribute

Default value for field

default_factory = None class-attribute instance-attribute

Default value factory for field

kw_only = False class-attribute instance-attribute

Whether field is keyword only

ty = _MISSING class-attribute instance-attribute

Type of field, if known. Must be Convertible.

converter = None class-attribute instance-attribute

Custom converter to use for this field.

replace_typevars(replacements)

Apply type variable replacements to self.

Source code in pane/field.py
def replace_typevars(self, replacements: t.Mapping[t.Union[t.TypeVar, ParamSpec], t.Type[t.Any]]) -> Self:
    """
    Apply type variable replacements to `self`.
    """
    if self.ty is _MISSING:
        return dataclasses.replace(self)
    return dataclasses.replace(self, ty=replace_typevars(t.cast(type, self.ty), replacements))

make_field(name, in_rename=None, out_rename=None)

Make a Field from this FieldSpec.

Source code in pane/field.py
def make_field(self, name: str,
               in_rename: t.Optional[t.Sequence[RenameStyle]] = None,
               out_rename: t.Optional[RenameStyle] = None) -> Field:
    """
    Make a [`Field`][pane.field.Field] from this [`FieldSpec`][pane.field.FieldSpec].
    """
    # out_name
    if self.out_name is not None:
        out_name = self.out_name
    elif self.rename is not None:
        out_name = self.rename
    else:
        out_name = rename_field(name, out_rename) if out_rename is not None else name

    if sum(p is not None for p in (self.rename, self.aliases, self.in_names)) > 1:
        raise TypeError("Can only specify one of 'rename', 'aliases', and 'in_names'")

    if self.rename is not None:
        in_names = (self.rename,)
    elif self.aliases is not None:
        in_names = (name, *(alias for alias in self.aliases if alias != name))
    elif self.in_names is not None:
        in_names = self.in_names
    else:
        in_names = tuple(rename_field(name, style) for style in in_rename) if in_rename is not None else (name,)

    ty = t.cast(type, t.Any if self.ty is _MISSING else self.ty)
    return Field(
        name=name, type=ty, out_name=out_name, in_names=in_names, init=self.init, exclude=self.exclude,
        repr=self.repr, hash=self.hash, compare=self.compare,
        default=self.default, default_factory=self.default_factory,
        kw_only=self.kw_only, converter=self.converter
    )

rename_field(field, style=None)

Rename field to match style style.

Parameters:

Name Type Description Default
field str

Field name to rename

required
style Optional[RenameStyle]

Style to match

None
Source code in pane/field.py
def rename_field(field: str, style: t.Optional[RenameStyle] = None) -> str:
    """
    Rename `field` to match style `style`.

    Parameters:
        field: Field name to rename
        style: Style to match
    """
    if style is None:
        return field

    return _CONVERT_FNS[style](_split_field_name(field))

field(*, rename=None, in_names=None, aliases=None, out_name=None, init=True, exclude=False, repr=True, hash=None, compare=True, default=_MISSING, default_factory=None, kw_only=False, converter=None)

field(*, rename: t.Optional[str] = None, in_names: None = None, aliases: None = None, out_name: t.Optional[str] = None, init: bool = True, exclude: bool = False, repr: bool = True, hash: t.Optional[bool] = None, compare: bool = True, default: t.Union[T, _Missing] = _MISSING, default_factory: t.Optional[t.Callable[[], T]] = None, kw_only: bool = False, converter: t.Optional[Converter[T]] = None) -> t.Any
field(*, rename: None = None, in_names: t.Sequence[str], aliases: None = None, out_name: t.Optional[str] = None, init: bool = True, exclude: bool = False, repr: bool = True, hash: t.Optional[bool] = None, compare: bool = True, default: t.Union[T, _Missing] = _MISSING, default_factory: t.Optional[t.Callable[[], T]] = None, kw_only: bool = False, converter: t.Optional[Converter[T]] = None) -> t.Any
field(*, rename: None = None, in_names: None = None, aliases: t.Sequence[str], out_name: t.Optional[str] = None, init: bool = True, exclude: bool = False, repr: bool = True, hash: t.Optional[bool] = None, compare: bool = True, default: t.Union[T, _Missing] = _MISSING, default_factory: t.Optional[t.Callable[[], T]] = None, kw_only: bool = False, converter: t.Optional[Converter[T]] = None) -> t.Any
field(*, rename: t.Optional[str] = None, in_names: t.Optional[t.Sequence[str]] = None, aliases: t.Optional[t.Sequence[str]] = None, out_name: t.Optional[str] = None, init: bool = True, exclude: bool = False, repr: bool = True, hash: t.Optional[bool] = None, compare: bool = True, default: t.Union[T, _Missing] = _MISSING, default_factory: t.Optional[t.Callable[[], T]] = None, kw_only: bool = False, converter: t.Optional[Converter[T]] = None) -> t.Any

Annotate a dataclass field.

Parameters:

Name Type Description Default
rename Optional[str]

Name to rename this field as. Used for both input and output. Useful when a field name should be different inside vs. outside of Python.

None
in_names Optional[Sequence[str]]

List of names which should convert into this field. If specified, the field name inside Python will be excluded (unlike aliases).

None
aliases Optional[Sequence[str]]

List of aliases (additional names) for this field. Includes the field name inside Python (unlike in_names).

None
out_name Optional[str]

Name which this field should convert into.

None
init bool

If False, this field won't be touched by pane, and it's up to the class to initialize it in __post_init__.

True
exclude bool

If False, this field is excluded from serialization and conversion to other datatypes (into_data, dict, write_json, etc.).

False
repr bool

Whether to include this field in the generated repr method.

True
hash Optional[bool]

Whether to include this field in the generated hash method. Defaults to compare.

None
compare bool

Whether to include this field in generated comparison methods (__eq__, __gt__, etc.).

True
default Union[T, _Missing]

Default value for field

_MISSING
default_factory Optional[Callable[[], T]]

Default value factory for field

None
kw_only bool

Whether the field is keyword-only.

False
Source code in pane/field.py
def field(*,
    rename: t.Optional[str] = None,
    in_names: t.Optional[t.Sequence[str]] = None,
    aliases: t.Optional[t.Sequence[str]] = None,
    out_name: t.Optional[str] = None,
    init: bool = True,
    exclude: bool = False,
    repr: bool = True,
    hash: t.Optional[bool] = None,
    compare: bool = True,
    default: t.Union[T, _Missing] = _MISSING,
    default_factory: t.Optional[t.Callable[[], T]] = None,
    kw_only: bool = False,
    converter: t.Optional[Converter[T]] = None,
) -> t.Any:
    """
    Annotate a dataclass field.

    Parameters:
      rename: Name to rename this field as. Used for both input and output. Useful when a field name should be different inside vs. outside of Python.
      in_names: List of names which should convert into this field. If specified, the field name inside Python will be excluded (unlike `aliases`).
      aliases: List of aliases (additional names) for this field. Includes the field name inside Python (unlike `in_names`).
      out_name: Name which this field should convert into.
      init: If `False`, this field won't be touched by `pane`, and it's up to the class to initialize it in `__post_init__`.
      exclude: If `False`, this field is excluded from serialization and conversion to other datatypes (into_data, dict, write_json, etc.).
      repr: Whether to include this field in the generated __repr__ method.
      hash: Whether to include this field in the generated __hash__ method. Defaults to `compare`.
      compare: Whether to include this field in generated comparison methods (`__eq__`, `__gt__`, etc.).
      default: Default value for field
      default_factory: Default value factory for field
      kw_only: Whether the field is keyword-only.
    """
    return FieldSpec(
        rename=rename, in_names=in_names, aliases=aliases, out_name=out_name,
        init=init, repr=repr, hash=hash if hash is not None else compare, compare=compare,
        exclude=exclude, default=default, default_factory=default_factory,
        kw_only=kw_only, converter=converter
    )