Skip to content

cog_loader

Dynamic cog loading system with priority-based ordering and telemetry.

This module provides the CogLoader class, which handles discovery, validation, and loading of bot cogs (extensions) from the filesystem. It supports: - Priority-based loading order for dependency management - Concurrent loading within priority groups - Configuration error handling with graceful skipping - Performance monitoring and telemetry via Sentry - Follows discord.py's extension loading patterns and best practices

Classes:

  • CogLoader

    Dynamic cog loader with priority-based ordering and performance tracking.

Classes

CogLoader

Python
CogLoader(bot: Bot)

Bases: Cog

Dynamic cog loader with priority-based ordering and performance tracking.

This class manages the discovery, validation, and loading of bot cogs from the filesystem. It ensures proper load order based on priorities, handles configuration errors gracefully, and provides detailed telemetry.

Attributes:

  • bot (Bot) –

    The bot instance cogs are loaded into.

  • cog_ignore_list (set[str]) –

    Set of cog names to skip during loading (from configuration).

  • load_times (defaultdict[str, float]) –

    Dictionary tracking load time for each cog (for performance monitoring).

  • load_priorities (dict[str, int]) –

    Priority mapping for cog categories (higher = loads first).

Notes

Loading order is critical for cogs with dependencies. Priority groups include: - handlers: Highest priority (event handlers, error handlers) - services: High priority (core services) - modules: Normal priority (bot commands and features) - plugins: Lowest priority (user extensions)

Initialize the cog loader with bot instance and configuration.

Parameters:

  • bot (Bot) –

    The bot instance to load cogs into.

Methods:

  • is_cog_eligible

    Check if a file is eligible for loading as a cog.

  • load_cogs

    Load cogs from a file or directory path with priority-based ordering.

  • load_cogs_from_folder

    Load cogs from a named folder relative to the tux package with timing.

  • setup

    Initialize the cog loader and load all bot cogs in priority order.

Functions

is_cog_eligible async
Python
is_cog_eligible(filepath: Path) -> bool

Check if a file is eligible for loading as a cog.

Validates that the file: - Is not in the ignore list - Is a Python file (.py extension) - Doesn't start with underscore (private module convention) - Is a regular file (not a directory or special file)

Parameters:

  • filepath (Path) –

    The path to the file to check.

Returns:

  • bool

    True if the file passes basic eligibility checks, False otherwise.

_contains_cog_or_extension async
Python
_contains_cog_or_extension(filepath: Path) -> bool

Check if a Python file contains a valid extension setup function using AST.

A valid extension file must contain an async setup(bot) function.

Parameters:

  • filepath (Path) –

    The path to the Python file to analyze.

Returns:

  • bool

    True if the file contains a valid extension setup function, False otherwise.

_is_configuration_error
Python
_is_configuration_error(exception: Exception) -> bool

Check if an exception is or contains a configuration error.

Walks the exception chain to detect TuxConfigurationError anywhere in the cause/context chain.

Parameters:

  • exception (Exception) –

    The exception to check.

Returns:

  • bool

    True if the exception chain contains a TuxConfigurationError.

Notes

Handles both explicit (cause) and implicit (context) exception chaining to catch config errors wrapped in other exception types.

_handle_configuration_skip
Python
_handle_configuration_skip(path: Path, error: Exception) -> None

Log configuration error and mark cog as skipped in telemetry.

Parameters:

  • path (Path) –

    The path to the cog that was skipped.

  • error (Exception) –

    The configuration error that caused the skip.

Notes

This provides consistent logging for configuration errors, ensuring users receive clear guidance on how to enable the cog.

_resolve_module_path
Python
_resolve_module_path(path: Path) -> str

Convert a file path to a Python module path.

Parameters:

  • path (Path) –

    The file path to convert.

Returns:

  • str

    The Python module path (e.g., "tux.modules.admin.dev").

Examples:

Python Console Session
>>> loader._resolve_module_path(Path("tux/modules/admin/dev.py"))
"tux.modules.admin.dev"
Notes

Strips the .py extension and converts path separators to dots.

_is_duplicate_load
Python
_is_duplicate_load(module: str) -> bool

Check if a module or its parent is already loaded.

This prevents duplicate loading of cogs and submodules. For example, if "tux.modules.admin" is loaded, this will return True for "tux.modules.admin.dev".

Parameters:

  • module (str) –

    The module path to check.

Returns:

  • bool

    True if the module or any parent module is already loaded.

Notes

Checks all parent modules in the path hierarchy to prevent conflicts with already-loaded extensions.

_load_single_cog async
Python
_load_single_cog(path: Path) -> None

Load a single cog with timing, error tracking, and telemetry.

This orchestrates the complete loading process: 1. Resolve module path from file path 2. Check for duplicate loading 3. Load the extension via discord.py 4. Record timing metrics and telemetry 5. Handle configuration errors gracefully

Parameters:

  • path (Path) –

    The path to the cog file to load.

Raises:

  • TuxCogLoadError

    If the cog fails to load due to non-configuration errors.

Notes

Configuration errors are handled gracefully and logged as warnings rather than failures, allowing the bot to start with partial features.

_get_cog_priority
Python
_get_cog_priority(path: Path) -> int

Get the loading priority for a cog based on its parent directory category.

Priority determines load order within the cog system. Cogs with higher priority values are loaded before cogs with lower priority values.

Parameters:

  • path (Path) –

    The path to the cog file.

Returns:

  • int

    The priority value (higher = loaded earlier), defaults to 0.

Examples:

Python Console Session
>>> loader._get_cog_priority(Path("tux/services/handlers/error.py"))
100  # handlers have highest priority
>>> loader._get_cog_priority(Path("tux/modules/admin/ban.py"))
50   # modules have normal priority
Notes

Priority is determined by the parent directory name, not the cog name. Priorities are configured in COG_PRIORITIES constant.

_load_cog_group async
Python
_load_cog_group(cogs: Sequence[Path]) -> None

Load a group of cogs concurrently with telemetry and error tracking.

Cogs within the same priority group are loaded in parallel for faster startup times. Configuration errors are handled gracefully by returning None and don't count as failures.

Parameters:

  • cogs (Sequence[Path]) –

    The sequence of cog paths to load concurrently.

Notes

Uses asyncio.gather with return_exceptions=True to ensure one cog's failure doesn't prevent others from loading.

_discover_and_prioritize_cogs async
Python
_discover_and_prioritize_cogs(directory: Path) -> list[tuple[int, Path]]

Discover eligible cogs in a directory and assign priorities.

Parameters:

  • directory (Path) –

    The directory to search for cogs.

Returns:

  • list[tuple[int, Path]]

    List of (priority, path) tuples sorted by priority (highest first).

Notes

This method recursively searches the directory for Python files, validates each as an eligible cog, assigns priorities based on parent directory, and sorts by priority for sequential loading.

_record_priority_distribution
Python
_record_priority_distribution(cog_paths: list[tuple[int, Path]]) -> None

Record the priority distribution of cogs for telemetry.

Parameters:

  • cog_paths (list[tuple[int, Path]]) –

    List of (priority, path) tuples to analyze.

Notes

Counts how many cogs exist at each priority level and records this in Sentry for monitoring load order distribution.

_load_by_priority_groups async
Python
_load_by_priority_groups(cog_paths: list[tuple[int, Path]]) -> None

Load cogs sequentially by priority group.

Cogs are grouped by priority and each group is loaded before moving to the next lower priority. Within each group, cogs load concurrently.

Parameters:

  • cog_paths (list[tuple[int, Path]]) –

    Sorted list of (priority, path) tuples (highest priority first).

Notes

This ensures that high-priority cogs (handlers, services) are fully loaded before lower-priority cogs (modules, plugins) start loading.

_process_single_file async
Python
_process_single_file(path: Path) -> None

Process a single file for loading (non-directory path).

Parameters:

  • path (Path) –

    The file path to process.

Notes

Checks eligibility before attempting to load the file as a cog.

_process_directory async
Python
_process_directory(path: Path) -> None

Process a directory of cogs with priority-based loading.

This method: 1. Discovers all Python files recursively 2. Validates each file as an eligible cog 3. Groups cogs by priority 4. Loads each priority group sequentially (higher priority first) 5. Within each group, loads cogs concurrently

Parameters:

  • path (Path) –

    The directory path to process recursively.

Notes

Loading strategy: - Priority groups are loaded sequentially (ensures handlers load first) - Cogs within a group load concurrently (faster startup) - This balances dependency order with performance

load_cogs async
Python
load_cogs(path: Path) -> None

Load cogs from a file or directory path with priority-based ordering.

Automatically handles both single files and directories. Directories are processed recursively with priority-based loading.

Parameters:

  • path (Path) –

    The path to a cog file or directory containing cogs.

Raises:

Notes

This is the main entry point for loading cogs from a path. Delegates to _process_single_file or _process_directory based on path type.

load_cogs_from_folder async
Python
load_cogs_from_folder(folder_name: str) -> None

Load cogs from a named folder relative to the tux package with timing.

This method provides performance monitoring and slow cog detection for a specific folder. It's used to load major cog categories like "services/handlers", "modules", or "plugins".

Parameters:

  • folder_name (str) –

    The folder name relative to the tux package (e.g., "modules" or "services/handlers").

Raises:

Notes

Skips gracefully if the folder doesn't exist (useful for optional plugin directories). Logs warnings for cogs that take >1s to load.

setup async classmethod
Python
setup(bot: Bot) -> None

Initialize the cog loader and load all bot cogs in priority order.

This is the main entrypoint for the cog loading system, called during bot startup. It loads cogs in this order: 1. services/handlers (error handlers, event listeners) - highest priority 2. modules (bot commands and features) - normal priority 3. plugins (user extensions) - lowest priority

Parameters:

  • bot (Bot) –

    The bot instance to load cogs into.

Raises:

Notes

This method: - Creates a CogLoader instance - Loads all cog folders sequentially (respects priorities) - Registers the CogLoader itself as a cog - Provides comprehensive telemetry via Sentry

Functions