Yes, you only need the type hints OR the annotations in the Args and Returns, not both.


References

According to the Google Python Style Guide: "The description should include required type(s) if the code does not contain a corresponding type annotation."

The Sphinx Docs also encourage this in their example code:


def function_with_pep484_type_annotations(param1: int, param2: str) -> bool:
    """Example function with PEP 484 type annotations.

    Args:
        param1: The first parameter.
        param2: The second parameter.

    Returns:
        The return value. True for success, False otherwise.

    """
Answer from Kris Gesling on Stack Overflow
🌐
Google
google.github.io › styleguide › pyguide.html
Google Python Style Guide
No: Python("Why are you hiding your eyes?") Gollum('The lint. It burns. It burns us.') Gollum("Always the great lint. Watching. Watching.") Prefer """ for multi-line strings rather than '''. Projects may choose to use ''' for all non-docstring multi-line strings if and only if they also use ' for regular strings.
🌐
Readthedocs
sphinxcontrib-napoleon.readthedocs.io › en › latest › example_google.html
Example Google Style Python Docstrings — napoleon 0.7 documentation
# -*- coding: utf-8 -*- """Example Google style docstrings. This module demonstrates documentation as specified by the `Google Python Style Guide`_. Docstrings may extend over multiple lines. Sections are created with a section header and a colon followed by a block of indented text.
Discussions

python - Type annotations with google style docstrings - Stack Overflow
When using google style docstrings and type annotations there's a double up of the type hints. Is there any community consensus on how to avoid this? Annoying double up of types: def sum(a: int, b:... More on stackoverflow.com
🌐 stackoverflow.com
My thoughts on docstrings, pdoc and Google style vs. Markdown
Stick with Google style, rely on type hints, and use pdoc now; switch to Sphinx or MkDocs later if you need broader tooling support. I’ve done this on a few libs: Google-style docstrings for Args/Returns/Raises, types only in hints, and pdoc for quick HTML. When you outgrow it, Sphinx + Napoleon + autodoc-typehints is solid; set napoleonincludeinitwithdoc = True and napoleonattrannotations = True so attributes and init land where you expect. If you prefer Markdown output, MkDocs + mkdocstrings (griffe backend) reads Google/NumPy cleanly and keeps IDEs happy. Lint your docs so they don’t drift: pydocstyle checks presence, and pydoclint (or darglint if you’re okay with archived) catches mismatches between signatures and docstrings. Add a pre-commit that runs pdoc and fails on warnings. For attribute docs discoverable at runtime, consider properties with docstrings or dataclasses with metadata; the post-assignment string trick won’t show in help(). I’ve used Sphinx for library docs and MkDocs+mkdocstrings for sites, and DreamFactory when I needed instant REST APIs with OpenAPI that fed into Postman. So go Google style with type hints, pdoc for speed now, and Sphinx/MkDocs if tooling or IDE support becomes critical. More on reddit.com
🌐 r/learnpython
9
2
September 18, 2025
coding style - What are the most common Python docstring formats? - Stack Overflow
You can add sphinx google style example as well. Great answer btw. EDIT: I edited your answer by myself. 2016-07-07T11:09:09.5Z+00:00 ... good answer. I dare say where you can change default docstring format in PyCharm (JetBrains): Settings --> Tools --> Python Integrated Tools --> Docstring format. More on stackoverflow.com
🌐 stackoverflow.com
documentation - Python Google-Style DocString for Function with No Arguments - Stack Overflow
I've been using the Google-Style Python Docstring format for a while now. The way I've been handling functions/methods with no arguments suddenly doesn't look correct to me. I did a bit of searchin... More on stackoverflow.com
🌐 stackoverflow.com
🌐
GitHub
gist.github.com › redlotus › 3bc387c2591e3e908c9b63b97b11d24e
Google Style Python Docstrings · GitHub
Google Style Python Docstrings. GitHub Gist: instantly share code, notes, and snippets.
🌐
Rutgers
iw3.math.rutgers.edu › solutions › example_google.html
Example Google Style Python Docstrings — Solutions 0.0.1 documentation
Docstring after attribute, with type specified. ... Class methods are similar to regular functions. ... Do not include the self parameter in the Args section. ... True if successful, False otherwise. ... list of str: Properties with both a getter and setter should only be documented in their getter method. If the setter method contains notable behavior, it should be mentioned here. exception example_google.ExampleError(msg, code)[source]
🌐
Mit
drake.mit.edu › styleguide › pyguide.html
Google Python Style Guide for Drake
Files should start with a docstring describing the contents and usage of the module. ```python """A one-line summary of the module or program, terminated by a period. Leave one blank line. The rest of this docstring should contain an overall description of the module or program.
Find elsewhere
🌐
Reddit
reddit.com › r/learnpython › my thoughts on docstrings, pdoc and google style vs. markdown
r/learnpython on Reddit: My thoughts on docstrings, pdoc and Google style vs. Markdown
September 18, 2025 -

So, I wanted to add some API documentation to my project. Unfortunately, there are many competing standards/styles and many tools to generate HTML documentation.

Initially I chose pdoc, as it seems simple, does the job well and requires zero configuration. So far, so good. The problem is that is doesn't FULLY support ANY of the most popular docstring standards - ReStructuredText, Google, NumPy; instead, it uses its own style based on Markdown. I actually find it nice & clean, because:

  • you don't need to specify variable/attribute/arg types if you already have type hints in your code

  • you document instance/class variables right after they are declared (not in class docstring)

  • similarly, you document _init__ constructor right after it is declared, not in the class docstring

The problem is that - besides pdoc itself - no one really recognizes its Markdown standard. It's not supported by PyCharm, pyment, pymend, nor by other tools.

However! According to Sphinx/Napoleon Example Google Style Python Docstrings, it is totally possible to use the Google docstrings style in a similar way - i.e, the 3 bullet points above would still work!

So, I could simply use Google style (which is a recognized standard) in a way I would use pdoc's Markdown. The only thing to make sure is not to use the Attributes: and Methods: sections in class docstring, as it would appear as duplicate in generated HTML. I would still use sections Args: Returns: Yields: and Raises: in function docstrings, where applicable.

And my commandline to run pdoc would be:

pdoc modulename -o docs --docformat google --no-show-source

What do you guys think?

PS. One minor downside of placing docstrings after variable declarations is that they do NOT become __doc__, as they do in the case of modules, classes and functions. So, these comments would not be discoverable programmatically (or interactively via help()). But I guess it doesn't matter that much...

🌐
Real Python
realpython.com › how-to-write-docstrings-in-python
How to Write Docstrings in Python – Real Python
June 19, 2025 - Google-style docstrings provide a clean, structured way to document your code, especially when it’s concerned with multiple parameters or returns complex values. They became popular through Google’s Python projects and other large codebases.
🌐
Google
android.googlesource.com › platform › external › google-styleguide › + › refs › tags › android-s-beta-2 › pyguide.md
Google Python Style Guide
A docstring should give enough information to write a call to the function without reading the function‘s code. The docstring should be descriptive-style ("""Fetches rows from a Bigtable.""") rather than imperative-style ("""Fetch rows from a Bigtable."""), except for @property data descriptors, ...
🌐
Sphinx
sphinx-doc.org › en › master › usage › extensions › napoleon.html
sphinx.ext.napoleon – Support for NumPy and Google style docstrings — Sphinx documentation
Google style tends to be easier to read for short and simple docstrings, whereas NumPy style tends be easier to read for long and in-depth docstrings. The choice between styles is largely aesthetic, but the two styles should not be mixed. Choose one style for your project and be consistent with it.
Top answer
1 of 6
1389

Formats

Python docstrings can be written following several formats as the other posts showed. However the default Sphinx docstring format was not mentioned and is based on reStructuredText (reST). You can get some information about the main formats in this blog post.

Note that the reST is recommended by the PEP 287

There follows the main used formats for docstrings.

- Epytext

Historically a javadoc like style was prevalent, so it was taken as a base for Epydoc (with the called Epytext format) to generate documentation.

Example:

"""
This is a javadoc style.

@param param1: this is a first param
@param param2: this is a second param
@return: this is a description of what is returned
@raise keyError: raises an exception
"""

- reST

Nowadays, the probably more prevalent format is the reStructuredText (reST) format that is used by Sphinx to generate documentation. Note: it is used by default in JetBrains PyCharm (type triple quotes after defining a method and hit enter). It is also used by default as output format in Pyment.

Example:

"""
This is a reST style.

:param param1: this is a first param
:param param2: this is a second param
:returns: this is a description of what is returned
:raises keyError: raises an exception
"""

- Google

Google has their own format that is often used. It also can be interpreted by Sphinx (ie. using Napoleon plugin).

Example:

"""
This is an example of Google style.

Args:
    param1: This is the first param.
    param2: This is a second param.

Returns:
    This is a description of what is returned.

Raises:
    KeyError: Raises an exception.
"""

Even more examples

- Numpydoc

Note that Numpy recommend to follow their own numpydoc based on Google format and usable by Sphinx.

"""
My numpydoc description of a kind
of very exhautive numpydoc format docstring.

Parameters
----------
first : array_like
    the 1st param name `first`
second :
    the 2nd param
third : {'value', 'other'}, optional
    the 3rd param, by default 'value'

Returns
-------
string
    a value in a string

Raises
------
KeyError
    when a key error
OtherError
    when an other error
"""

Converting/Generating

It is possible to use a tool like Pyment to automatically generate docstrings to a Python project not yet documented, or to convert existing docstrings (can be mixing several formats) from a format to an other one.

Note: The examples are taken from the Pyment documentation

2 of 6
354

The Google style guide contains an excellent Python style guide. It includes conventions for readable docstring syntax that offers better guidance than PEP-257. For example:

def square_root(n):
    """Calculate the square root of a number.

    Args:
        n: the number to get the square root of.
    Returns:
        the square root of n.
    Raises:
        TypeError: if n is not a number.
        ValueError: if n is negative.

    """
    pass

I like to extend this to also include type information in the arguments, as described in this Sphinx documentation tutorial. For example:

def add_value(self, value):
    """Add a new value.

       Args:
           value (str): the value to add.
    """
    pass
🌐
Readthedocs
gemseo.readthedocs.io › en › 5.3.2 › software › example_google_docstring.html
Example Google Style Docstrings — GEMSEO 5.3.2 documentation
For the __init__ method only: add to the return type annotation another comment to discard the legit style checks for missing docstring parts, the comment shall be """ # noqa: D205, D212, D415 self.attr1 = arg1 self.attr2 = arg2 self._attr3 = arg3 @property def readonly_property(self) -> str: """Property is documented in the getter method.""" return "readonly_property" @property def readwrite_property(self) -> list[str]: """Property with both getter and setter is only documented in the getter method.
Top answer
1 of 4
12

Package

The code described in the following section have now been made available in a separate package. Please see this repository for details: https://github.com/Xaldew/yasnippet-radical-snippets.


Old Answer

I use the package called yasnippet for something similar to this. After some minor changes I adapted it to use the the Google docstring style instead:

Do note however that it requires some setup:

The snippet itself needs to execute some utility elisp code to generate the text. This is typically solved by creating a file called .yas-setup.el with the code inside the python-mode snippet directory. It is however also possible to place the code somewhere inside your .emacs instead.

The code for the snippet is:

# -*- mode: snippet -*-
# Insert Google style docstring and function definition.
# name: Python Google style Docstring
# key: defg
# type: snippet
# contributor: Xaldew
# --
def ${1:name}($2):
    \"\"\"$3
    ${2:$(python-args-to-google-docstring yas-text t)}
    ${5:Returns:
        $6
}
    \"\"\"
    ${0:$$(let ((beg yas-snippet-beg)
                (end yas-snippet-end))
        (yas-expand-snippet
          (buffer-substring-no-properties beg end) beg end
              (quote ((yas-indent-line nil) (yas-wrap-around-region nil))))
            (delete-trailing-whitespace beg (- end 1)))}

The code for the .yas-setup.el is:

(defun python-args-to-google-docstring (text &optional make-fields)
  "Return a reST docstring format for the python arguments in yas-text."
  (let* ((indent (concat "\n" (make-string (current-column) 32)))
         (args (python-split-args text))
     (nr 0)
         (formatted-args
      (mapconcat
       (lambda (x)
         (concat "   " (nth 0 x)
             (if make-fields (format " ${%d:arg%d}" (cl-incf nr) nr))
             (if (nth 1 x) (concat " \(default " (nth 1 x) "\)"))))
       args
       indent)))
    (unless (string= formatted-args "")
      (concat
       (mapconcat 'identity
          (list "" "Args:" formatted-args)
          indent)
       "\n"))))

Note that python-split-args is provided by the standard snippets. I.e.: https://github.com/AndreaCrotti/yasnippet-snippets/tree/master You do however get those by default when you install the package through package.el.

With everything setup properly, you should be able to write "defg" followed by Tab to expand the snippet (See the image for an example).

There is still an issue with using this inside nested indentation, e.g., within classes or as nested functions. In those cases the docstring is erroneously indented an extra time for some reason. I'll update this post if I manage to fix that.

The snippet should now work inside other scopes by forbidding yasnippet from auto-indenting the second expansion.

2 of 4
3

As lunaryorn mentioned that style is not popular and there aren't any packages.

However there is a package called sphinx-doc which will generate doc string in sphinx format(demo).

You can modify that package to generate strings as per your requirement.

🌐
Readthedocs
gemseo.readthedocs.io › en › stable › software › example_google_docstring.html
Example Google Style Docstrings — GEMSEO 6.3.0 documentation
For the __init__ method only: add to the return type annotation another comment to discard the legit style checks for missing docstring parts, the comment shall be """ # noqa: D205, D212, D415 self.attr1 = arg1 self.attr2 = arg2 self._attr3 = arg3 @property def readonly_property(self) -> str: """Property is documented in the getter method.""" return "readonly_property" @property def readwrite_property(self) -> list[str]: """Property with both getter and setter is only documented in the getter method.
🌐
JetBrains
youtrack.jetbrains.com › issue › PY-9795
Support for Google Style Python docstrings : PY-9795
April 12, 2022 - {{ (>_<) }} This version of your browser is not supported. Try upgrading to the latest stable version. Something went seriously wrong
Top answer
1 of 2
8

Assuming you would like to use napoleon to render your docstrings into docs, the sphinx developers are working towards a way to add custom sections to class-level docstrings (see Issue #33).

Currently, in the Google Style Docstrings Example, the class ExamplePEP526Class example states

If the class has public attributes, they may be documented here in an Attributes section and follow the same formatting as a function's Args section. If napoleon_attr_annotations is True, types can be specified in the class body using PEP 526 annotations.

PEP 526 added variable annotations to type hints. Hence, your code could now be written:

"""Sandbox module"""

class Toto:
    """ This class is an example

    Attributes:
        class_attribute (str): (class attribute) The class attribute
        instance_attribute (str): The instance attribute
    """

    class_attribute: str = ""

    def __init__(self):
        self.instance_attribute: str = ""

For one thing, it seems you forgot to put the type hint str after class_attribute when defining it, so mypy (if using an external type checker) probably couldn't discover its type.

Ironically, the reverse situation would have worked: in napoleon version 3.4, if napoleon_attr_attributes is set to True, then

If an attribute is documented in the docstring without a type and has an annotation in the class body, that type is used.

Second, the pass at the end of your __init__ method is allowed, but unnecessary since you define instance_attribute there.

I mention Issue #33 because, personally, I would rather call the heading "Class Variables" as "Attributes" by itself doesn't distinguish between instance vs. class attributes/variables. For the time being, you may want to put your own notation in the attribute description like I have done.

For me, I either have fewer class attributes than instance attributes or none at all, so I only note if an attribute is a class attribute (otherwise, it is an instance attribute). That way, I don't have to write (instance attribute) next to all my instance attributes. Alternatively, you could try putting class in the parentheses with the type the same what that optional is listed:

class_attribute (str, class): The class attribute

I'm not sure if that will work or break. If it breaks, it would certainly be nice to have added to the docstring syntax in the future (I think this looks cleaner).

Lastly, you could document the class variable as an attribute docstring as defined in PEP 257 as well as this SO answer by putting a docstring directly underneath the assignment like so:

"""Sandbox module"""

class Toto:

    class_attribute: str = ""
    """class_attribute (str): (class attribute) The class attribute"""

    def __init__(self):
        """ This class is an example
    
        Attributes:
            instance_attribute (str): The instance attribute
        """
        self.instance_attribute: str = ""
2 of 2
-2

Try this:

"""
    Sandbox module
    ~~~~~~~~~~~~~~
"""

class Toto:
    """This class is an example

    Attributes:
        instance_attribute (str): The instance attribute #OK
    """
    
    #: str: The class attribute #Unresolved reference
    class_attribute = ""

    def __init__(self):
        self.instance_attribute = ""
        pass

This works fine for me using sphinx.

🌐
Better Programming
betterprogramming.pub › 3-different-docstring-formats-for-python-d27be81e0d68
3 Different Docstring Formats for Python | by Yash Salvi | Better Programming
April 27, 2022 - NumPy style tends to require more vertical space, whereas Google-style tends to use more horizontal space. Google-style tends to be easier to read for short and simple docstrings, whereas NumPy-style tends to be easier to read for long and in-depth ...
🌐
Readthedocs
gemseo.readthedocs.io › en › 6.0.0 › software › example_google_docstring.html
Example Google Style Docstrings — GEMSEO 6.0.0 documentation
For the __init__ method only: add to the return type annotation another comment to discard the legit style checks for missing docstring parts, the comment shall be """ # noqa: D205, D212, D415 self.attr1 = arg1 self.attr2 = arg2 self._attr3 = arg3 @property def readonly_property(self) -> str: """Property is documented in the getter method.""" return "readonly_property" @property def readwrite_property(self) -> list[str]: """Property with both getter and setter is only documented in the getter method.