Python – Is It Poor Practice to Have Dynamically Updated Docstrings?

documentationpython

When I'm creating a docstring, sometimes I want to refer to a value, for instance:

def try_download(data, path):
    """Tries to download ATTEMPTS times, catching socket errors."""

Where ATTEMPTS is just a constant int defined at the start of the file. But would it be better to write it so that it's generating a string actually indicating what the value is, ie.

def try_download(data, path):
    """Tries to download {} times, catching socket errors.""".format(ATTEMPTS)

The advantage to this, would be that someone else reading dynamically from the function would get a more helpful message indicating the actual number. However someone reading the actual script has a slightly less readable sentence. There's also a degree of danger that this makes the docstring error prone in that errors could occur, but in reality if it's replaced by a number that can't be printed, the actual function will have bigger problems than it's docstring.

So is this worrying over nothing, or is it better to stay safe and not insert variables into docstrings?

Best Answer

The approach you're describing doesn't actually produce a docstring. It doesn't result in the __doc__ property of the function being set, which means that it's not available to the help function, and wouldn't be available to (typical) automated documentation generators. Here's a simple example that shows this in action. First, a function with a "traditional" docstring:

>>> def bar():
    "some value: 42"
    return 42

>>> bar.__doc__
'some value: 42'

>>> help(bar)
Help on function bar in module __main__:

bar()
    some value: 42

Note that the __doc__ property is set, and help will show the contents of that string. Now, let's try with the dynamically generated "docstring". I put docstring in scare quotes because it's not actually a docstring.

>>> def foo():
    "some value: {}".format(3)
    return 42

>>> foo.__doc__

>>> help(foo)
Help on function foo in module __main__:

foo()

There's no value for foo.__doc__, and help doesn't display anything aside from the function declaration, which means that the system didn't interpret the value as a docstring. That's not really surprising, since the first expression in the function body isn't a string, it's a function call to a member function of a string.

So, to answer the questions,

Is it poor practice to have dynamically updated docstrings?

There are ways to dynamically update a docstring, viz., by setting the __doc__ property of the function, but that's not what your approach is doing. Whether it's good or bad practice probably depends on the application. If you're dynamically generating some functions and want to programatically assign documentation to them, it might be fine. In the way that you're describing though, it simply doesn't work.

The advantage to this, would be that someone else reading dynamically from the function would get a more helpful message indicating the actual number.

It depends on what you mean by "reading dynamically from the function". It might be helpful to someone reading the source, but it's definitely not helpful to someone who is looking at the output of help, or who is reading the value of the __doc__ property.

Related Topic