Skip to main content

Properties for dataclass fields

Project description

field-properties

Properties for dataclass fields

Example

from dataclasses import dataclass

from field_properties import field_property, unwrap_property


@dataclass(frozen=True)
class Foo:
    bar: int = field_property(default=0)  # Same parameter than dataclasses.field

    @field_property(bar)  # Equivalent to @field_property(bar).getter
    def get_bar(self) -> int:
        # unwrap_property(self).bar is equivalent to self._bar
        # but it's type-checked and linter-friendly
        return unwrap_property(self).bar

    # When not declared, getter, setter and deleter are generated like the following:
    # @field_property(bar).setter
    # def set_bar(self, value: int):
    #     unwrap_property(self).bar = value


assert repr(Foo()) == repr(Foo(0)) == "Foo(bar=0)"

How does it works?

When a dataclass field has a default value, this value is assigned as a class attribute. field_property use this mechanism and create a field with a property as default value.

If a default value/factory is registered with field_property, the property setter will be called with it in __init__.

Default getter/setter/deleter

field_property generates default getter/setter/deleter as simple wrappers around an instance attribute whose name is the field name prefixed with an underscore _. unwrap_property allows accessing this attribute in a type-checked/linter-friendly way.

By the way, if all the getter/setter/deleter are declared (and thus not generated), the protected attribute will not be created.

Overriding

Field properties can be overridden, but the dataclass field must be overridden too — this is because a new field must be created, as property is declared as its default value (see previous section).

from dataclasses import dataclass

from field_properties import field_property, unwrap_property


@dataclass
class Foo:
    bar: int = field_property(default=0)

    @field_property(bar)
    def get_bar(self):
        return unwrap_property(self).bar + 1

class Foo2(Foo):
    bar: int = field_property(default=0)  # field property must be overridden
    # field_property(inherit=True) is a shortcut to override a field
    # and reusing all it's arguments

    @field_property(bar)
    def get_bar(self):
        return unwrap_property(self).bar + 2


assert Foo() == 1
assert Foo2() == 2

In fact, because field is redeclared, it's also possible to override normal fields with a field property

from dataclasses import dataclass

from field_properties import field_property


@dataclass
class Foo:
    bar: int = 0

class Foo2(Foo):
    bar: int = field_property(default=1)

assert Foo2() == 1

Raw property

field_property comes with a default implementation for its getter/setter/deleter. This can be turned off with raw=False parameter. Here is an example of a read_only field:

from dataclasses import dataclass
from field_properties import field_property

@dataclass
class Foo:
    bar: int = field_property(init=False, raw=True)

    @field_property(bar)
    def get_bar(self) -> int:
        return 0

assert Foo().bar == 0
assert str(Foo()) == "Foo(bar=0)"
try:
    Foo().bar = 1
except AttributeError:
    assert True
else:
    assert False

PEP 614

Decorator syntax @field_property(bar).setter is only valid in Python 3.9. Previous version can use the following hack:

from dataclasses import dataclass

from field_properties import field_property


@dataclass
class Foo:
    bar: int = field_property()

    def set_bar(self, value: int):
        ...
    field_property(bar).setter(set_bar)

Project details


Release history Release notifications | RSS feed

This version

0.1

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

field-properties-0.1.tar.gz (5.3 kB view hashes)

Uploaded Source

Built Distribution

field_properties-0.1-py3-none-any.whl (6.5 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page