.. Copyright (c) 2023 - 2023, Oracle and/or its affiliates. All rights reserved. .. Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/. .. References/links .. _sphinx-apidoc: https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html =================== Macaron Style Guide =================== Macaron makes use of different linters. These linters are managed using `pre-commit `_ hooks (see the `.pre-commit-config.yaml `_ file). Most styling issues should be caught by pre-commit hooks. However, there are some additional styling rules that we follow. -------------- Python Modules -------------- We ban the use of ``__all__`` in ``__init__.py`` files due to known issues with the `sphinx-apidoc`_ docstring generator. ------ Naming ------ We avoid using the same name for two or more classes in all cases (including cases where the two classes are in different modules), due to known issues with the `sphinx-apidoc`_ docstring generator. ---------- Docstrings ---------- We use `sphinx-apidoc`_ to generate :doc:`API Reference ` automatically from `Python docstrings `_ written in the code. We follow the `numpydoc style `_ for Python docstrings (see `example `_) with some exceptions. '''''''''''''''''''''' Docstrings for classes '''''''''''''''''''''' Each class should have a docstring written in a triple-quoted block describing the purpose of the class. For variables of a class: we do not use the ``Attribute`` section as per the `numpydoc style for class docstring `_, due to some known issues with Sphinx. Instead, to document class variables, we follow the following convention: - For simple Python classes having an ``__init__`` constructor: We document the ``__init__`` constructor like any other regular method, i.e. all parameters should be documented. We do not document `instance variables `_ and consider them to be private to the class. To expose an instance variable of a class in the documentation, we use `Python property `_ and document the property methods (``getter``, ``setter``, and ``deleter`` methods) instead. Example: .. code-block:: python class Point2D: """A point in the 2D coordinate system.""" def __init__(self, coordinate: tuple[float, float]) -> None: """Construct a point in the 2D coordinate system. Parameters ---------- coordinate : tuple[float, float] A pair of x and y coordinates. """ self._x = tuple[0] self._y = tuple[1] @property def x(self) -> float: """Get the x coordinate of the point.""" return self._x - For Python classes that declare instance variables in class attributes (e.g. :py:class:`typing.NamedTuple`, :py:func:`dataclasses.dataclass`, or `SQLAlchemy ORM Mapped classes `_): We document each instance variable with a comment above the variable prefixed with ``#:`` (if the comment spans more than one line, all lines must be prefixed with ``#:``). Example: .. code-block:: python from typing import NamedTuple class Point2D(NamedTuple): """A point in the 2D coordinate system.""" #: The x coordinate of the point. x: float #: The y coordinate of the point. y: float