How to document Python functions with overload/dispatch decorators?

|▌冷眼眸甩不掉的悲伤 提交于 2020-08-26 06:54:51

问题


Applying Documentation to Multi-Dispatched Functions

I am using the multipledispatch package, in a fashion similar to the example code below. I want to be able to see the docstring text when I ask for help(my_add) in the Python command line, but instead all I see is information about the decorator.

Functools.wraps must be the way to do it, but how?

I have looked up functools.wraps, which I'm sure is what I want to use. I have found examples of how to use it, such as this and this.

But I still don't entirely understand two issues:

  1. How to apply the functools.wraps to external decorators that I don't "own".
  2. How to apply it specifically to this case with multiple dispatch, since the function I want to wrap will have multiple docstrings associated with the same function name.

Example: Decorated Function Creation

Below is an example to help explain.

>>> from multipledispatch import dispatch
>>> @dispatch(str, str)
... def my_add(elem1, elem2):
...   '''A flavor of 'add' where two strings are concatenated.'''
...   return elem1 + ' ' + elem2
... 
>>> @dispatch(int, int)
... def my_add(elem1, elem2):
...   '''A flavor of 'my_add' where two strings are concatenated.'''
...   return elem1 + elem2
... 
>>> my_add('hey','you')
'hey you'
>>> my_add(4, 5)
9
>>> my_add(4.5, 6)

(Traceback details removed...)

KeyError: (<class 'float'>, <class 'int'>)
During handling of the above exception, another exception occurred:
NotImplementedError: Could not find signature for my_add: <float, int>

I wanted to show that error and the different dispatches just to show that that part is working as I want it (looking for the matched dispatch and calling the associated "flavor" of the function).

Example: Calling help on the Decorated Function Fails!

But next, if I try to look at the help, instead of seeing the simple docstring that I have provided, I see the docstring associated with the @dispatch decorator.

>>> help(my_add)

Help on Dispatcher in module multipledispatch.dispatcher object:

my_add = class Dispatcher(builtins.object)
 |  Methods defined here:
 |  
 |  __call__(self, *args, **kwargs)
 |      Call self as a function.
 |  
 |  __getstate__(self)
 |  

etc.


I'm not even sure what it should show, since there are potentially 2 conflicting docstrings I'd like to push forward. So, I tried to see if I could call help on a function that's actually run, but then of course it gives me help on the returned data type. E.g.,

>>> help(my_add(3, 5))

Help on int object:

class int(object)
 |  int(x=0) -> integer
 |  int(x, base=10) -> integer
 |  
 |  Convert a number or string to an integer, or return 0 if no arguments

回答1:


The functools.wraps() decorator would have to be part of the decorator implementation and you can't apply it after the fact. The issue here is that the decorator returns an instance of a custom class, and help() can only show documentation for the class of that instance.

The Dispatcher() instance the decorator returns already has a __doc__ attribute, one which lists the doc strings of all decorated functions. From the documentation you linked:

The Dispatcher creates a detailed docstring automatically. To add a description of the multimethod itself, provide it when creating the Dispatcher.

The docstring is there for your example too:

>>> print(my_add.__doc__)
Multiply dispatched method: my_add

Inputs: <str, str>
-------------------
A flavor of 'add' where two strings are concatenated.

Inputs: <int, int>
-------------------
A flavor of 'my_add' where two strings are concatenated.

(note that the docstrings are reflected correctly from your example, complete with errors).

The real issue here is that help() can only print the __doc__ string of the class, so print(type(my_add).__doc__)) is used as a starting point. This is not something that can easily be changed; just stick to printing the __doc__ attribute of the instance directly.



来源:https://stackoverflow.com/questions/48347628/how-to-document-python-functions-with-overload-dispatch-decorators

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!