use init-style reprs on user-creatable classes
We use <class-name attrs=value> style reprs on pretty much every model. For user creatable classes, it would be nice to use class-name(attr=value) style reprs instead, so they can be copied to recreate the object. For some classes, this may result in a lot of values, but they should be included.
This would follow the style outlined by https://docs.python.org/3/reference/datamodel.html#object.__repr
We could go the __repr_attributes__ route for that, just instead of a base class use a decorator.
MVP:
class _HasReprAttributes(Protocol):
__repr_attributes__: ClassVar[tuple[str, ...]]
ReprEnabledT = TypeVar("ReprEnabledT", bound=_HasReprAttributes)
def make_repr(cls: type[ReprEnabledT], /) -> type[ReprEnabledT]:
def __repr__(self: ReprEnabledT) -> str:
attrs = ", ".join(
f"{key.lstrip('_')}={getattr(self, key)!r}" for key in cls.__repr_attributes__
)
return f"{cls.__name__}({attrs})"
cls.__repr__ = __repr__
return cls
What's the use case here? For copying, copy.copy/.deepcopy already works well, I'd say. Additionally, including all fields in the reprs won't work for classes which have a ConnectionState reference, which is most of them.
https://docs.python.org/3/reference/datamodel.html#object.repr
If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment).
including all fields in the reprs won't work for classes which have a
ConnectionStatereference, which is most of them.
@onerandomusername did say "user creatable", which probably implies no state.
No idea which and how many classes is that, though.
Yeah, ones that the user can or should be creating. Things like flags, commands, permissions, intents, install params.
Most of those dataclasses.