manim/docs/source/contributing/documentation.rst
Jason Villanueva e384ce93f2
Added testing/documentation from GitHub Wiki to Sphinx Docs (#1137)
* Added precommit for black, updated contributing documentation

Updated contributing.rst and related files

Fixed some grammar, added pre-commit section

* picked pre-commit version, removed redundant language_version

* Fix section headings

* Added GitHub testing/doc Wiki pages to docs

* Update docs/source/contributing.rst

Co-authored-by: Naveen M K <naveen@syrusdark.website>

* Update docs/source/contributing.rst

Co-authored-by: Naveen M K <naveen@syrusdark.website>

* Update docs/source/contributing.rst

Co-authored-by: Naveen M K <naveen@syrusdark.website>

* Update docs/source/contributing.rst

Co-authored-by: Naveen M K <naveen@syrusdark.website>

* Update docs/source/contributing.rst

Co-authored-by: Naveen M K <naveen@syrusdark.website>

* Update docs/source/contributing.rst

* Update docs/source/contributing.rst

Co-authored-by: Naveen M K <naveen@syrusdark.website>

* Fixed some relative links

* Fixed flake8 issue

* Apply suggestions from code review

Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at>

Co-authored-by: Naveen M K <naveen@syrusdark.website>
Co-authored-by: Benjamin Hackl <devel@benjamin-hackl.at>
2021-03-31 02:23:38 -07:00

316 lines
11 KiB
ReStructuredText
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

====================
Adding Documentation
====================
When submitting a new class through a PR, or any changes in general,
there should be documentation where possible. Here are the guidelines
for writing it.
Formatting and Running Tests
----------------------------
Please begin the description of the class/function in the same line as
the 3 quotes:
.. code:: py
def do_this():
"""This is correct.
(...)
"""
def dont_do_this():
"""
This is incorrect.
(...)
"""
NumPy Format
------------
Use the numpy format for sections and formatting - see
https://numpydoc.readthedocs.io/en/latest/format.html.
This includes:
1. The usage of ``Attributes`` to specify ALL ATTRIBUTES that a
class can have, their respective types and a brief (or long, if
needed) description. (See more on :ref:`_types`)
Also, ``__init__`` parameters should be specified as ``Parameters`` **on
the class docstring**, *rather than under* ``__init__``. Note that this
can be omitted if the parameters and the attributes are the exact same
(i.e., dataclass) - priority should be given to the ``Attributes``
section, in this case, which must **always be present**, unless the
class specifies no attributes at all. (See more on Parameters in number
2 of this list.)
Example:
.. code:: py
class MyClass:
"""My cool class. Long or short (whatever is more appropriate) description here.
Parameters
----------
name : :class:`str`
The class's name.
id : :class:`int`
The class's id.
mobj : Optional[:class:`~.Mobject`], optional
The mobject linked to this instance. Defaults to `Mobject()` \
(is set to that if `None` is specified).
Attributes
----------
name : :class:`str`
The user's name.
id : :class:`int`
The user's id.
singleton : :class:`MyClass`
Something.
mobj : :class:`~.Mobject`
The mobject linked to this instance.
"""
def __init__(name, id, singleton, mobj = None): # in-code typehints are optional for now
...
2. The usage of ``Parameters`` on functions in order to specify how
every parameter works and what it does. This should be excluded if
the function has no parameters. Note that you **should not** specify
the default value of the parameter on the type. On the documentation
render, this is already specified on the function's signature. If you
need to indicate a further consequence of value omission or simply
want to specify it on the docs, make sure to **specify it in the
parameter's DESCRIPTION**.
See an example on list item 4.
.. NOTE::
When documenting varargs (args and kwargs), make sure to
document them by listing the possible types of each value specified,
like this:
::
Parameters
----------
args : Union[:class:`int`, :class:`float`]
The args specified can be either an int or a float.
kwargs : :class:`float`
The kwargs specified can only be a float.
Note that, if the kwargs expect specific values, those can be specified
in a section such as ``Other Parameters``:
::
Other Parameters
----------------
kwarg_param_1 : :class:`int`
Parameter documentation here
(etc)
3. The usage of ``Returns`` to indicate what is the type of this
function's return value and what exactly it returns (i.e., a brief -
or long, if needed - description of what this function returns). Can
be omitted if the function does not explicitly return (i.e., always
returns ``None`` because ``return`` is never specified, and it is
very clear why this function does not return at all). In all other
cases, it should be specified.
See an example on list item 4.
4. The usage of ``Examples`` in order to specify an example of usage of
a function **is highly encouraged** and, in general, should be
specified for *every function* unless its usage is **extremely
obvious**, which can be debatable. Even if it is, it's always a good
idea to add an example in order to give a better orientation to the
documentation user. Use the following format for Python code:
.. code:: rst
::
# python code here
**NOTE: Also, if this is a video- or animation-related change, please
try to add an example GIF or video if possible for demonstration
purposes.**
Make sure to be as explicit as possible in your documentation. We all
want the users to have an easier time using this library.
Example:
.. code:: py
def my_function(thing, other, name, *, d, test=45): # typings are optional for now
"""My cool function. Builds and modifies an :class:`EpicClassInThisFile` instance with the given parameters.
Parameters
----------
thing : :class:`int`
Specifies the index of life.
other : :class:`numpy.ndarray`
Specifies something cool.
name : :class:`str`
Specifies my name.
d : :class:`~.SomeClassFromFarAway`
Sets thing D to this value.
test : :class:`int`, optional
Defines the amount of times things should be tested. \
Defaults to 45, because that is almost the meaning of life.
Returns
-------
:class:`EpicClassInThisFile`
The generated EpicClass with the specified attributes and modifications.
Examples
--------
Normal usage::
my_function(5, np.array([1, 2, 3]), "Chelovek", d=SomeClassFromFarAway(cool=True), test=5)
"""
# code...
pass
.. _types:
Types
-----
Always specify types with the correct **role** (see
https://www.sphinx-doc.org/en/1.7/domains.html#python-roles) for the
sake of proper rendering. E.g.: Use ``:class:`int``` to refer to an int
type, and in general ``:class:`<path>``` to refer to a certain class
(see ``Path specification`` below). See after for more specific
instructions.
Path specifications
~~~~~~~~~~~~~~~~~~~
1. If it's on stdlib: Use ``<name>`` directly. If it's a class, just the
name is enough. If it's a method (``:meth:``) or attribute
(``:attr:``), dotted names may be used (e.g.
``:meth:`str.to_lower```).
Example: ``:class:`int```, ``:class:`str```, ``:class:`float```,
``:class:`bool```
2. If it's on the same file as the docstring or, for methods and
attributes, under the same class, then the name may also be specified
directly.
Example: ``:class:`MyClass``` referring to a class in the same file;
``:meth:`push``` referring to a method in the same class;
``:meth:`MyClass.push``` referring to a method in a different class in
the same file; ``:attr:`color``` referring to an attribute in the same
class; ``:attr:`MyClass.color``` referring to an attribute in a
different class in the same file.
3. If it's on a different file, then you may either use the full dotted
name (e.g. ``~manim.animations.Animation``) or simply use the
shortened way (``~.Animation``). Note that, if there is ambiguity,
then the full dotted name must be used where the actual class can't
be deduced. Also note the ``~`` before the path - this is so that it
displays just ``Animation`` instead of the full location in the
rendering. It can be removed for disambiguation purposes only.
Example: ``:class:`~.Animation```, ``:meth:`~.VMobject.set_color```,
``:attr:`~.VMobject.color```
4. If it's a class from a different module, specify the full dotted
syntax.
Example: ``:class:`numpy.ndarray``` for a numpy ndarray.
Type specifications
~~~~~~~~~~~~~~~~~~~
**The following instructions refer to types of attributes, parameters
and return values.** When specifying a type mid-text, it does not
necessarily have to be typeset. However, if it's a class name, a method,
or an enum's attribute/variant, then it is recommended to be typeset at
least on the first occurrence of the name, so that the users can quickly
jump to the related documentation.
1. Class names should be wrapped in ``:class:`path_goes_here```. See
examples in the subsection above.
2. Method names should be wrapped in ``:meth:`path_goes_here```. See
examples in the subsection above.
3. Attribute names should be wrapped in ``:attr:`path_goes_here```. See
examples in the subsection above.
4. If ``None`` can also be specified, use ``Optional[type]``, where
``type`` must follow the guidelines in the current section.
Example: ``Optional[:class:`str`]`` means you can either specify a
``str`` or ``None``.
5. If more than one type is possible, use
``Union[type_1, type_2, (...), type_n]``, where all the ``type_n``
must follow the guidelines in the current section. Note that, if one
of these types is ``None``, then the Union should be wrapped with
``Optional`` instead.
Example: ``Union[:class:`str`, :class:`int`]`` for either ``str`` or
``int``. ``Optional[Union[:class:`int`, :class:`bool`]]`` for either
``int``, ``bool`` or ``None``.
6. **Dictionaries:** Use ``Dict[key_type, value_type]``, where
``key_type`` and ``value_type`` must follow the guidelines in the
current section.
Example: ``Dict[:class:`str`, :class:`~.Mobject`]`` is a dictionary that
maps strings to Mobjects.
``Dict[:class:`str`, Union[:class:`int`, :class:`MyClass`]]`` is a
dictionary that maps a string to either an int or an instance of
``MyClass``.
7. **If the parameter is a list:** Note that it is very rare to require
the parameter to be exactly a ``list`` type. One could usually
specify a ``tuple`` instead, for example. So, in order to cover all
cases, consider:
1. If the parameter only needs to be an ``Iterable``, i.e., if the
function only requires being able to iterate over this parameter's
value (e.g. can be a ``list``, ``tuple``, ``str``, but also
``zip()``, ``iter()`` and so on), then specify
``Iterable[type_here]``, where ``type_here`` is the type of the
iterable's yielded elements and should follow the format in the
present section (``Type specifications``).
Example: ``Iterable[:class:`str`]`` for any iterable of strings;
``Iterable[:class:`~.Mobject`]`` for an iterable of Mobjects; etc.
2. If you require being able to index the parameter (i.e. ``x[n]``)
or retrieve its length (i.e. ``len(x)``), or even just pass it to
a function that requires any of those, then specify ``Sequence``,
which allows any list-like object to be specified (e.g. ``list``,
``tuple``...)
Example: ``Sequence[:class:`str`]`` for a sequence of strings;
``Sequence[Union[:class:`str`, :class:`int`]]`` for a sequence of
integers or strings.
3. If you EXPLICITLY REQUIRE it to be a ``list`` for some reason,
then use ``List[type]``, where ``type`` is the type that any
element in the list will have. It must follow the guidelines in
the current section.
8. **If the return type is a list or tuple:** Specify ``List[type]`` for
a list, ``Tuple[type_a, type_b, (...), type_n]`` for a tuple (if the
elements are all different) or ``Tuple[type, ...]`` (if all elements
have the same type). Each ``type_n`` on those representations
correspond to elements in the returned list/tuple, and must follow
the guidelines in the current section.
Example: ``List[Optional[:class:`str`]]`` for a list that returns
elements that are either a ``str`` or ``None``;
``Tuple[:class:`str`, :class:`int`]`` for a tuple of type
``(str, int)``; ``Tuple[:class:`int`, ...]`` for a tuple of variable
length with only integers.