attrs
attrs copied to clipboard
Store attribute name used in __init__ parameters
It has come up a couple times recently that I wanted to automatically build an instance of an attrs class. The latest is to just fill it with True and then use as a filter for other instances of the class. For this it would be nice to be able to get the name of a parameter for an attribute in the __init__() signature. I understand that at present the rules for attribute-name -> init-name are pretty simple but it seems reasonable to not force code outside attrs to be aware of it. I would think either attr.init_name(cls, name) or Attribute.init_name could resolve this issue. In my couple cases I would have used the latter though the former is more general and doesn't require a class to be present. But... the former also presumes a totally constant rule which imposes some amount of limitation on flexibility of the translation.
Anyways, I think Attribute.init_name should be easy to add and should cover a vast majority of uses.
I'm happy to make up a PR if this is or might be of interest.
https://github.com/python-attrs/attrs/blob/8824dc26c219abcb43564dd9386fe1a88f938344/src/attr/_make.py#L1681-L1693
Since we'll be releasing the field transformation code in the next release, I think this should go in before it gets more complicated. Are you still interested in it?
@sscherfke this seems like something that should be of your interest too?
Hm. I never thought of this before, because usually attr name == init name is True.
I also can’t think of a concrete use case for which you’d need a mapping between field name and init arg-name. 🤔 @altendky could you please provide a concrete example for this?
I don't remember the details to make it more concrete than in the OP, sorry. That said, being able to construct a class instance without explicitly writing out the parameters seems to not be a big request here. :] Of course, the flip side is that the most interested person here (me) doesn't have a concrete example at present.
If a PR is wanted, I can try to fit that in. I'm figuring that just Attribute.init_name would be the bit to add. attr.ib(init=False) would give None? Or would we need some more specific sentinel to cover some corner case.
This came up again in #python. Present interest is to be able to have x: int act as x: int = attr.ib(converter=int). Having the __init__ name would allow this to be implemented by a custom decorator that applies @attr.s and then takes the resulting class and attr.make_class to create a secondary class with the converter automatically set. Yes, there could also be a feature addition to attrs for @attr.s(type_hint_as_converter) in this case but not everything that people want to do like this belongs in attrs.
You can already do this with the field_transformer attribute of attr.s(). There are no transformers for auto-converters bundled with attrs yet, but I have a prototype implemented in Typed Settings: https://gitlab.com/sscherfke/typed-settings/-/blob/main/src/typed_settings/attrs/init.py#L41
Thanks. I clearly need to read up on field transformers and learn this 'new' feature.
To be fair, that feature is not 'new' but new. :D