Code Style Guide#

This guide covers code style guidelines and conventions for PhyloZoo.

Code Conventions#

Type Hinting#

All functions and classes must use type hints for parameters, return types, and class attributes. Prefer modern built-in generics and PEP 604 unions (e.g., list[int], dict[str, float], int | None) now that we require Python 3.10+.

Example:

def process_network(
    network: DirectedPhyNetwork,
    threshold: float = 0.5,
) -> SemiDirectedPhyNetwork:
    """Process a network."""
    # Implementation
    pass

Use TypeVar for generic types when appropriate. Prefer explicit types over Any—only use Any when absolutely necessary. Use -> None for functions that don’t return values.

Docstrings#

All public functions, classes, and methods must include NumPy-style docstrings with detailed parameter descriptions, return values, exceptions, and examples.

Format:

def function_name(param1: Type, param2: Type) -> ReturnType:
    """
    Brief description of the function.

    Parameters
    ----------
    param1 : Type
        Description of param1.
    param2 : Type
        Description of param2.

    Returns
    -------
    ReturnType
        Description of what is returned.

    Raises
    ------
    ValueError
        When and why this exception is raised.

    Examples
    --------
    >>> example_usage()
    expected_output

    Notes
    -----
    Additional notes or implementation details.
    """

Include all sections that are relevant (Parameters, Returns, Raises, Examples, Notes, See Also, etc.). When including an example, also include it in the tests.

Naming Conventions#

  • Classes: Use PascalCase (e.g., DirectedPhyNetwork, QuartetProfile)

  • Functions and methods: Use snake_case (e.g., compute_layout, is_treechild)

  • Constants: Use UPPER_SNAKE_CASE (e.g., DEFAULT_RADIUS)

  • Private/internal: Use leading underscore (e.g., _internal_function, _private_attr)

Development Tools#

PhyloZoo relies on standard tools for code quality checks and automation: Black (formatting), Ruff (linting), and mypy (type checking).

Installation#

Install the tools directly:

pip install black ruff mypy

or via the development extra:

pip install -e ".[dev]"

Code Formatting (Black)#

PhyloZoo uses Black for code formatting with a line length of 100 characters.

Format code before committing:

black src/ tests/

Linting (Ruff)#

PhyloZoo uses Ruff for linting. Run linting checks:

ruff check src/ tests/

Type Checking (mypy)#

PhyloZoo uses mypy for static type checking. Run type checks:

mypy src/

Type checking configuration is in pyproject.toml. The project uses Python 3.10+ with modern type hint features.

Example#

Here’s an example of properly styled code:

from typing import TypeVar
from phylozoo.core.network.sdnetwork import SemiDirectedPhyNetwork

T = TypeVar('T')


def induced_subnetwork(
    network: SemiDirectedPhyNetwork,
    taxa: list[str],
) -> SemiDirectedPhyNetwork:
    """
    Extract the subnetwork induced by a subset of taxa.

    Parameters
    ----------
    network : SemiDirectedPhyNetwork
        The phylogenetic network.
    taxa : list[str]
        Subset of taxon labels to induce the subnetwork on.

    Returns
    -------
    SemiDirectedPhyNetwork
        The induced subnetwork.

    Raises
    ------
    PhyloZooValueError
        If any taxon is not in the network.

    Examples
    --------
    >>> from phylozoo.core.network.sdnetwork import derivations
    >>> network = ...  # SemiDirectedPhyNetwork
    >>> sub = derivations.subnetwork(network, taxa=["A", "B", "C"])
    >>> len(sub.taxa) <= 3
    True
    """
    from phylozoo.core.network.sdnetwork import derivations
    return derivations.subnetwork(network, taxa)