hikari icon indicating copy to clipboard operation
hikari copied to clipboard

Get rid of properties in builders

Open ashleney opened this issue 4 years ago • 4 comments

Summary

Builders should be remade to not use properties and instead they should just accept direct mutation using their attributes. Setters or properties which are not directly built may remain but they shouldn't be the main way to use the builder.

Why is this needed?

Currently, you are required to use long builders using fairly unpythonic setters instead of just being able to set everything in the __init__. Normally this would've been possible thanks to attrs but since the properties are prefixed with underscores pyright cannot understand that attrs is fine with the underscores being left out.

Ideal implementation

# before
class SomeBuilder:
    _whatever: module.SomeEnum

    _something: int = attr.field(kw_only=True)
    _other: str = attr.field(kw_only=True)

    @property
    def whatever(self) -> module.SomeEnum:
        return self._whatever
    # <repeated for all other fields>

    def set_whatever(self: T, x: Union[int, module.SomeEnum]) -> T:
        self._whatever = module.SomeEnum(x)
        return self
    # <repeated for all other fields>
# after
class SomeBuilder:
    whatever: module.SomeEnum

    something: int = attr.field(kw_only=True)
    other: str = attr.field(kw_only=True)

    def set_whatever(self: T, x: Union[int, module.SomeEnum]) -> T:
        self.whatever = module.SomeEnum(x)
        return self
    # <repeated for all other fields>

Checklist

  • [X] I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

ashleney avatar Dec 13 '21 09:12 ashleney

Hmm, I agree with this.

ahnaf-zamil avatar Jan 24 '22 02:01 ahnaf-zamil

Builders should be remade to not use properties and instead they should just accept direct mutation using their attributes.

This would prevent the library from adding validation to setting calls in the future which isn't ideal seeing as the rest flow needs a lot of validation.

Also how the data is stored internally is impl detail, this pattern you're suggesting would make the internal storage a part of the interface which would change the nature of builders such as the button builder.

FasterSpeeding avatar Jan 24 '22 03:01 FasterSpeeding

Normally this would've been possible thanks to attrs but since the properties are prefixed with underscores pyright cannot understand that attrs is fine with the underscores being left out.

That's a pyright/attrs issue and not in scope of this project, you shouldn't let a type checker stop you from doing stuff just because its wrong. You can just pass data to the init if you want to avoid any validation or don't want to use setters

FasterSpeeding avatar Jan 24 '22 03:01 FasterSpeeding

Makes sense. I suppose we should get rid of all the init=False then at least.

ashleney avatar Feb 04 '22 11:02 ashleney