Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 96 additions & 1 deletion doc/source/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,99 @@ linear models are always welcome.
**Github**

Fork the repo, make a branch with your new feature/documentation/typos
and submit a pull request.
and submit a pull request.

.. _docstring-conventions:

Docstring conventions
~~~~~~~~~~~~~~~~~~~~~

Docstrings use the `numpydoc <https://numpydoc.readthedocs.io/en/latest/format.html>`_
format. Every module, class, function, method and property needs one, unless its name
starts with an underscore. Apply these nine rules to every docstring that you write or
change.

1. Put ``, optional`` after the type of every parameter that has a default. The default
value goes in the description, never in the type line.
2. Write a union of types as ``int or str``. Use curly braces only for a set of literal
values, written with plain quotes: ``{"robust", "unadjusted"}``. List every value that
the code accepts, aliases included.
3. Do not subscript types. Write ``list of str`` and ``dict of str to DataFrame``, not
``list[str]`` and ``dict[str, DataFrame]``.
4. ``array_like`` means that the value is converted with ``np.asarray`` and then used as
an array. ``ndarray`` means that it must already be an array. ``sequence of X`` means
that it is only iterated over or indexed.
5. Use ``bool``, ``int``, ``str`` and ``callable``, not ``boolean``, ``integer``,
``string`` or ``function``. Document ``**cov_config`` and ``**weight_config`` with
their stars, and list their keys.
6. Use the standard section names only, with underlines exactly as long as the header.
Write ``See Also``, not ``See also``. In order, the sections are ``Parameters``,
``Attributes``, ``Methods``, ``Returns``, ``Yields``, ``Other Parameters``,
``Raises``, ``Warns``, ``Warnings``, ``See Also``, ``Notes``, ``References`` and
``Examples``.
7. A ``Returns`` section gives concrete types, such as ``Series`` or ``IVResults``. It
names what the function returns, not what it accepts.
8. Every documented parameter exists, and every parameter is documented, in the order of
the signature.
9. A real bug that you find while editing a docstring goes in its own ``BUG`` commit.

For example:

.. code-block:: text

Parameters
----------
cats : DataFrame or array_like
Category codes of pandas categoricals, with shape (nobs, ncats).
output_format : {"csc", "csr", "coo"}, optional
Format of the sparse output. The default is ``"csc"``.
drop : {"first", "last"}, optional
Whether to exclude the first or the last category. The default is ``"first"``.

Checking docstrings
^^^^^^^^^^^^^^^^^^^

``numpydoc lint`` checks docstrings. It needs numpydoc 1.10 or later. Run it from the
root of the repository. It prints one line for each violation, and exits with status 1 if
there is any violation:

.. code-block:: bash

python -m pip install "numpydoc>=1.10"
python -m numpydoc lint $(git ls-files "linearmodels/*.py") --config .

In PowerShell, write ``(git ls-files "linearmodels/*.py")`` for the file list. To check
only some files, pass their paths instead. On Windows, also run Python in UTF-8 mode, for
example with ``python -X utf8``, because numpydoc reads the files with the system
encoding and some docstrings contain non-ASCII characters.

The ``[tool.numpydoc_validation]`` table in ``pyproject.toml`` sets what is checked.

* Every numpydoc check is enforced except ``ES01`` (no extended summary), ``SA01`` (no
``See Also`` section) and ``EX01`` (no ``Examples`` section). The enforced checks
include the punctuation of summaries and of parameter and return descriptions
(``SS03``, ``PR08``, ``PR09``, ``RT04`` and ``RT05``), the description of every
``See Also`` entry (``SA04``), parameters that match the signature (``PR01``, ``PR02``
and ``PR03``), and the names and order of the sections (``GL06`` and ``GL07``).
Numpydoc does not check rules 1 to 4 and 9, the keys listed under rule 5 or the types
named under rule 7. Check them in review.
* Module docstrings are required (``GL08`` applies to modules), including the docstrings
of ``__init__.py`` files. One line is enough.
* The linter skips tests, ``conftest.py``, ``_version.py``, special methods such as
``__init__`` (document the constructor in the class docstring), functions defined
inside other functions, and every name with a leading underscore. The exceptions are
the public members of private base classes, such as ``_IVModelBase.predict``, which the
reference pages show on the public subclasses, and ``_OLS``, ``_Panel`` and
``LinearConstraint``, which the reference pages list.
* The linter cannot see decorators, so it asks for a ``Returns`` section and an infinitive
verb in the summary of every property. The configuration ignores both checks for a
docstring without a ``Parameters`` section, so a property needs only a summary. A
method without parameters that returns a value, such as ``PanelData.copy``, still needs
a ``Returns`` section, but the linter does not check it.
``python -m numpydoc validate linearmodels.panel.data.PanelData.copy`` does; ignore
``ES01``, ``SA01`` and ``EX01`` in its output.
* Some declarations cannot satisfy the linter. A property setter and an ``@overload``
stub cannot have a docstring that is shown in the documentation: write
``# numpydoc ignore=GL08`` on its ``def`` line. A ``NamedTuple`` has no ``__init__``, so
the linter reports its fields as unknown parameters: document them under ``Parameters``
and write ``# numpydoc ignore=PR02`` on its ``class`` line.
44 changes: 44 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,50 @@ force_sort_within_sections=true
include_trailing_comma=true
use_parentheses=true

[tool.numpydoc_validation]
# Docstring lint. Run it from the repository root with
# python -m numpydoc lint $(git ls-files "linearmodels/*.py") --config .
# The rules are in "Docstring conventions" in doc/source/contributing.rst.
# Needs numpydoc 1.10 or later, which added exclude_files.
#
# Every check except the extended summary (ES01), See Also (SA01) and Examples (EX01).
checks = ["all", "ES01", "SA01", "EX01"]

# Files that are not linted. The patterns are matched at the start of the path as it
# is given on the command line, and accept both / and \ as the separator.
exclude_files = [
# Tests
'(?:.*[/\\])?tests[/\\]',
'(?:.*[/\\])?conftest\.py$',
# Generated and build files
'(?:.*[/\\])?_version\.py$',
'(?:.*[/\\])?_build[/\\]',
]

# Objects that are not linted. The patterns are searched in the dotted name of the
# object, which is the file name without .py, the class and the member. For example,
# the name of IVGMM.fit in linearmodels/iv/model.py is model.IVGMM.fit.
exclude = [
# Special methods, such as __init__. The class docstring documents the constructor.
'\.__\w+__$',
# Private functions, methods and properties, and everything defined inside them.
'\._[a-z0-9]',
# Private classes, except _OLS and _Panel, which the reference pages list. The public
# members of private base classes, such as _IVModelBase.predict, are linted because
# the documentation shows them on the public subclasses.
'\._(?!OLS$|Panel$)[A-Z][^.]*$',
# Private modules, except LinearConstraint, which the reference pages list.
'^_[a-z0-9][^.]*(\.(?!LinearConstraint(\.|$)).*)?$',
# Functions defined inside other functions or methods.
'^[^.]+\.(?:[^.]+\.)*_*[a-z][^.]*\.[^.]+$',
]

# numpydoc lint cannot see decorators, so it asks every property for a Returns section and
# for a summary that starts with an infinitive verb. Ignore both checks for docstrings
# without a Parameters section, which are the docstrings of properties.
override_RT01 = ['\A(?![\s\S]*\nParameters\n-+\n)']
override_SS05 = ['\A(?![\s\S]*\nParameters\n-+\n)']

[tool.coverage.run]
source = [ "linearmodels" ]
branch = true
Expand Down
Loading