• A trivial question that I don't know - document a function/method

    From Paulo da Silva@21:1/5 to All on Sat Oct 22 21:58:09 2022
    Hi all!

    What is the correct way, if any, of documenting a function/method?

    1.
    def foo(a,b):
    """ A description.
    a: Whatever 1
    b: Whatever 2
    """
    ...

    2.
    def foo(a,b):
    """ A description.
    a -- Whatever 1
    b -- Whatever 2
    """
    ...

    3.
    def foo(a,b):
    """ A description.
    @param a: Whatever 1
    @param b: Whatever 2
    """
    ...

    4.
    def foo(a,b):
    """ A description.
    :param a: Whatever 1
    :param b: Whatever 2
    """
    ...

    5.
    Any other ...

    Any comments/suggestions are welcome.
    Thanks.
    Paulo

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Stromberg@21:1/5 to p_d_a_s_i_l_v_a_ns@nonetnoaddress.p on Sat Oct 22 16:09:11 2022
    I don't think there is a "correct" way. It depends somewhat on what tools you're using. I like pydocstyle, which I have hung off of vim with
    syntastic. pydocstyle checks for https://peps.python.org/pep-0257/ conformance.

    Also, rather than describe the types of formal parameters to functions in a docstring, I like to use mypy for https://peps.python.org/pep-0484/ with
    its --disallow-untyped-calls and --ignore-missing-imports options, which I
    hang off of a Makefile, called by a vim macro.

    On Sat, Oct 22, 2022 at 3:39 PM Paulo da Silva < p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> wrote:

    Hi all!

    What is the correct way, if any, of documenting a function/method?

    1.
    def foo(a,b):
    """ A description.
    a: Whatever 1
    b: Whatever 2
    """
    ...

    2.
    def foo(a,b):
    """ A description.
    a -- Whatever 1
    b -- Whatever 2
    """
    ...

    3.
    def foo(a,b):
    """ A description.
    @param a: Whatever 1
    @param b: Whatever 2
    """
    ...

    4.
    def foo(a,b):
    """ A description.
    :param a: Whatever 1
    :param b: Whatever 2
    """
    ...

    5.
    Any other ...

    Any comments/suggestions are welcome.
    Thanks.
    Paulo

    --
    https://mail.python.org/mailman/listinfo/python-list


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to Paulo da Silva on Sat Oct 22 21:49:55 2022
    On 10/22/2022 4:58 PM, Paulo da Silva wrote:
    Hi all!

    What is the correct way, if any, of documenting a function/method?

    1.
    def foo(a,b):
        """ A description.
        a: Whatever 1
        b: Whatever 2
        """
    [snip]
    5.
        Any other ...

    Any comments/suggestions are welcome.
    Thanks.
    Paulo


    This is not a trivial question - not because it is hard but because it
    is important, and more so when someone else needs to work with your
    code. It's surprising how easy it is to forget these details about even
    your own code. Here are some examples of how I like to document
    functions and methods, mostly based on PEP-257, Docstring Conventions (https://peps.python.org/pep-0257/) and Guido's style guide before it.

    def make_title_from_headline(self, p, h):
    """From node title, return title with over- and underline- strings.

    The leading symbol is chosen based on the indent level of
    the node.

    Note that might different from p.h because of, e.g.,
    directive removal.

    ARGUMENTS
    p -- the node position whose indent level is to be used.
    h -- the headline string to be processed.

    RETURNS
    a string
    """

    Key points - include all the arguments and the return. Capitals help
    lead the eye to the ARGUMENT and RETURNS blocks. If you use keyword
    arguments, add a KEYWORD ARGUMENTS section.

    def plot(self, stackposition=MAIN, clearFirst=True):
    """Plot a 2-D graph.

    ARGUMENTS
    self -- an instance of a PlotManager
    stackposition -- an integer denoting which data set to plot.
    clearFirst -- True if the previous plot should be cleared,
    else False.

    RETURNS
    nothing
    """

    Key point -- if the function/method returns nothing, say so.

    class Dataset:
    '''Class to represent a 2D curve.

    ATTRIBUTES
    xdata, ydata -- sequences holding the x or y data sets.
    Must be the same length. May be lists or numpy
    ndarrays.
    auxDataset -- dictionary of auxiliary data sets (e.g., for holding
    statistical information)
    errorBands -- List of Datasets to hold errors
    orig_filename -- file path, if any, used to load data (before
    any transformations have been applied).
    xaxislabel -- label text for the X axis label
    yaxislabel -- label text for the Y axis label
    figurelabel -- label text for the graph of this data
    ymin -- minimum value for Y axis
    ymax -- maximum value for Y axis
    parms -- dictionary of parameters, Meant to store the
    current values so they can be written to a file.
    '''

    If you have the space, these annotations could instead be placed in-line
    in the class's __init__() method. But it's not often there is enough
    space, and when they are in the docstring they will be extracted and
    displayed by docstring tools, which is a good thing.

    Sometimes it can happen that a function/method is is simple and clear
    that its name, and the names of the arguments, make it obvious what
    their meaning is. But that happens less often than you might think.


    - Be concise, but choose clarity over brevity;
    - Try to devise good, descriptive names as far as possible;
    - A long list of arguments probably should be ordered alphabetically,
    but could also be grouped, with each group ordered. Otherwise, it is
    useful to list the parameters in the order they appear in the
    function/method signature.
    - Be consistent in your docstrings, but remember there will be times
    that it makes more sense to relax the consistency.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Stefan Ram@21:1/5 to Paulo da Silva on Sun Oct 23 09:54:30 2022
    Paulo da Silva <p_d_a_s_i_l_v_a_ns@nonetnoaddress.pt> writes:
    What is the correct way, if any, of documenting a function/method?

    I have found a file in which it is claimed that the
    documentation was written by Guido van Rossum.

    |# Michael McLay started this module. Steve Majewski changed the
    |# interface to SvFormContentDict and FormContentDict. The multipart
    |# parsing was inspired by code submitted by Andreas Paepcke. Guido van
    |# Rossum rewrote, reformatted and documented the module and is currently
    |# responsible for its maintenance.
    "cgi.py" - Guido von Rossum (2.6)

    This file might give an impression of how Guido himself
    writes documentation.

    Module:

    |"""Support module for CGI (Common Gateway Interface) scripts.
    |
    |This module defines a number of utilities for use by CGI scripts
    |written in Python.
    |"""

    Function:

    |"""Parse a query in the environment or from a file (default stdin)
    |
    | Arguments, all optional:
    |
    | fp : file pointer; default: sys.stdin.buffer
    |
    | environ : environment dictionary; default: os.environ
    |
    | keep_blank_values: flag indicating whether blank values in
    | percent-encoded forms should be treated as blank strings.
    | A true value indicates that blanks should be retained as
    | blank strings. The default false value indicates that
    | blank values are to be ignored and treated as if they were
    | not included.
    ...
    |"""

    . Class:

    |"""Store a sequence of fields, reading multipart/form-data.
    |
    |This class provides naming, typing, files stored on disk, and
    |more. At the top level, it is accessible like a dictionary, whose
    |keys are the field names. (Note: None can occur as a field name.)
    |The items are either a Python list (if there's multiple values) or
    |another FieldStorage or MiniFieldStorage object. If it's a single
    |object, it has the following attributes:
    |
    |name: the field name, if specified; otherwise None
    |
    |filename: the filename, if specified; otherwise None; this is the
    | client side filename, *not* the file name on which it is
    | stored (that's a temporary file you don't deal with)
    |
    ...
    |The class is subclassable, mostly for the purpose of overriding
    |the make_file() method, which is called internally to come up with
    |a file open for reading and writing. This makes it possible to
    |override the default choice of storing all files in a temporary
    |directory and unlinking them as soon as they have been opened.
    |
    |"""

    .

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gilmeh Serda@21:1/5 to Paulo da Silva on Sun Oct 23 15:12:18 2022
    On Sat, 22 Oct 2022 21:58:09 +0100, Paulo da Silva wrote:

    5.
    Any other ...

    I believe the latest idea is:

    def foo(a: some_type, b: some_type) -> some_return_type:
    """ A description.
    """
    # function body
    return value_of_some_return_type

    --
    Gilmeh

    A prisoner of war is a man who tries to kill you and fails, and then asks
    you not to kill him. -- Sir Winston Churchill, 1952

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Karsten Hilbert@21:1/5 to All on Sun Oct 23 20:37:46 2022
    Am Sat, Oct 22, 2022 at 09:49:55PM -0400 schrieb Thomas Passin:

    def make_title_from_headline(self, p, h):
    """From node title, return title with over- and underline- strings.
    ...
    RETURNS
    a string
    """
    ....
    def plot(self, stackposition=MAIN, clearFirst=True):
    """Plot a 2-D graph.
    ...
    RETURNS
    nothing
    """

    Would it not, these days, be clearer to

    def make_title_from_headline(self, p, h) -> str:

    def plot(self, stackposition=MAIN, clearFirst=True) -> None:

    and use RETURNS (or Returns:) only when what is returned
    warrants further explanation (say, as to what is returned
    when).

    Karsten
    --
    GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paulo da Silva@21:1/5 to All on Sun Oct 23 21:20:43 2022
    Às 21:58 de 22/10/22, Paulo da Silva escreveu:
    Hi all!

    What is the correct way, if any, of documenting a function/method?


    Thank you all for the, valuable as usual, suggestions.
    I am now able to make my choices.

    Paulo

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Karsten Hilbert@21:1/5 to as I on Sun Oct 23 23:49:22 2022
    Am Sun, Oct 23, 2022 at 05:16:48PM -0400 schrieb Thomas Passin:

    def make_title_from_headline(self, p, h) -> str:

    def plot(self, stackposition=MAIN, clearFirst=True) -> None:

    1. Knowing the type of a parameter isn't all you usually want to know;

    Sure, as I said:

    and use RETURNS (or Returns:) only when what is returned
    warrants further explanation (say, as to what is returned
    when).

    same for arguments, which *usually* warrant some further
    explanation, except for rare cases such as

    def format_a_string(string2format:str=None) -> str:

    where string2format just might not require further
    explanation.

    2. If the type information isn't in the docstring, it won't be reported by reporting
    tools that use the docstring.

    While true such tools could be considered suboptimal (these
    days, again as I said).

    Then there are all those cases where the signature hasn't been type-annotated

    True but OPs question was *how* to document so there's no
    perceived problem with having to document.

    I would say that if the types are annotated, the method is simple enough, and the names
    are clear enough, sure, go ahead and rely on the type annotations. The most important
    thing is that readers can understand what the arguments and returns are intended to be,
    so some flexibility makes sense.

    +1

    Karsten
    --
    GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Passin@21:1/5 to Karsten Hilbert on Sun Oct 23 17:16:48 2022
    On 10/23/2022 2:37 PM, Karsten Hilbert wrote:
    Am Sat, Oct 22, 2022 at 09:49:55PM -0400 schrieb Thomas Passin:

    def make_title_from_headline(self, p, h):
    """From node title, return title with over- and underline- strings.
    ...
    RETURNS
    a string
    """
    ....
    def plot(self, stackposition=MAIN, clearFirst=True):
    """Plot a 2-D graph.
    ...
    RETURNS
    nothing
    """

    Would it not, these days, be clearer to

    def make_title_from_headline(self, p, h) -> str:

    def plot(self, stackposition=MAIN, clearFirst=True) -> None:

    and use RETURNS (or Returns:) only when what is returned
    warrants further explanation (say, as to what is returned
    when).

    It might, but remember:

    1. Knowing the type of a parameter isn't all you usually want to know;
    2. If the type information isn't in the docstring, it won't be reported
    by reporting tools that use the docstring.

    Then there are all those cases where the signature hasn't been
    type-annotated, either because adding them to existing code would be a
    big burden, or because the developer feels it's too much trouble, all
    things considered.

    I would say that if the types are annotated, the method is simple
    enough, and the names are clear enough, sure, go ahead and rely on the
    type annotations. The most important thing is that readers can
    understand what the arguments and returns are intended to be, so some flexibility makes sense.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Schachner, Joseph (US)@21:1/5 to All on Mon Oct 24 13:07:58 2022
    SSBoZWFkIGEgc21hbGwgc29mdHdhcmUgdGVhbSBtdWNoIG9mIHdob3NlIG91dHB1dCBpcyBQeXRo b24uICAgSSB3b3VsZCBncmF0ZWZ1bGx5IGFjY2VwdCBhbnkgb2YgdGhlIGZvcm1hdHMgeW91IHNo b3cgYmVsb3cuICBNeSBwcmVmZXJlbmNlIGlzICMxLg0KDQotLS0gSm9zZXBoIFMuDQoNCg0KVGVs ZWR5bmUgQ29uZmlkZW50aWFsOyBDb21tZXJjaWFsbHkgU2Vuc2l0aXZlIEJ1c2luZXNzIERhdGEN Cg0KLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCkZyb206IFBhdWxvIGRhIFNpbHZhIDxwX2Rf YV9zX2lfbF92X2FfbnNAbm9uZXRub2FkZHJlc3MucHQ+IA0KU2VudDogU2F0dXJkYXksIE9jdG9i ZXIgMjIsIDIwMjIgNDo1OCBQTQ0KVG86IHB5dGhvbi1saXN0QHB5dGhvbi5vcmcNClN1YmplY3Q6 IEEgdHJpdmlhbCBxdWVzdGlvbiB0aGF0IEkgZG9uJ3Qga25vdyAtIGRvY3VtZW50IGEgZnVuY3Rp b24vbWV0aG9kDQoNCkhpIGFsbCENCg0KV2hhdCBpcyB0aGUgY29ycmVjdCB3YXksIGlmIGFueSwg b2YgZG9jdW1lbnRpbmcgYSBmdW5jdGlvbi9tZXRob2Q/DQoNCjEuDQpkZWYgZm9vKGEsYik6DQoJ IiIiIEEgZGVzY3JpcHRpb24uDQoJYTogV2hhdGV2ZXIgMQ0KCWI6IFdoYXRldmVyIDINCgkiIiIN CgkuLi4NCg0KMi4NCmRlZiBmb28oYSxiKToNCgkiIiIgQSBkZXNjcmlwdGlvbi4NCglhIC0tIFdo YXRldmVyIDENCgliIC0tIFdoYXRldmVyIDINCgkiIiINCgkuLi4NCg0KMy4NCmRlZiBmb28oYSxi KToNCgkiIiIgQSBkZXNjcmlwdGlvbi4NCglAcGFyYW0gYTogV2hhdGV2ZXIgMQ0KCUBwYXJhbSBi OiBXaGF0ZXZlciAyDQoJIiIiDQoJLi4uDQoNCjQuDQpkZWYgZm9vKGEsYik6DQoJIiIiIEEgZGVz Y3JpcHRpb24uDQoJOnBhcmFtIGE6IFdoYXRldmVyIDENCgk6cGFyYW0gYjogV2hhdGV2ZXIgMg0K CSIiIg0KCS4uLg0KDQo1Lg0KCUFueSBvdGhlciAuLi4NCg0KQW55IGNvbW1lbnRzL3N1Z2dlc3Rp b25zIGFyZSB3ZWxjb21lLg0KVGhhbmtzLg0KUGF1bG8NCg0K

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mats Wichmann@21:1/5 to Paulo da Silva on Mon Oct 24 11:17:29 2022
    On 10/23/22 14:20, Paulo da Silva wrote:
    Às 21:58 de 22/10/22, Paulo da Silva escreveu:
    Hi all!

    What is the correct way, if any, of documenting a function/method?


    Thank you all for the, valuable as usual, suggestions.
    I am now able to make my choices.

    Paulo

    It also matters whether you expect the docstring to stand on its own, or
    to be processed by a doc-generation tool (like Sphinx). In the former
    case, make it look nice in a way that suits you. In the latter case, use
    the reStructuredText conventions that exist (there are at least three
    common styles) for the document processor. While these styles are
    intended to also be very human-readable, they may not be exactly how you wanted to format things for visual display when looking directly at
    code, so it's worth thinking about this up front.

    See for example:

    https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)