attrs icon indicating copy to clipboard operation
attrs copied to clipboard

Store attribute name used in __init__ parameters

Open altendky opened this issue 6 years ago • 8 comments

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

altendky avatar Sep 10 '19 15:09 altendky

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?

hynek avatar Oct 19 '20 06:10 hynek

@sscherfke this seems like something that should be of your interest too?

hynek avatar Oct 19 '20 08:10 hynek

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?

sscherfke avatar Oct 19 '20 09:10 sscherfke

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.

altendky avatar Oct 19 '20 13:10 altendky

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.

altendky avatar Dec 05 '20 15:12 altendky

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

sscherfke avatar Dec 05 '20 16:12 sscherfke

Thanks. I clearly need to read up on field transformers and learn this 'new' feature.

altendky avatar Dec 05 '20 16:12 altendky

To be fair, that feature is not 'new' but new. :D

hynek avatar Dec 13 '20 06:12 hynek