# i2.doc_mint

Meta-interfaces

### Functions

| [`assert_wants`](#i2.doc_mint.assert_wants)(example, \*args, \*\*kwargs)         | Render a `doctest.Example` as an `assert` comparing its source to its want.                                                                                     |
|----------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`convert_string`](#i2.doc_mint.convert_string)(s, converters)                     | Convert `s` with the first converter that matches (a dict containing `s` as a key, or a callable returning something other than None); return `s` if none does. |
| [`docstring_to_params`](#i2.doc_mint.docstring_to_params)(docstring, \*[, ...])         | Parse a docstring and extract parameter specifications.                                                                                                         |
| [`doctest_string`](#i2.doc_mint.doctest_string)(obj[, example_callback, recurse])  | Extract the doctests found in given object.                                                                                                                     |
| [`doctest_string_print`](#i2.doc_mint.doctest_string_print)(obj[, ...])                  | Extract the doctests found in given object.                                                                                                                     |
| [`doctest_string_trans_lines`](#i2.doc_mint.doctest_string_trans_lines)(doctest_obj[, ...])    | Yield `example_callback(example)` for each example of a `doctest.DocTest`.                                                                                      |
| [`find_in_params`](#i2.doc_mint.find_in_params)(query, params, \*[, search_in])    | Find parameters in a list of parameter specifications.                                                                                                          |
| [`indent_lines`](#i2.doc_mint.indent_lines)(string, indent)                      | Indent each line of a string.                                                                                                                                   |
| [`inject_docstring_content`](#i2.doc_mint.inject_docstring_content)(to_inject, \*[, ...])    | Inject content into the docstring of a function.                                                                                                                |
| [`literal_eval_converter`](#i2.doc_mint.literal_eval_converter)(s[, max_length])           | Evaluate `s` as a Python literal, or return None when it is not one (or is longer than `max_length`, or contains a newline or `;`).                             |
| [`mk_example_wants_callback`](#i2.doc_mint.mk_example_wants_callback)(source_want_func)       | Make a `doctest.Example` callback from a `(source, want) -> str` function.                                                                                      |
| [`most_common_indent`](#i2.doc_mint.most_common_indent)(string[, ignore_first_line])   | Find the most common indentation in a string.                                                                                                                   |
| [`non_doctest_lines`](#i2.doc_mint.non_doctest_lines)(doc)                            | Generator of lines of the doc string that are not in a doctest scope.                                                                                           |
| [`old_doctest_string`](#i2.doc_mint.old_doctest_string)(obj[, output_prefix, ...])     | Extract the doctests found in given object.                                                                                                                     |
| [`output_prefix`](#i2.doc_mint.output_prefix)(example, \*args, \*\*kwargs)        | Render a `doctest.Example` as its source followed by a `# OUTPUT:` line.                                                                                        |
| [`params_to_docstring`](#i2.doc_mint.params_to_docstring)(params, \*[, doc_style, ...]) | Generate a docstring from a list of parameter specifications.                                                                                                   |
| [`register_converter`](#i2.doc_mint.register_converter)(converter)                     | Register a new converter.                                                                                                                                       |
| [`split_line_comments`](#i2.doc_mint.split_line_comments)(s)                            | Split a single line into its code and its `#` comment (empty if none).                                                                                          |
| [`split_text_and_doctests`](#i2.doc_mint.split_text_and_doctests)(doc_string)               | Generates alternating blocks of "text" (string) and "doctest blocks" (`DoctestBlock` instances, which are essentially a list of `ExampleX` instances).          |
| [`string_param_to_obj`](#i2.doc_mint.string_param_to_obj)(string_to_object_mapping)     | Convert a string representation of a parameter to an object.                                                                                                    |
| [`strip_comments`](#i2.doc_mint.strip_comments)(code)                              | Remove whole-line `#` comments from `code` (inline comments are kept).                                                                                          |

### Classes

| [`DoctestBlock`](#i2.doc_mint.DoctestBlock)([seq])                            | A list that (should) contain doctest Example instances   |
|-------------------------------------------------------------------------------------------------|----------------------------------------------------------|
| [`ExampleX`](#i2.doc_mint.ExampleX)(source[, want, exc_msg, lineno, ...]) | doctest.Example eXtended to have more convenient methods |

### *class* i2.doc_mint.DoctestBlock(seq=())

Bases: [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)

A list that (should) contain doctest Example instances

### *class* i2.doc_mint.ExampleX(source, want=None, exc_msg=None, lineno=0, indent=0, options=None)

Bases: [`Example`](https://docs.python.org/3/library/doctest.html#doctest.Example)

doctest.Example eXtended to have more convenient methods

### i2.doc_mint.assert_wants(example, \*args, \*\*kwargs)

Render a `doctest.Example` as an `assert` comparing its source to its want.

```pycon
>>> import doctest
>>> assert_wants(doctest.Example(source='1 + 1\n', want='2\n'))
'assert (1 + 1) == 2 #'
```

### i2.doc_mint.convert_string(s, converters)

Convert `s` with the first converter that matches (a dict containing `s` as a
key, or a callable returning something other than None); return `s` if none does.

* **Return type:**
  [`object`](https://docs.python.org/3/builtins/functions.html#object)

```pycon
>>> convert_string("None", dflt_str_to_obj_converters), convert_string("3.5", dflt_str_to_obj_converters)
(None, 3.5)
>>> convert_string("hello", dflt_str_to_obj_converters)
'hello'
```

### i2.doc_mint.docstring_to_params(docstring, \*, doc_style='numpy', converters=[{'-inf': -inf, 'False': False, 'None': None, 'True': True, 'bool': <class 'bool'>, 'complex': <class 'complex'>, 'dict': <class 'dict'>, 'float': <class 'float'>, 'inf': inf, 'int': <class 'int'>, 'list': <class 'list'>, 'nan': nan, 'set': <class 'set'>, 'str': <class 'str'>, 'tuple': <class 'tuple'>}, <function literal_eval_converter>])

Parse a docstring and extract parameter specifications.

* **Parameters:**
  * **docstring** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The docstring to parse.
  * **doc_style** ([`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[`'numpy'`, `'google'`, `'rest'`]) – The style of the docstring to parse. One of ‘numpy’, ‘google’, or ‘rest’.
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)]
* **Returns:**
  A list of parameter specifications, where each specification is a dictionary containing:
  - name: The name of the parameter (str).
  - default: The default value of the parameter (str, optional).
  - annotation: The type annotation for the parameter (str, optional).
  - description: A description of the parameter (str).

**Examples**

```pycon
>>> docstring = '''
... Parameters
... ----------
... x : int, default=1
...     An integer value.
... y : str, default=None
...     An optional string.
... '''
>>> params = docstring_to_params(docstring)
>>> params  == [
...     {'name': 'x', 'default': 1, 'annotation': int, 'description': 'An integer value.'},
...     {'name': 'y', 'default': None, 'annotation': str, 'description': 'An optional string.'}
... ]
True
```

```pycon
>>> docstring = '''
... Args:
...     x (int, optional): An integer value. Defaults to 1.
...     y (str, optional): An optional string. Defaults to None.
... '''
>>> params = docstring_to_params(docstring, doc_style='google')
>>> params == [
...     {"name": "x", "default": 1, "annotation": int, "description": "An integer value."},
...     {"name": "y", "default": None, "annotation": str, "description": "An optional string."},
... ]
True
```

```pycon
>>> docstring = '''
... :param x: An integer value. (Default: 1)
... :type x: int
... :param y: An optional string. (Default: None)
... :type y: str
... '''
>>> params = docstring_to_params(docstring, doc_style='rest')
>>> params == [
...     {"name": "x", "default": 1, "annotation": int, "description": "An integer value."},
...     {"name": "y", "default": None, "annotation": str, "description": "An optional string."},
... ]
True
```

### i2.doc_mint.doctest_string(obj, example_callback=<function mk_example_wants_callback.<locals>.example_wants_callback>, recurse=True)

Extract the doctests found in given object.

* **Parameters:**
  * **obj** – Object (module, class, function, etc.) you want to extract doctests from.
  * **recurse** – Whether the process should find doctests in the attributes of the object, recursively.
* **Params output_prefix:**
* **Returns:**
  A string containing the doctests, with output lines prefixed by ‘# Output:’

### i2.doc_mint.doctest_string_print(obj, example_callback=<function mk_example_wants_callback.<locals>.example_wants_callback>, recurse=True)

Extract the doctests found in given object.

* **Parameters:**
  * **obj** – Object (module, class, function, etc.) you want to extract doctests from.
  * **recurse** – Whether the process should find doctests in the attributes of the object, recursively.
* **Returns:**
  A string containing the doctests, with output lines prefixed by ‘# Output:’

### i2.doc_mint.doctest_string_trans_lines(doctest_obj, example_callback=<function mk_example_wants_callback.<locals>.example_wants_callback>)

Yield `example_callback(example)` for each example of a `doctest.DocTest`.

### i2.doc_mint.find_in_params(query, params, , search_in=('name', 'description'))

Find parameters in a list of parameter specifications.

* **Parameters:**
  * **query** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The query to search for.
  * **params** ([`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable) | [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – 

    The list of parameter specifications.
    Params can be provided in two formats:
    - A function, from which the params will be extracted from the docstring.
    - A list of dictionaries where each dictionary specifies a parameter, containing:
      > - name: The name of the parameter (str).
      > - default: The default value of the parameter (any, optional).
      > - annotation: The type annotation for the parameter (str, optional).
      > - description: A description of the parameter (str).

    If a callable is provided, it will be used to generate the list of parameter specifications.
  * **search_in** – The fields to search in each parameter specification.
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)]
* **Returns:**
  A list of parameter specifications that match the query.

### Examples

```pycon
>>> params = [
...     {"name": "x", "default": 1, "annotation": "int", "description": "An integer value."},
...     {"name": "y", "default": None, "annotation": "str", "description": "An optional string."},
... ]
>>> find_in_params('int', params)
[{'name': 'x', 'default': 1, 'annotation': 'int', 'description': 'An integer value.'}]
```

### i2.doc_mint.indent_lines(string, indent)

Indent each line of a string.

* **Parameters:**
  * **string** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The string to indent.
  * **indent** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The string to use for indentation.
* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)
* **Returns:**
  The indented string.

**Examples**

```pycon
>>> print(indent_lines('This is a test.\nAnother line.', ' ' * 8))
        This is a test.
        Another line.
```

### i2.doc_mint.inject_docstring_content(to_inject, , position=-1, indent=True)

Inject content into the docstring of a function.

#### NOTE
If you use the decorator on a string, it will assume that string is the doc
string you want to transform and return the modified string directly.

* **Parameters:**
  * **to_inject** – The content to inject.
  * **position** – The position in the docstring to inject the content.
    If an integer, the content is injected at that line number (pushing the rest down).
    If a string, will consider it as a regex pattern to match the line to inject after.
    Default is -1, to inject at the end.
  * **indent** – Control on indent.
    If True, will use the most common indent of the input docstrings.
    If a string, it will use that specific string.
* **Returns:**
  A decorator that injects the content into the docstring of the decorated function.

**Examples**

```pycon
>>> @inject_docstring_content('This is a test.')
... def test_func():
...     '''This is the docstring.'''
...     pass
>>> test_func.__doc__
'This is the docstring.\nThis is a test.'
>>> @inject_docstring_content('This is a test.', position='###INSERT HERE###')
... def test_func():
...     '''This is the docstring.
...     ###INSERT HERE###
...     More blah.
...     '''
...     pass
>>> test_func.__doc__
'This is the docstring.\n    ###INSERT HERE###\n    More blah.\n    '
```

### i2.doc_mint.literal_eval_converter(s, max_length=1000)

Evaluate `s` as a Python literal, or return None when it is not one (or is
longer than `max_length`, or contains a newline or `;`).

```pycon
>>> literal_eval_converter("[1, 2]"), literal_eval_converter("foo")
([1, 2], None)
```

### i2.doc_mint.mk_example_wants_callback(source_want_func)

Make a `doctest.Example` callback from a `(source, want) -> str` function.

The callback returns the example’s source untouched when the example expects no
output.

### i2.doc_mint.most_common_indent(string, ignore_first_line=True)

Find the most common indentation in a string.

* **Parameters:**
  * **string** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The string to analyze.
  * **ignore_first_line** – Whether to ignore the first line when determining the
    indentation. Default is True since the first line often has no indentation
    because of the way python strings appear in code.
* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)
* **Returns:**
  The most common indentation string.

**Examples**

```pycon
>>> most_common_indent('    This is a test.\n    Another line.')
'    '
```

### i2.doc_mint.non_doctest_lines(doc)

Generator of lines of the doc string that are not in a doctest scope.

```pycon
>>> def _test_func():
...     '''Line 1
...     Another
...     >>> doctest_1
...     >>> doctest_2
...     line_after_a_doc_test
...     another_line_that_is_in_the_doc_test scope
...
...     But now we're out of a doctest's scope
...
...     >>> Oh no, another doctest!
...     '''
>>> from inspect import getdoc
>>>
>>> list(non_doctest_lines(getdoc(_test_func)))
['Line 1', 'Another', "But now we're out of a doctest's scope", '']
```

* **Parameters:**
  **doc**
* **Returns:**

### i2.doc_mint.old_doctest_string(obj, output_prefix='# OUTPUT: ', include_attr_without_doctests=False, recurse=True)

Extract the doctests found in given object.

* **Parameters:**
  * **obj** – Object (module, class, function, etc.) you want to extract doctests from.
  * **output_prefix**
  * **recurse** – Whether the process should find doctests in the attributes of the object, recursively.
* **Returns:**
  A string containing the doctests, with output lines prefixed by ‘# Output:’

### i2.doc_mint.output_prefix(example, \*args, \*\*kwargs)

Render a `doctest.Example` as its source followed by a `# OUTPUT:` line.

```pycon
>>> import doctest
>>> output_prefix(doctest.Example(source='1 + 1\n', want='2\n'))
'1 + 1\n# OUTPUT: 2\n'
```

### i2.doc_mint.params_to_docstring(params, , doc_style='numpy', take_name_of_types=False, quote_string_defaults=True)

Generate a docstring from a list of parameter specifications.

* **Parameters:**
  * **params** ([`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)]) – 

    A list of dictionaries where each dictionary specifies a parameter.
    Each dictionary should contain:
    > - name: The name of the parameter (str).
    > - default: The default value of the parameter (any, optional).
    > - annotation: The type annotation for the parameter (str, optional).
    > - description: A description of the parameter (str).
  * **doc_style** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The style of the docstring to generate. One of ‘numpy’, ‘google’, or ‘rest’.
  * **take_name_of_types** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to use the name of the type as the annotation (bool).
  * **quote_string_defaults** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Whether to quote string defaults (bool).
* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)
* **Returns:**
  A formatted docstring (str).

**Examples**

```pycon
>>> params = [
...     {"name": "x", "default": 1, "annotation": "int", "description": "An integer value."},
...     {"name": "y", "default": None, "annotation": "str", "description": "An optional string."},
... ]
>>> print(params_to_docstring(params))
:param x: An integer value.
:type x: int, default=1
:param y: An optional string.
:type y: str, default=None
:param <BLANKLINE>:
:param >>> print(params_to_docstring(params:
:type >>> print(params_to_docstring(params: +NORMALIZE_WHITESPACE
:param doc_style='google'))  # doctest:
:type doc_style='google'))
:param Args: x (int, optional): An integer value. Defaults to 1.
             y (str, optional): An optional string. Defaults to None.
:param <BLANKLINE>:
:param >>> print(params_to_docstring(params:
:type >>> print(params_to_docstring(params: +NORMALIZE_WHITESPACE
:param doc_style='rest'))  # doctest:
:type doc_style='rest'))
:param :
:type : param x: An integer value. (Default: 1)
:param :
:type : type x: int
:param :
:type : param y: An optional string. (Default: None)
:param :
:type : type y: str
:param <BLANKLINE>:
```

### i2.doc_mint.register_converter(converter)

Register a new converter. A converter can be:

> - A dict: { “None”: None, “int”: int, … }
> - A callable: lambda s: attempt to parse s and return object or None

### i2.doc_mint.split_line_comments(s)

Split a single line into its code and its `#` comment (empty if none).

```pycon
>>> split_line_comments("f(1)  # a comment")
('f(1)  ', ' a comment')
```

### i2.doc_mint.split_text_and_doctests(doc_string)

Generates alternating blocks of “text” (string) and “doctest blocks”
(`DoctestBlock` instances, which are essentially a list of `ExampleX` instances).

```pycon
>>> example = '''
...     This is to test the doctest splitter.
...     Until now, we're in a text block.
...     The following is a doctest block:
...
...     >>> 2 + 3
...     5
...     >>> t = 5
...     >>> tt = 10
...
...     This is another text block, followed with another doctest block:
...
...     >>> def foo():
...     ...     return 42
...     >>> foo()
...     42
...
... '''
>>>
>>> blocks = list(split_text_and_doctests(example))
```

There are 5 blocks:

```pycon
>>> len(blocks)
5
```

The first block is a string, corresponding to explanatory text of the doc string:

```pycon
>>> isinstance(blocks[0], str)
True
>>> print(blocks[0])

This is to test the doctest splitter.
Until now, we're in a text block.
The following is a doctest block:

```

The next block is a `DoctestBlock` instance.

```pycon
>>> block = blocks[1]
>>> isinstance(block, DoctestBlock)
True
```

This block has 3 elements (`ExampleX` instances)

```pycon
>>> len(block)
3
```

If you ask for the string representation of this block, you’ll get a doctest string:

```pycon
>>> str(block)
'    >>> 2 + 3\n    5\n    >>> t = 5\n    >>> tt = 10\n'
```

### i2.doc_mint.string_param_to_obj(string_to_object_mapping, string=None)

Convert a string representation of a parameter to an object.

Use Case: When parsing a docstring, you get values as strings, but these values
may need to be converted to their actual object types
(in the case of default and annotatios for example).
This is a helper function to do that conversion.

* **Parameters:**
  * **string** – The string representation of the parameter.
  * **string_to_object_mapping** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – A mapping from string representations to objects.
* **Returns:**
  The object corresponding to the string representation.

**Examples**

```pycon
>>> string_to_object_mapping = {
...     'None': None,
...     'list': list,
...     'int': int,
... }
>>> string_to_obj = string_param_to_obj(string_to_object_mapping)
>>> string_to_obj('None')
>>> string_to_obj('list')
<class 'list'>
>>> string_to_obj('int')
<class 'int'>
>>> string_to_obj('not something listed')
'not something listed'
```

### i2.doc_mint.strip_comments(code)

Remove whole-line `#` comments from `code` (inline comments are kept).

```pycon
>>> strip_comments("# header\nx = 1  # set x\n")
'x = 1  # set x\n'
```
