def test_format_doc_removes_unnecessary_newlines_when_appropriate_in_tables(): def doc_fun(): """ I am a poorly formatte d doc string. Args: - x (optional): actually not really here I talk too much. Raises: - TypeError: why not Example: ```python ## TODO: ## put some ## code here ``` """ pass res = format_doc(doc_fun, in_table=True) sub_string = ( '<p class="methods">I am a poorly formatte d doc string.<br><br>**Args**:' ) assert sub_string in res assert "<br>**Raises**:" in res
def test_format_doc_correctly_handles_code_blocks_outside_of_tables(): def doc_fun(): """ A `dict` that also supports attribute ("dot") access. Think of this as an extension to the standard python `dict` object. Args: - init_dict (dict, optional): dictionary to initialize the `DotDict` with - **kwargs (optional): key, value pairs with which to initialize the `DotDict` **Example**: ```python dotdict = DotDict({'a': 34}, b=56, c=set()) dotdict.a # 34 dotdict['b'] # 56 dotdict.c # set() ``` """ pass res = format_doc(doc_fun) sub_string = ( "**Example**: \n```python\n dotdict = DotDict({'a': 34}," " b=56, c=set())\n dotdict.a # 34\n dotdict['b'] # 56\n dotdict.c # set()\n\n```" ) assert sub_string in res
def test_format_doc_on_subclass_with_doc_but_inherited_init(): class Parent: """ This is the parent doc Args: - x (int): a number """ def __init__(self, x: int): pass def fn(self): pass class Child(Parent): """ This is the child doc """ def fn(self): pass doc = format_doc(Child) expected = textwrap.dedent(""" This is the child doc """).strip() assert doc == expected
def consistency_check(obj, obj_name): patt = re.compile(r"(?<=>`)(.*?)(?=[\(|`:])") doc = format_doc(obj) try: arg_list_index = doc.index("**Args**:") end = doc[arg_list_index:].find("</ul") arg_doc = doc[arg_list_index:(arg_list_index + end)] doc_args = {arg.strip() for arg in patt.findall(arg_doc)} except ValueError: doc_args = set() items = get_call_signature(obj) actual_args = {(a if isinstance(a, str) else a[0]) for a in items} undocumented = actual_args.difference(doc_args) # If the sig contains **kwargs, any keyword is valid if any(k.startswith("**") for k in actual_args): non_existent = {} else: non_existent = doc_args.difference(actual_args) if undocumented: undoc_args = ", ".join(undocumented) raise ValueError( f"{obj_name} has arguments without documentation: {undoc_args}") elif non_existent: undoc_args = ", ".join(non_existent) raise ValueError( f"{obj_name} has documentation for arguments that aren't real: {undoc_args}" )
def test_format_doc_on_subclass_with_doc_but_inherited_init(): class Parent: """ This is the parent doc Args: - x (int): a number """ def __init__(self, x: int): pass def fn(self): pass class Child(Parent): """ This is the child doc """ def fn(self): pass doc = format_doc(Child) expected = textwrap.dedent(""" This is the child doc #### Parent Class Documentation (`test_format_doc_on_subclass_with_doc_but_inherited_init.<locals>.Parent`): This is the parent doc **Args**: <ul class="args"><li class="args">`x (int)`: a number</li></ul> """).strip() assert doc == expected
def consistency_check(obj, obj_name): patt = re.compile(r"(?<=>`)(.*?)(?=[\(|`:])") doc = format_doc(obj) try: arg_list_index = doc.index("**Args**:") end = doc[arg_list_index:].find("</ul") arg_doc = doc[arg_list_index : (arg_list_index + end)] doc_args = {arg.strip() for arg in patt.findall(arg_doc)} except ValueError: doc_args = set() standalone, varargs, kwonly, kwargs, varkwargs = get_call_signature(obj) actual_args = ( set() .union(standalone) .union(varargs) .union([k for k, v in kwonly]) .union([k for k, v in kwargs]) .union(varkwargs) ) if actual_args.intersection(doc_args) < actual_args: undoc_args = ", ".join(actual_args.difference(doc_args)) raise ValueError( f"{obj_name} has arguments without documentation: {undoc_args}" ) elif doc_args.intersection(actual_args) < doc_args: undoc_args = ", ".join(doc_args.difference(actual_args)) raise ValueError( f"{obj_name} has documentation for arguments that aren't real: {undoc_args}" )
def test_format_doc_on_raw_exception(): formatted = format_doc(NamedException) expected = textwrap.dedent( """ Just a name, nothing more. """ ).strip() assert formatted == expected
def test_format_doc_on_raw_exception(): formatted = format_doc(NamedException) expected = textwrap.dedent(""" Just a name, nothing more. #### Parent Class Documentation (`Exception`): Common base class for all non-exit exceptions. """).strip() assert formatted == expected
def test_format_doc_escapes_asteriks_inside_tables(): def my_doc(): """ See: ```python my_doc(**kwargs) ``` """ pass res = format_doc(my_doc, in_table=True) assert res.count(r">\*<") == 2
def test_sections_have_formatted_headers_for_class_method_docs(obj, fn): doc = format_doc(fn, in_table=True) for section in ["Args", "Returns", "Raises", "Example"]: option1 = ">**{}**:".format(section) option2 = "\n**{}**:".format(section) assert (section in doc) is any( [(o in doc) for o in (option1, option2)] ), "{obj.__module__}.{obj.__name__}.{fn.__name__} has a poorly formatted {sec} header.".format( obj=obj, fn=fn, sec=section) if (section != "Example") and section in doc: assert "{}**:<".format(section) in doc.replace( " ", "" ), "{obj.__module__}.{obj.__name__}.{fn.__name__} has a poorly formatted {sec} listing.".format( obj=obj, fn=fn, sec=section)
def test_sections_have_formatted_headers_for_class_docs(obj): doc = format_doc(obj) for section in ["Args", "Returns", "Raises", "Example"]: option1 = ">**{}**:".format(section) option2 = "\n**{}**:".format(section) option3 = "**{}**:".format(section) assert (section in doc) is any( [(o in doc) for o in (option1, option2)] + [doc.startswith(option3)] ), "{obj.__module__}.{obj.__name__} has a poorly formatted {sec} header.".format( obj=obj, sec=section) if (section != "Example") and section in doc: assert "{}**:<".format(section) in doc.replace( " ", "" ), "{obj.__module__}.{obj.__name__} has a poorly formatted {sec} listing.".format( obj=obj, sec=section)
def test_format_doc_on_simple_doc(): def my_fun(): """ Indicates that a task should not run and wait for manual execution. Args: - message (Any, optional): Defaults to `None`. A message about the signal. """ pass formatted = format_doc(my_fun) assert formatted == ( "Indicates that a task should not run and wait for manual execution.\n\n" '**Args**: <ul class="args">' '<li class="args">' "`message (Any, optional)`: Defaults to `None`. A message about the signal.</li></ul>" )