# Source: https://fastcore.fast.ai/docments.html.md

# Docments


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

[`docments`](https://fastcore.fast.ai/docments.html#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](https://stackoverflow.com/questions/62167540/why-do-definitions-have-a-space-before-the-colon-in-numpy-docstring-sections),
which is a pain to create and maintain, and awkward to read in code. For
instance, using [numpy-style
documentation](https://numpydoc.readthedocs.io/en/latest/format.html):

``` python
def add_np(a:int, b:int=0)->int:
    """The sum of two numbers.
    
    Used to demonstrate numpy-style docstrings.

Parameters
----------
a : int
    the 1st number to add
b : 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:

``` python
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
```

## Numpy docstring helper functions

[`docments`](https://fastcore.fast.ai/docments.html#docments) also
supports numpy-style docstrings, or a mix or numpy-style and docments
parameter documentation. The functions in this section help get and
parse this information.

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L26"
target="_blank" style="float:right; font-size:smaller">source</a>

### docstring

``` python

def docstring(
    sym
):

```

*Get docstring for `sym` for functions ad classes*

``` python
test_eq(docstring(add), "The sum of two numbers.")
```

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L34"
target="_blank" style="float:right; font-size:smaller">source</a>

### parse_docstring

``` python

def parse_docstring(
    sym
):

```

*Parse a numpy-style docstring in `sym`*

``` python
# parse_docstring(add_np)
```

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L39"
target="_blank" style="float:right; font-size:smaller">source</a>

### isdataclass

``` python

def isdataclass(
    s
):

```

*Check if `s` is a dataclass but not a dataclass’ instance*

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L44"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_dataclass_source

``` python

def get_dataclass_source(
    s
):

```

*Get source code for dataclass `s`*

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L49"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_source

``` python

def get_source(
    s
):

```

*Get source code for string, function object or dataclass `s`*

``` python
parms = _param_locs(add)
parms
```

    {2: 'a', 3: 'b', 4: 'return'}

``` python
_get_comment(2, 'a', {2: ' the 1st number to add'}, parms)
```

    'the 1st number to add'

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L133"
target="_blank" style="float:right; font-size:smaller">source</a>

### get_name

``` python

def get_name(
    obj
):

```

*Get the name of `obj`*

``` python
test_eq(get_name(in_ipython), 'in_ipython')
test_eq(get_name(L.map), 'map')
```

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L146"
target="_blank" style="float:right; font-size:smaller">source</a>

### qual_name

``` python

def qual_name(
    obj
):

```

*Get the qualified name of `obj`*

``` python
assert qual_name(docscrape) == 'fastcore.docscrape'
```

## Docments

Let’s manually go through each step of `_docments` to see what it does:

``` python
def _b(
    z:str='b', # Last
):
    return b, a

@delegates(_b)
def _c(
    b:str, # Ignore
    a:int=2
): return b, a # Third

@delegates(_c)
def _d(
    c:int, # First
    b:str, # Second
    **kwargs
)->int: # Return an int
    return c, _c(b, **kwargs)
```

``` python
s = _d
nps = parse_docstring(s)
if isclass(s) and not is_dataclass(s): s = s.__init__
comments = {o.start[0]:_clean_comment(o.string) for o in _tokens(s) if o.type==COMMENT}
comments
```

    {3: ' First', 4: ' Second', 6: ' Return an int'}

``` python
parms = _param_locs(s, returns=True, args_kwargs=True) or {}
parms
```

    {3: 'c', 4: 'b', 5: 'kwargs', 6: 'return'}

``` python
docs = {arg:_get_comment(line, arg, comments, parms) for line,arg in parms.items()}
docs
```

    {'c': 'First', 'b': 'Second', 'kwargs': None, 'return': 'Return an int'}

``` python
sig = signature(s, eval_str=True)
res = {name:_get_full(p, docs) for name,p in sig.parameters.items()}
res
```

    {'c': {'docment': 'First', 'anno': int, 'default': inspect._empty},
     'b': {'docment': 'Second', 'anno': str, 'default': inspect._empty},
     'a': {'docment': None, 'anno': int, 'default': 2},
     'z': {'docment': None, 'anno': str, 'default': 'b'}}

``` python
res['return'] = AttrDict(docment=docs.get('return'), anno=sig.return_annotation, default=empty)
res = _merge_docs(res, nps)
res
```

    {'c': {'docment': 'First', 'anno': int, 'default': inspect._empty},
     'b': {'docment': 'Second', 'anno': str, 'default': inspect._empty},
     'a': {'docment': None, 'anno': int, 'default': 2},
     'z': {'docment': None, 'anno': str, 'default': 'b'},
     'return': {'docment': 'Return an int',
      'anno': int,
      'default': inspect._empty}}

``` python
_d.__delwrap__
```

    <function __main__._c(b: str, a: int = 2, *, z: str = 'b')>

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L153"
target="_blank" style="float:right; font-size:smaller">source</a>

### docments

``` python

def docments(
    s, full:bool=False, eval_str:bool=False, returns:bool=True, args_kwargs:bool=False
):

```

*Get docments for `s`*

``` python
docments(_d)
```

``` python
{'a': None, 'b': 'Second', 'c': 'First', 'return': 'Return an int', 'z': 'Last'}
```

``` python
docments(_d, full=True)
```

``` python
{ 'a': {'anno': <class 'int'>, 'default': 2, 'docment': None},
  'b': { 'anno': <class 'str'>,
         'default': <class 'inspect._empty'>,
         'docment': 'Second'},
  'c': { 'anno': <class 'int'>,
         'default': <class 'inspect._empty'>,
         'docment': 'First'},
  'return': { 'anno': <class 'int'>,
              'default': <class 'inspect._empty'>,
              'docment': 'Return an int'},
  'z': {'anno': <class 'str'>, 'default': 'b', 'docment': 'Last'}}
```

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

``` python
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
```

``` python
docments(add)
```

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

`args_kwargs=True` adds args and kwargs docs too:

``` python
def add(
    a:int, # the 1st number to add
    *args, # some args
    b=0,   # the 2nd number to add
    **kwargs, # Passed to the `example` function
)->int:    # the result of adding `a` to `b`
    "The sum of two numbers."
    return a+b
```

``` python
docments(add, args_kwargs=True)
```

``` python
{ 'a': 'the 1st number to add',
  'args': 'some args',
  'b': 'the 2nd number to add',
  'kwargs': 'Passed to the `example` function',
  'return': 'the result of adding `a` to `b`'}
```

If you pass `full=True`, the values are `dict` of defaults, types, and
docments as values. Note that the type annotation is inferred from the
default value, if the annotation is empty and a default is supplied.
(Note that for `full`, `args_kwargs=True` is always set too.)

``` python
docments(add, full=True)
```

``` python
{ 'a': { 'anno': <class 'int'>,
         'default': <class 'inspect._empty'>,
         'docment': 'the 1st number to add'},
  'args': { 'anno': <_ParameterKind.VAR_POSITIONAL: 2>,
            'default': <class 'inspect._empty'>,
            'docment': 'some args'},
  'b': { 'anno': <class 'int'>,
         'default': 0,
         'docment': 'the 2nd number to add'},
  'kwargs': { 'anno': <_ParameterKind.VAR_KEYWORD: 4>,
              'default': <class 'inspect._empty'>,
              'docment': None},
  'return': { 'anno': <class 'int'>,
              'default': <class 'inspect._empty'>,
              'docment': 'the result of adding `a` to `b`'}}
```

To evaluate stringified annotations (from python 3.10), use `eval_str`:

``` python
docments(add, full=True, eval_str=True)['a']
```

``` python
{ 'anno': <class 'int'>,
  'default': <class 'inspect._empty'>,
  'docment': 'the 1st number to add'}
```

``` python
docments(add, full=True)['a']
```

``` python
{ 'anno': <class 'int'>,
  'default': <class 'inspect._empty'>,
  'docment': 'the 1st number to add'}
```

If you need more space to 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:

``` python
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
```

``` python
docments(add)
```

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

Docments works with async functions, too:

``` python
async def add_async(
    # 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
```

``` python
test_eq(docments(add_async), docments(add))
```

You can also use docments with classes and methods:

``` python
class Adder:
    "An addition calculator"
    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
```

``` python
docments(Adder)
```

``` python
{'a': 'First operand', 'b': '2nd operand', 'return': None, 'self': None}
```

``` python
docments(Adder.calculate)
```

``` python
{'return': 'Integral result of addition operator', 'self': None}
```

docments can also be extracted from numpy-style docstrings:

``` python
print(add_np.__doc__)
```

    The sum of two numbers.

        Used to demonstrate numpy-style docstrings.

    Parameters
    ----------
    a : int
        the 1st number to add
    b : int
        the 2nd number to add (default: 0)

    Returns
    -------
    int
        the result of adding `a` to `b`

``` python
docments(add_np)
```

``` python
{ 'a': 'the 1st number to add',
  'b': 'the 2nd number to add (default: 0)',
  'return': 'the result of adding `a` to `b`'}
```

You can even mix and match docments and numpy parameters:

``` python
def add_mixed(a:int, # the first number to add
              b
             )->int: # the result
    """The sum of two numbers.

Parameters
----------
b : int
    the 2nd number to add (default: 0)"""
    return a+b
```

``` python
docments(add_mixed, full=True)
```

``` python
{ 'a': { 'anno': <class 'int'>,
         'default': <class 'inspect._empty'>,
         'docment': 'the first number to add'},
  'b': { 'anno': <class 'inspect._empty'>,
         'default': <class 'inspect._empty'>,
         'docment': 'the 2nd number to add (default: 0)'},
  'return': { 'anno': <class 'int'>,
              'default': <class 'inspect._empty'>,
              'docment': 'the result'}}
```

You can use docments with dataclasses, however if the class was defined
in online notebook, docments will not contain parameters’ comments. This
is because the source code is not available in the notebook. After
converting the notebook to a module, the docments will be available.
Thus, documentation will have correct parameters’ comments.

Docments even works with
[`delegates`](https://fastcore.fast.ai/meta.html#delegates):

``` python
from fastcore.meta import delegates
```

``` python
def _a(a:str=None): return a # First

@delegates(_a)
def _b(b:str, # Second
       **kwargs
      ): # Return nothing
    return b, (_a(**kwargs)) 

docments(_b)
```

``` python
{'a': 'First', 'b': 'Second', 'return': None}
```

``` python
docments(_b, full=True)
```

``` python
{ 'a': {'anno': <class 'str'>, 'default': None, 'docment': 'First'},
  'b': { 'anno': <class 'str'>,
         'default': <class 'inspect._empty'>,
         'docment': 'Second'},
  'return': { 'anno': <class 'inspect._empty'>,
              'default': <class 'inspect._empty'>,
              'docment': None}}
```

Builtins just return an empty dict:

``` python
docments(str)
```

``` python
{'args': None, 'kwargs': None, 'return': None, 'self': None}
```

## Extract docstrings

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L174"
target="_blank" style="float:right; font-size:smaller">source</a>

### sig_source

``` python

def sig_source(
    obj
):

```

*Full source of signature line(s) for a function or class.*

``` python
print(sig_source(flexiclass))
```

    def flexiclass(
            cls # The class to convert
        ) -> dataclass:

``` python
def simple(x: dict[str, int]): return x
print(sig_source(simple))
```

    def simple(x: dict[str, int]): return x

``` python
def multi(a, b=1,
          c=2,
          d=3):
    return a
print(sig_source(multi))
```

    def multi(a, b=1,
              c=2,
              d=3):

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L221"
target="_blank" style="float:right; font-size:smaller">source</a>

### extract_docstrings

``` python

def extract_docstrings(
    code
):

```

*Create a dict from function/class/method names to tuples of docstrings
and param lists*

``` python
sample_code = """
"This is a module."

def top_func(a, b, *args, **kw):
    "This is top-level."
    pass

class SampleClass:
    "This is a class."

    def __init__(self, x, y):
        "Constructor for SampleClass."
        pass

    def method1(self, param1):
        "This is method1."
        pass

    def _private_method(self):
        "This should not be included."
        pass

class AnotherClass:
    def __init__(self, a, b):
        "This class has no separate docstring."
        pass"""

exp = {'_module': ('This is a module.', ''),
       'top_func': ('This is top-level.', 'a, b, *args, **kw'),
       'SampleClass': ('This is a class.', 'self, x, y'),
       'SampleClass.method1': ('This is method1.', 'self, param1'),
       'AnotherClass': ('This class has no separate docstring.', 'self, a, b')}
test_eq(extract_docstrings(sample_code), exp)
```

## Rendering docment Tables

Render nicely formatted tables that shows
[`docments`](https://fastcore.fast.ai/docments.html#docments) for any
function or method.

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L254"
target="_blank" style="float:right; font-size:smaller">source</a>

### DocmentTbl

``` python

def DocmentTbl(
    obj, verbose:bool=True, returns:bool=True
):

```

*Compute the docment table string*

[`DocmentTbl`](https://fastcore.fast.ai/docments.html#docmenttbl) can
render a markdown table showing
[`docments`](https://fastcore.fast.ai/docments.html#docments) if
appropriate. This is an example of how a
[`docments`](https://fastcore.fast.ai/docments.html#docments) table will
render for a function:

``` python
def _f(a,      # description of param a
       b=True, # description of param b
       c:str=None
       ) -> int: ...

_dm = DocmentTbl(_f)
_dm
```

<table>
<thead>
<tr>
<th></th>
<th><strong>Type</strong></th>
<th><strong>Default</strong></th>
<th><strong>Details</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>a</td>
<td></td>
<td></td>
<td>description of param a</td>
</tr>
<tr>
<td>b</td>
<td>bool</td>
<td>True</td>
<td>description of param b</td>
</tr>
<tr>
<td>c</td>
<td>str</td>
<td>None</td>
<td></td>
</tr>
<tr>
<td><strong>Returns</strong></td>
<td><strong>int</strong></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>

If one column in the table has no information, for example because there
are no default values, that column will not be shown. In the below
example, the **Default** column, will not be shown. Additionally, if the
return of the function is not annotated the **Returns** row will not be
rendered:

``` python
def _f(a,
        b:int, #param b
        c:str='foo'  #param c
       )->str: # Result of doing it
    "Do a thing"
    ...
```

``` python
_dm2 = DocmentTbl(_f)
_dm2
```

<table>
<thead>
<tr>
<th></th>
<th><strong>Type</strong></th>
<th><strong>Default</strong></th>
<th><strong>Details</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>a</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>b</td>
<td>int</td>
<td></td>
<td>param b</td>
</tr>
<tr>
<td>c</td>
<td>str</td>
<td>foo</td>
<td>param c</td>
</tr>
<tr>
<td><strong>Returns</strong></td>
<td><strong>str</strong></td>
<td></td>
<td><strong>Result of doing it</strong></td>
</tr>
</tbody>
</table>

[`DocmentTbl`](https://fastcore.fast.ai/docments.html#docmenttbl) also
works on classes. By default, the `__init__` will be rendered:

``` python
class _Test:
    def __init__(self,
                 a,      # description of param a
                 b=True, # description of param b
                 c:str=None):
        ...

    def foo(self,
            c:int,      # description of param c
            d=True, # description of param d
           ):
        ...
```

``` python
DocmentTbl(_Test)
```

<table>
<thead>
<tr>
<th></th>
<th><strong>Type</strong></th>
<th><strong>Default</strong></th>
<th><strong>Details</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>a</td>
<td></td>
<td></td>
<td>description of param a</td>
</tr>
<tr>
<td>b</td>
<td>bool</td>
<td>True</td>
<td>description of param b</td>
</tr>
<tr>
<td>c</td>
<td>str</td>
<td>None</td>
<td></td>
</tr>
</tbody>
</table>

You can also pass a method to be rendered as well:

``` python
DocmentTbl(_Test.foo)
```

<table>
<thead>
<tr>
<th></th>
<th><strong>Type</strong></th>
<th><strong>Default</strong></th>
<th><strong>Details</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>c</td>
<td>int</td>
<td></td>
<td>description of param c</td>
</tr>
<tr>
<td>d</td>
<td>bool</td>
<td>True</td>
<td>description of param d</td>
</tr>
</tbody>
</table>

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L311"
target="_blank" style="float:right; font-size:smaller">source</a>

### DocmentList

``` python

def DocmentList(
    obj
):

```

*Initialize self. See help(type(self)) for accurate signature.*

``` python
DocmentList(_f)
```

- `a`
- `b:int`   *param b*
- `c:str=foo`   *param c*
- `return:str`   *Result of doing it*

``` python
print(_fmt_sig('foo', [('a:int', 'first'), ('b:str', None), ('c', 'third')], ')->int:', 80))
```

    def foo(
        a:int, # first
        b:str, c, # third
    )->int:

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L347"
target="_blank" style="float:right; font-size:smaller">source</a>

### DocmentText

``` python

def DocmentText(
    obj, maxline:int=110, docstring:bool=True
):

```

*Initialize self. See help(type(self)) for accurate signature.*

``` python
DocmentText(_f).params
```

    [('a', None), ('b:int', 'param b'), ("c:str='foo'", 'param c')]

``` python
DocmentText(_f)
```

``` python
def _f(
    a, b:int, # param b
    c:str='foo', # param c
)->str: # Result of doing it
    "Do a thing"
```

``` python
def _g(
    a, b:int, cccccccccccccccccccc:int, ccccccccdccccccccccc:int, cccccccccccecccccccc:int, cccccccfcccccccccc:int, ccccccccccccgccccc:int, # hi
    c:str='foo'
)->str:
    "Do a thing"

DocmentText(_g, maxline=80, docstring=False)
```

``` python
def _g(
    a, b:int, cccccccccccccccccccc:int, ccccccccdccccccccccc:int,
    cccccccccccecccccccc:int, cccccccfcccccccccc:int, ccccccccccccgccccc:int, # hi
    c:str='foo'
)->str:
```

``` python
DocmentText(partial(_g, 1), maxline=80, docstring=False)
```

``` python
def _g[partial: 1](
    b:int, cccccccccccccccccccc:int, ccccccccdccccccccccc:int,
    cccccccccccecccccccc:int, cccccccfcccccccccc:int, ccccccccccccgccccc:int,
    c:str='foo'
)->str:
```

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L376"
target="_blank" style="float:right; font-size:smaller">source</a>

### sig2str

``` python

def sig2str(
    func, maxline:int=110
):

```

*Generate function signature with docments as comments*

``` python
print(sig2str(_d))
```

    def _d(
        c:int, # First
        b:str, # Second
        a:int=2, z:str='b', # Last
    )->int: # Return an int

## Documentation For An Object

Render the signature as well as the
[`docments`](https://fastcore.fast.ai/docments.html#docments) to show
complete documentation for an object.

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L390"
target="_blank" style="float:right; font-size:smaller">source</a>

### ShowDocRenderer

``` python

def ShowDocRenderer(
    sym, name:str | None=None, title_level:int=3, maxline:int=110
):

```

*Show documentation for `sym`*

------------------------------------------------------------------------

<a
href="https://github.com/AnswerDotAI/fastcore/blob/main/fastcore/docments.py#L425"
target="_blank" style="float:right; font-size:smaller">source</a>

### MarkdownRenderer

``` python

def MarkdownRenderer(
    sym, name:str | None=None, title_level:int=3, maxline:int=110
):

```

*Markdown renderer for `show_doc`*

``` python
def _f(a,
        b:callable=print, #param b
        c:str='foo'  #param c
       )->str: # Result of doing it
    "Do a thing"
    ...

MarkdownRenderer(_f)
```

``` python

def _f(
    a, b:callable=print, # param b
    c:str='foo', # param c
)->str: # Result of doing it

```

*Do a thing*

``` python
def f(a:int=0 # aa
): pass

@delegates(f)
def g(
    b:int|str, # bb
    **kwargs
): return kwargs
```

``` python
MarkdownRenderer(g)
```

``` python

def g(
    b:int | str, # bb
    a:int=0, # aa
):

```

``` python
MarkdownRenderer(next)
```

``` python

def next(iterator, default=..., /)

```

*Return the next item from the iterator.*

If default is given and the iterator is exhausted, it is returned
instead of raising StopIteration.