Chilipp / docrep

A Python Module for intelligent reuse of docstrings
Apache License 2.0
30 stars 4 forks source link

Add custom sections #24

Closed mario-bermonti closed 3 years ago

mario-bermonti commented 3 years ago

Thanks for the great work! I'm trying to use docrep in my project but cannot, for the life of me, find a way to add a custom section to the text_sections attr.

I have tried many different things, but none of them work. I always get a KeyError when I add the section called Rules to the docstring. How do I add a new custom section to text_sections and also keep the original ones (ex., Examples, Notes)?

This is my code:

import docrep
docstrings = docrep.DocstringProcessor()

@docstrings.get_sections(
    base='do_something_great',
    sections=[
        "Parameters",
        "Rules",
    ],
)
def do_something_great(x, y):
    """Do something

    More description.

    Parameters
    ----------
    x :str
        is x
    y :str
        is y

    Rules 
    -----
    *characteristic*: Important rule for this characteristic. It is such
        an important characteristic.

    Returns
    -------
    instances_of_characteristic: int
        Number of times the *characteristic* was observed
    """
    pass

@docstrings.with_indent(4)
def do_more(*args, **kwargs):
    """Do even more stuff

    Even more description

    Parameters
    ----------
    %(do_something_great.parameters)s

    Rules
    -----
    %(do_something_great.rules)s

    Returns
    -------
    instances_of_characteristics : int
        Number of times many important characteristics are found.
    """
    pass

help(do_more)

How can I add the Rules section to the text_sections so that I can use it in do_more?

mario-bermonti commented 3 years ago

And I checked docrep’s documentation extensively, but did’t understand how to do it.

mario-bermonti commented 3 years ago

I solved it after experimenting more. I was confused about changing the how to change a classs attribute. Sorry!

For anyone that has this same question in the future, the correct way to solve it is by adding the following before instantiating the DocstringProcess class: docrep.DocstringProcessor.text_sections = ["Rules", "Notes", "Warnings"]

Chilipp commented 3 years ago

hey @mario-bermonti! yes, my apologies, this is an undocumented behaviour. I'd subclass the DocstringProcessor but yes, this is how it's supposed to work.

mario-bermonti commented 3 years ago

In a related note, is there anything special that should be done if I want to use docrep with instance methods? I tried the same as above, which was with a standard procedural function, but it doesn't work. I get a warning that it did’t find a valid key.

I have tried various things, but none of them work.

Should I open a new issue for this?

Chilipp commented 3 years ago

hey @mario-bermonti! yes please, open a new issue for that.

It should not make any difference whether you are using a function or method. So I'd need a bit of code to see what is going wrong

mario-bermonti commented 3 years ago

Done! Should this issue be reopened until this behavior is documented?

Chilipp commented 3 years ago

yes, good idea

mario-bermonti commented 3 years ago

Hey @Chilipp! I've run into another related issue that I don't know how to solve.

I'm not able to reuse custom sections from the docstring of a method in another module.

This is my first module docrep1.py. In this one, the custom section Rules is correctly inserted into _check_silent_letters.

# docrep1.py
from docrep import DocstringProcessor
DocstringProcessor.param_like_sections = [
    "Rules",
    "Parameters",
    "Other Parameters",
    "Returns",
    "Raises"
]
docstrings = DocstringProcessor()

class W():
    @docstrings.get_sections(base="silent_up", sections=["Parameters", "Rules"])
    @docstrings.dedent
    def _check_silent_u(self):
        """
        Count the number of silent letters *u*.

        Parameters
        ----------
        x : int
            some param

        Rules 
        -----
        *u*: when preceded by an *g* or *q* and
            followed by a *i* or *e*. These follow the pattern *gui*, *gue*,
            *que*, *qui*. 

        Returns
        -------
        silent_u_count: int
            Number of silent letters *u* in the word
        """
        pass

    def _check_silent_letters(self):
        """
        Count the number of silent letters.

        Silent letters are graphemes that do not have a phonemic representation.
        In Spanish, silent letters are *h*s and *u*s that meet certain criteria. 

        %(silent_up.parameters)s

        Rules
        -----
        %(silent_up.rules)s

        Returns
        -------
        silent_letter_count : int
            Number of silent letters.
        """
        pass
    docstrings.dedent(_check_silent_letters)

print(f"doc_check_silent: \n {W._check_silent_letters.__doc__}")

However, when I try to get the sections from _check_silent_u to use them in module 2 docrep2.py, Rules is not inserted. There is no error or warning, I just get an empty string (I think).

from docrep1 import W
from docrep import DocstringProcessor
DocstringProcessor.param_like_sections = [
    "Rules",
    "Parameters",
    "Other Parameters",
    "Returns",
    "Raises"
]
docstrings2 = DocstringProcessor()

docstrings2.dedent(W._check_silent_u)
docstrings2.get_sections(W._check_silent_u, base="silent_upp", sections=["Parameters", "Rules"])

@docstrings2.dedent
def do_more2(*args, **kwargs):
    """
    Add two number 2

    Parameters
    ----------
    %(silent_upp.parameters)s

    Rules
    -----
    %(silent_upp.rules)s

    """
    pass

print(f"docs_do_more: \n {do_more2.__doc__}")

I'm I doing something wrong? I write this question/issue here because I think it's related, but do let me know if it's not.

mario-bermonti commented 3 years ago

I forgot to add that I default sections like Parameters and Returns do get inserted correctly, but not Rules

mario-bermonti commented 3 years ago

I checked the docstrings.params and it contains the do_something.rules as an entry, but the value is an empty string.

Chilipp commented 3 years ago

hey @mario-bermonti! This is a tough one: You have a space behind Rules. Just remove it and it will work.

image

Just a side note: I strongly recommend to configure your editor to automatically remove trailing white spaces

mario-bermonti commented 3 years ago

hey @mario-bermonti! This is a tough one: You have a space behind Rules. Just remove it and it will work.

image

Sorry! 😓

Just a side note: I strongly recommend to configure your editor to automatically remove trailing white spaces

It's supposed to be configured to remove trailing white spaces. I will have to check that out.

I finally got it working and actually decided to go the way you suggested by subclassing the DocstringProcessor. I actually followed the documentation you recently added about this (#26). 👍