-
-
Notifications
You must be signed in to change notification settings - Fork 373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow converter.optional to take a Converter such as converter.pipe as its argument #1372
base: main
Are you sure you want to change the base?
Conversation
2c43211
to
9b22892
Compare
def optional_converter(val, inst, field): | ||
if val is None: | ||
return None | ||
return converter(val, inst, field) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not guaranteed that the converter takes 3 arguments.
The root issue is that earlier versions of attrs had a "basic" converter that just took a single val
. But now with the Converter
class, Converter
callables may take one, two (self), two(field), or three parameters.
Some introspection here may be necessary.
Also, since converters now may be callables with one two or three params, the type signature ought to be updated as well
https://github.com/python-attrs/attrs/blob/main/src/attrs/__init__.pyi#L54
Something like Callable[[Any], Any] | Callable[[Any, Any], Any] | Callable[[Any, Any, Any], Any]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually a Converter
instance always takes three arguments:
Lines 2712 to 2725 in 13e9a6a
if not (self.takes_self or self.takes_field): | |
self.__call__ = lambda value, _, __: self.converter(value) | |
elif self.takes_self and not self.takes_field: | |
self.__call__ = lambda value, instance, __: self.converter( | |
value, instance | |
) | |
elif not self.takes_self and self.takes_field: | |
self.__call__ = lambda value, __, field: self.converter( | |
value, field | |
) | |
else: | |
self.__call__ = lambda value, instance, field: self.converter( | |
value, instance, field | |
) |
The callable it takes as an argument can take one, two or three, but the Converter
class normalizes it to always take three arguments
So I believe this is correct
I think the typing information might need an update, to accept Callable[[Any], Any] | Converter
but I think that's a separate issue so maybe we should follow up on that on a separate PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for starting on a fix!
The constructor consumes __annotations__, so move the constructor call to after those have been set on the optional_converter function
Summary
Allow
converter.optional
to take a Converter such asconverter.pipe
as its argument.Fixes #1348
Pull Request Check List
main
branch – use a separate branch!Our CI fails if coverage is not 100%.
.pyi
)..rst
and.md
files is written using semantic newlines.changelog.d
.