add_attribute_function: bind function to OpenAPIConverter instance#498
add_attribute_function: bind function to OpenAPIConverter instance#498
Conversation
|
Alternatives:
class FieldConverterMixin:
def field2property(self, field):
ret = {}
for attr_func in self.attribute_functions:
ret.update(attr_func(field, openapi_converter=self, ret=ret))
return ret
@staticmethod
def field2type_and_format(field, openapi_converter, **kwargs):
[...]
@staticmethod
def field2default(field, **kwargs):
[...]
def my_custom_funct(field, openapi_converter, **kwargs):
[...]
converter.add_attribute_function(my_custom_funct)This way, all signatures are the same. I'm not sure which interface is the best. But current interface looks awkward to me. |
|
This works for me. I agree that the current interface is awkward and it's better to have a consistent interface. Currently three field types, (Nested, List, and Dict) require access to self. I image that at least some of the custom fields would require it as well. |
|
Yes, and one could also add custom methods not only for custom fields but for custom properties. In fact, any method potentially needs access to the converter just to know the OAS version. I'm still hesitant between this PR and the second alternative above (static methods + self/openapi_converter passed as kwargs). The latter is slightly clearer to the user creating a custom function because the former (this PR) means the user creating a custom function writes a function having def my_custom_func(self, field, **kwargs): # <-- self, here, while not in class scope
[...]
ma_plugin.converter.add_attribute_function(my_custom_func)OTOH, the def my_custom_func(field, openapi_converter, **kwargs): # <-- openapi_converter here
[...]
ma_plugin.converter.add_attribute_function(my_custom_func)Maybe I'm overthinking it. I'll probably merge this. Just need to update docs/changelog. Meanwhile, thoughts welcome. I can rework for the static functions alternative. |
|
One additional alternative would be to make all static methods but instead of passing the At the end of the day we are saving users having to create their logic in a subclass. So by requiring them to add a |
| .. code-block:: python | ||
|
|
||
| def my_custom_field2properties(field, **kwargs): | ||
| def my_custom_field2properties(self, field, **kwargs): |
There was a problem hiding this comment.
Maybe rename the first arg to make it more clear? converter?
There was a problem hiding this comment.
Yeah, I was wondering.
The point is that the custom and stock functions look alike. And the doc says the function will be bound. We could stress out bound -> self, or s/self/converter. But converter is not that self-explanatory either.
No strong feeling either way. In any case, it's a trick in trick's clothing.
There was a problem hiding this comment.
Fair enough. I've no strong opinion either way. self just looks strange on a function, but yeah..'trick's clothing'. =)
This achieves the same goal as #497.
It makes things more consistent to have custom attribute functions be bound to the instance like the default ones.
This means all custom functions must accept
self(even if they don't use it). I think consistency is worth this (little) inconvenience.