From automation
Applies Sun Lab Python coding conventions when writing, reviewing, or refactoring code. Covers .py files, docstrings, type annotations, naming, formatting, error handling, imports, file ordering, and ataraxis library preferences. Use when writing new Python code, modifying existing code, reviewing pull requests, or when the user asks about Python coding standards.
npx claudepluginhub sun-lab-nbb/ataraxis --plugin automationThis skill uses the workspace's default tool permissions.
Applies Sun Lab Python coding conventions.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Applies Sun Lab Python coding conventions.
You MUST read this skill and load the relevant reference files before writing or modifying Python code. You MUST verify your changes against the checklist before submitting.
Covers:
Does not cover:
/readme-style)/commit)/skill-design)/explore-codebase)You MUST follow these steps when this skill is invoked.
Read this entire file. The core conventions below apply to ALL Python code.
Based on the task, load the appropriate reference files:
| Task | Reference to load |
|---|---|
| Writing or modifying docstrings/types | docstrings-and-types.md |
| Writing classes, dataclasses, or enums | class-patterns.md |
| Using ataraxis libs, Numba, Click, tests | libraries-and-tools.md |
| Using ataraxis library features | Invoke /explore-dependencies first, then load above |
| Reviewing code before submission | anti-patterns.md |
Load multiple references when the task spans multiple domains.
Write or modify Python code following all conventions from this file and the loaded references.
Complete the verification checklist at the end of this file. Every item must pass before submitting work. For anti-pattern examples, load anti-patterns.md.
Use full words, not abbreviations:
| Avoid | Prefer |
|---|---|
t, t_sq | interpolation_factor, t_squared |
coeff, coeffs | coefficient, coefficients |
pos, idx | position, index |
img, val | image, value |
compute_coefficients, extract_features_process_batch, _validate_inputprocess, handle, do_somethingModule-level constants with type annotations, descriptive names, and inline docstrings:
_MINIMUM_SAMPLE_COUNT: int = 100
"""Minimum number of samples required for statistical validity."""
Always use keyword arguments for clarity:
# Good
np.zeros((4,), dtype=np.float32)
compute_coefficients(interpolation_factor=t, output=result)
# Avoid
np.zeros((4,), np.float32)
compute_coefficients(t, result)
Exceptions:
range(4), len(array).jitclass method calls, which do not support keyword arguments. Use positional
arguments for these calls and add a brief inline comment if the call is not self-explanatory.
Note: standard @njit / @jit functions do support keyword arguments and are not exempt
from this rule.In projects that depend on ataraxis-base-utilities, use console.error for error reporting:
from ataraxis_base_utilities import console
def process_data(self, data: NDArray[np.float32], threshold: float) -> None:
if not (0 < threshold <= 1):
message = (
f"Unable to process data with the given threshold. The threshold must be in range "
f"(0, 1], but got {threshold}."
)
console.error(message=message, error=ValueError)
In projects that do not depend on ataraxis-base-utilities, use standard raise with the same
message format.
message variable before passing to console.error() or raise# The constant 2.046392675 is the theoretical injectivity bound for 2D cubic B-splines.
limit = (1.0 / 2.046392675) * self._grid_sampling * factor
# Set x to 5 before x = 5)# ====== or # ------)All local (within-library) imports must directly import the required names:
# Good - import specific names
from .spline_grid import SplineGrid
from .deformation import Deformation, zoom, diffuse
# Bad - importing the module itself
from . import spline_grid
Cross-package imports must go through the package's __init__.py:
# Good - imports from the package's __init__.py
from ..configuration import RuntimeContext, SingleDayConfiguration
# Bad - imports directly from a submodule in another package
from ..configuration.single_day import RuntimeContext, SingleDayConfiguration
Within-package imports use direct module imports:
from .spline_grid import SplineGrid
There are two types of __init__.py files with different docstring requirements.
The top-level __init__.py (e.g., src/library_name/__init__.py) uses an extended docstring with
documentation links and authors:
"""Provides assets for processing and analyzing neural imaging data.
See the `documentation <https://project-api-docs.netlify.app/>`_ for the description of
available assets. See the `source code repository <https://github.com/Sun-Lab-NBB/project-name>`_
for more details.
Authors: Author Name (Handle)
"""
from .module_one import ClassOne, function_one
from .module_two import ClassTwo, ClassThree
# console.enable() belongs only in top-level application libraries (e.g., sl-experiment).
# Component libraries must NOT enable console — the application entry point handles this.
__all__ = [
"ClassOne",
"ClassThree",
"ClassTwo",
"function_one",
]
Subpackage __init__.py files (e.g., src/library_name/subpackage/__init__.py) use a single-line
docstring only:
"""Provides configuration and runtime data classes for the processing pipeline."""
from .config import Config, Settings
from .data import DataStore
__all__ = [
"Config",
"DataStore",
"Settings",
]
pyproject.toml, welcome.rst, README.md)
with no language or project name prefix. Include documentation link, source repository link,
and authors. Email addresses in the Authors: line are optional and omitted by default__init__.pyconsole.enable() belongs only in top-level application libraries
that serve as the final entry point (e.g., sl-experiment). Component and dependency libraries
(e.g., ataraxis-video-system) must NOT call console.enable() — the top-level application
is responsible for enabling the console before any component library code runs__all__: Every __init__.py must declare __all__ with all public API members__all__ entries alphabetically__init__.py files may contain logic that benefits from
being executed exactly once on import (e.g., setting the multiprocessing start method,
configuring environment variables for platform compatibility). Beyond that, __init__.py files
should contain only imports and __all__All definitions within a file follow this vertical ordering from top to bottom:
_UPPER_SNAKE_CASE values)_ prefixed)Public definitions appear above private definitions. This matches the C-family convention used across all Sun Lab projects (C#, C++), where the public API is presented first and implementation details follow. Readers see the interface before the helpers that support it.
Within each visibility group, definitions should loosely follow the order in which they are called during the library's runtime. When there is no clear call hierarchy, group definitions by purpose.
Enumerations and dataclasses define the types that worker functions and classes operate on. They must appear above the functions and classes that use them.
Exception — dataclass-only modules: In files whose primary product is the dataclasses themselves, the order is: enumerations first, then public helper functions, then private helper functions, then dataclasses at the bottom.
Use truthiness checks instead of explicit comparisons to True or False:
# Good - truthiness
if not self._is_enabled:
return
if items:
process(items=items)
if not file_list:
console.error(message="No files found.", error=FileNotFoundError)
# Avoid - explicit boolean comparison
if self._is_enabled == True: # Wrong
if self._is_enabled is True: # Wrong
if len(items) > 0: # Wrong - use truthiness instead
Exception: Always use is None / is not None for None checks, never truthiness:
# Good - explicit None check
if self._data is not None:
process(data=self._data)
Prefer early returns (guard clauses) over deeply nested conditionals:
# Good - guard clauses reduce nesting
def process_session(self, data: NDArray[np.float32], threshold: float) -> NDArray[np.float32]:
"""Processes session data with the given threshold."""
if not self._is_enabled:
return data
if data.size == 0:
message = "Unable to process session data. The data array is empty."
console.error(message=message, error=ValueError)
# Main logic at minimal indentation level.
filtered = data[data > threshold]
return filtered
def line before the docstring% formatting or
.format().f prefix on all
lines of the multi-line string.Use pathlib.Path for all path manipulation instead of string operations:
config_path = Path(base_directory) / "config" / "settings.yaml"
| Skill | Relationship |
|---|---|
/explore-dependencies | Provides live ataraxis dependency API snapshots; invoke before using features |
/cpp-style | Provides C++ conventions; Python conventions parallel these |
/csharp-style | Provides C# conventions; Python conventions parallel these |
/readme-style | Provides README conventions; invoke for README tasks |
/commit | Provides commit message conventions; invoke for commit tasks |
/skill-design | Provides skill file conventions; invoke for skill authoring tasks |
/explore-codebase | Provides project context that informs style-compliant code changes |
When reviewing or modifying code, proactively check for style violations and fix them. When writing new code, apply all conventions from this skill and its references without being asked. If you notice existing code near your changes that violates conventions, mention it to the user but do not fix it unless asked.
You MUST verify your edits against this checklist before submitting any changes to Python files.
Python Style Compliance:
- [ ] Google-style docstrings on all public and private members
- [ ] Docstring section order: Summary -> Extended Description -> Notes -> Args -> Returns -> Raises
- [ ] No Examples sections or in-code examples in docstrings
- [ ] Imperative mood in summaries ("Processes..." not "This method processes...")
- [ ] Prose used instead of bullet lists in docstrings
- [ ] All parameters and returns have type annotations
- [ ] NumPy arrays specify dtype explicitly (NDArray[np.float32])
- [ ] Type aliases use PEP 695 `type` statement syntax
- [ ] Full words used (no abbreviations like `pos`, `idx`, `val`)
- [ ] Private members use `_underscore` prefix
- [ ] Keyword arguments used for function calls (except Numba `jitclass` method calls)
- [ ] Error handling uses console.error() when ataraxis-base-utilities is available (else raise)
- [ ] Double quotes used for all strings (enforced by ruff)
- [ ] F-strings used exclusively (no % formatting or .format())
- [ ] Lines under 120 characters
- [ ] All imports at top of file (no deferred or inline imports)
- [ ] Import sorting delegated to ruff (do not manually reorder)
- [ ] Local imports use direct name imports (no module imports)
- [ ] Cross-package imports go through package __init__.py (not submodules)
- [ ] __init__.py files have __all__ (alphabetically sorted)
- [ ] Top-level library __init__.py has extended docstring (description, docs link, repo link, authors)
- [ ] Subpackage __init__.py files have single-line docstrings only (no links or authors)
- [ ] console.enable() only in top-level application libraries, not component libraries
- [ ] Public definitions above private definitions in file
- [ ] Enums and dataclasses above worker functions and classes
- [ ] Definitions ordered by call hierarchy or grouped by purpose
- [ ] Inline comments use third person imperative
- [ ] No heavy section separator blocks (# ====== or # ------)
- [ ] Numba functions use cache=True
- [ ] Decorator stacking order: @staticmethod/@classmethod, @njit, custom, @property
- [ ] Dataclasses use frozen=True for immutable configs (omit for mutable state)
- [ ] Dataclasses use slots=True by default (omit for YamlConfig subclasses or classes needing __dict__)
- [ ] Enum members have inline docstrings; StrEnum for strings, IntEnum for codes
- [ ] __repr__ uses ClassName(key=value) format; no __str__
- [ ] Boolean checks use truthiness (not == True); None checks use `is None`
- [ ] Guard clauses / early returns preferred over deep nesting
- [ ] I/O operations separated from processing logic
- [ ] Context managers used for resource management
- [ ] Pathlib used for path manipulation (not string concatenation)
- [ ] Two blank lines between top-level definitions
- [ ] Trailing commas in multi-line structures
Ataraxis Library Preferences (when ataraxis libraries are dependencies):
- [ ] Invoked /explore-dependencies to obtain current API snapshot for each ataraxis dependency
- [ ] Used ataraxis library features instead of standard library equivalents where available
- [ ] Console output uses console.echo() instead of print(); raw=True for pre-formatted content
- [ ] Error handling uses console.error() instead of raise (when ataraxis-base-utilities available)
- [ ] console.enable() absent in component libraries (only top-level application libraries enable it)