How to specify that a parameter is a list of specific objects in Python docstrings

Question:

I really like using docstrings in Python to specify type parameters when projects get beyond a certain size.

I’m having trouble finding a standard to use to specify that a parameter is a list of specific objects, e.g. in Haskell types I’d use [String] or [A].

Current standard (recognisable by PyCharm editor):

def stringify(listOfObjects):
    """
    :type listOfObjects: list
    """
    return ", ".join(map(str, listOfObjects))

What I’d prefer:

OPTION 1

def stringify(listOfObjects):
    """
    :type listOfObjects: list<Object>  
    """
    return ", ".join(map(str, listOfObjects))

OPTION 2

def stringify(listOfObjects):
    """
    :type listOfObjects: [Object]
    """
    return ", ".join(map(str, listOfObjects))

I suppose that wasn’t a great example – the more relevant use case would be one where the objects in the list must be of a specific type.

BETTER EXAMPLE

class Food(Object):
    def __init__(self, calories):
        self.calories = calories

class Apple(Food):
    def __init__(self):
        super(self, 200)

class Person(Object):
    energy = 0
    def eat(foods):
        """
        :type foods: [Food]  # is NOT recognised by editor
        """
        for food in foods:
            energy += food.calories

So, other than the fact that I’m getting hungry, this example illustrates that if called with a list of the wrong kind of object, the code would break. Hence the importance of documenting not only that it needs a list, but that it needs a list of Food.

RELATED QUESTION
How can I tell PyCharm what type a parameter is expected to be?
Please note that I’m looking for a more specific answer than the one above.

Asked By: Alex

||

Answers:

in python

type([1,2,3]) == type(['a', 'b', 'c'])

you can also add a string to list of ints.

So for what you are trying to achieve PyCharm would have to magically check your whole code for what you are adding to the list before passing it as argument.

You can take a look at this question Python : define a list of a specific type of object

Array module however allows only ‘basic values’.

Only solution i can think of here is to create your own class that extends python list “FoodsList” that can check for type before adding element.

class Food():
    def __init__(self, calories):
        self.calories = calories

class FoodsList(list):
    #you can optionally extend append method here to validate type
    pass

def eat(foods):
    """
    :type foods: FoodsList
    """
    energy = 0
    for food in foods:
        energy += food.calories
    return energy


list = FoodsList()
list.append(Food(3))
list.append(Food(4))
print eat(list)
Answered By: fsw

In comments section of PyCharm’s manual there’s a nice hint from developer:

#: :type: dict of (str, C)
#: :type: list of str

It works for me pretty well. Now it makes me wonder what’s the best way to document parametrized classes in Python :).

Answered By: Michael Korbakov

When writing docstrings in the google style you can do:

class ToDocument(object):
    """This is my Documentation.

    Args:
        typed_list (:obj:`list` of :obj:`str`): Description of typed list

    """
    ...

This also works pretty fine in sphinx, when combined with the napoleon-extension. Refer to the extension’s doc for more examples on documentation.

Answered By: Kim

As pointed out in the PyCharm docs, a (legacy, pre-PEP-484) way of doing this is using square brackets:

list[Foo]: List of Foo elements

dict[Foo, Bar]: Dict from Foo to Bar

list of str, as suggested in the accepted answer, does not work as expected in PyCharm.

Starting with Python 3.5 and the implementation of PEP-484, you can also use type hints, which may be nicely supported by your IDE/editor. How this is easily done in PyCharm is explained here.

In essence, to declare a list return type using type-hinting (Python >=3.5), you may do something like this:

from typing import List

"""
Great foo function.

:rtype: list[str]
"""
def foo() -> List[str]:
    return ['some string', 'some other string']

Here we declare (somewhat redundantly) that the function foo returns a list of strings, both in the type hint -> List[str] and in the docstring :rtype: list[str].

Other pre-declared types and more info can be found in the Python docs for typing.

Answered By: Hendrik
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.