docments provides programmatic access to comments in function parameters and return types. It can be used to create more developer-friendly documentation, CLI, etc tools.

## Why?

Without docments, if you want to document your parameters, you have to repeat param names in docstrings, since they're already in the function signature. The parameters have to be kept synchronized in the two places as you change your code. Readers of your code have to look back and forth between two places to understand what's happening. So it's more work for you, and for your users.

Furthermore, to have parameter documentation formatted nicely without docments, you have to use special magic docstring formatting, often with odd quirks, which is a pain to create and maintain, and awkward to read in code. For instance, using numpy-style documentation:

def add(a:int, b:int=0)->int:
"""The sum of two numbers.

Parameters
----------
x : int
y : int
the 2nd number to add (default: 0)

Returns
-------
int
the result of adding a to b"""
return a+b


By comparison, here's the same thing using docments:

def add(
a:int, # the 1st number to add
b=0,   # the 2nd number to add
)->int:    # the result of adding a to b
"The sum of two numbers."
return a+b


## Usage

#### docments[source]

docments(s, full=False, returns=True)

dict of parameter names to 'docment-style' comments in function or string s

The returned dict has parameter names as keys, and comments as values. The return value comment appears in the return, unless returns=False. Using the add definition above, we get:

docments(add)

{'a': 'the 1st number to add',
'b': 'the 2nd number to add',
'return': 'the result of adding a to b'}

This is the same format that __annotations__ uses in Python.

add.__annotations__

{'a': int, 'return': int}

Pass full=True to get the annotation and default value for each parameter, along with its docment. Note that the type annotation is inferred from the default value, if the annotation is empty and a default is supplied.

docments(add, full=True)

{'a': - docment: the 1st number to add
- anno: <class 'int'>
- default: <class 'inspect._empty'>,
'b': - docment: the 2nd number to add
- anno: <class 'int'>
- default: 0,
'return': - docment: the result of adding a to b
- anno: <class 'int'>
- default: <class 'inspect._empty'>}

If you need more space document a parameter, place one or more lines of comments above the parameter, or above the return type. You can mix-and-match these docment styles:

def add(
# The first operand
a:int,
# This is the second of the operands to the *addition* operator.
# Note that passing a negative value here is the equivalent of the *subtraction* operator.
b:int,
)->int: # The result is calculated using Python's builtin + operator.
"Add a to b"
return a+b

docments(add)

{'a': 'The first operand',
'b': 'This is the second of the operands to the *addition* operator.\nNote that passing a negative value here is the equivalent of the *subtraction* operator.',
'return': "The result is calculated using Python's builtin + operator."}

You can also use documents with classes and methods:

class Adder:
def __init__(self,
a:int, # First operand
b:int, # 2nd operand
): self.a,self.b = a,b

def calculate(self
)->int: # Integral result of addition operator
"Add a to b"
return a+b

docments(Adder),docments(Adder.calculate)

({'self': None, 'a': 'First operand', 'b': '2nd operand'},
{'self': None, 'return': 'Integral result of addition operator'})
from nbdev.export import notebook2script
notebook2script()

Converted 00_test.ipynb.
Converted 01_basics.ipynb.
Converted 02_foundation.ipynb.
Converted 03_xtras.ipynb.
Converted 03a_parallel.ipynb.
Converted 03b_net.ipynb.
Converted 04_dispatch.ipynb.
Converted 05_transform.ipynb.
Converted 06_docments.ipynb.
Converted 07_meta.ipynb.
Converted 08_script.ipynb.
Converted index.ipynb.
Converted parallel_win.ipynb.