.. 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