python-attrs / attrs

Python Classes Without Boilerplate
https://www.attrs.org/
MIT License
5.27k stars 367 forks source link

Expand allowed types for converters #662

Open stevetarver opened 4 years ago

stevetarver commented 4 years ago

Converters are one-arg functions, some one-arg functions yield type error

Unsupported converter, only named functions and types are currently supported

One of the things I love about attrs is "good engineering practices" baked in - especially typing support for our linters. The current typing omits a couple of use cases:

Global converters are great for global concerns, but more specific concerns should be grouped in the smallest enclosing scope. Given an attrs class with a field that is a nested attrs class, I would love to use a converter on the nested class field that is a static method on that class - only that class knows how to map inbound data to class fields.

Use case: we frequently have a class static method to create an instance from serialized data, e.g. MyClass.from_dict(). I would like to use my_field: MyClass = attrib(converter=MyClass.from_dict).

The second case, class constructor, is useful for single arg constructor classes.

Use case: we use a lot of class StringEnum(str, Enum) derived classes. These are kinda cool because they will yield an enum when passed a str or an Enum. Many simple classes that exist to eliminate string literals, or consolidate global concepts also fit in this category.

What one-arg converters should be prohibited? Not coming up with any except lambdas for the obvious inconsistency and maintenance problems they cause as the proliferate a large code bases.

For clarity: these idioms already work, I just have to # type: ignore each line.

euresti commented 4 years ago

Just FYI this is actually done inside the mypy plugin which lives inside the mypy code base at https://github.com/python/mypy/blob/master/mypy/plugins/attrs.py

I wrote the plugin, and published it there because that was the only place to do it back then, and because I get regression testing for free. Sadly, I don't really have time to implement new features like this and the mypy developers have bigger fish to fry. However, if you can figure out how to make it work I'd be glad to code review.

stevetarver commented 4 years ago

Thanks for the very prompt response. I will add this as an item to my list of dark projects - no idea on time frame, but will take you up on the code review offer.