diff --git a/pyproject.toml b/pyproject.toml index 21f4fb9..d4cfb41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,11 +4,60 @@ version = "0.1.0" description = "A simple Python package for managing Docker Compose files" readme = "README.md" requires-python = ">=3.13" -dependencies = [ - "pytest>=8.4.0", - "pyyaml>=6.0.2", -] +dependencies = ["pytest>=8.4.0", "pyyaml>=6.0.2"] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" + +[tool.ruff] +preview = true +line-length = 120 +lint.select = ["ALL"] +lint.pydocstyle.convention = "google" +lint.isort.required-imports = ["from __future__ import annotations"] +lint.pycodestyle.ignore-overlong-task-comments = true + +lint.ignore = [ + "ANN201", # Checks that public functions and methods have return type annotations. + "ARG001", # Checks for the presence of unused arguments in function definitions. + "B008", # Allow Form() as a default value + "CPY001", # Missing copyright notice at top of file + "D100", # Checks for undocumented public module definitions. + "D101", # Checks for undocumented public class definitions. + "D102", # Checks for undocumented public method definitions. + "D104", # Missing docstring in public package. + "D105", # Missing docstring in magic method. + "D105", # pydocstyle - missing docstring in magic method + "D106", # Checks for undocumented public class definitions, for nested classes. + "ERA001", # Found commented-out code + "FBT003", # Checks for boolean positional arguments in function calls. + "FIX002", # Line contains TODO + "G002", # Allow % in logging + "PGH003", # Check for type: ignore annotations that suppress all type warnings, as opposed to targeting specific type warnings. + "PLR6301", # Checks for the presence of unused self parameter in methods definitions. + "RUF029", # Checks for functions declared async that do not await or otherwise use features requiring the function to be declared async. + "TD003", # Checks that a TODO comment is associated with a link to a relevant issue or ticket. + "PLR0913", # Checks for function definitions that include too many arguments. + "PLR0917", # Checks for function definitions that include too many positional arguments. + + # Conflicting lint rules when using Ruff's formatter + # https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules + "COM812", # Checks for the absence of trailing commas. + "COM819", # Checks for the presence of prohibited trailing commas. + "D206", # Checks for docstrings that are indented with tabs. + "D300", # Checks for docstrings that use '''triple single quotes''' instead of """triple double quotes""". + "E111", # Checks for indentation with a non-multiple of 4 spaces. + "E114", # Checks for indentation of comments with a non-multiple of 4 spaces. + "E117", # Checks for over-indented code. + "ISC001", # Checks for implicitly concatenated strings on a single line. + "ISC002", # Checks for implicitly concatenated strings that span multiple lines. + "Q000", # Checks for inline strings that use single quotes or double quotes, depending on the value of the lint.flake8-quotes.inline-quotes option. + "Q001", # Checks for multiline strings that use single quotes or double quotes, depending on the value of the lint.flake8-quotes.multiline-quotes setting. + "Q002", # Checks for docstrings that use single quotes or double quotes, depending on the value of the lint.flake8-quotes.docstring-quotes setting. + "Q003", # Checks for strings that include escaped quotes, and suggests changing the quote style to avoid the need to escape them. + "W191", # Checks for indentation that uses tabs. +] + +[tool.ruff.lint.per-file-ignores] +"tests/*" = ["S101", "D103", "PLR2004"] diff --git a/src/compose/__init__.py b/src/compose/__init__.py index 5d578f0..810543f 100644 --- a/src/compose/__init__.py +++ b/src/compose/__init__.py @@ -8,12 +8,16 @@ configuration files through Python classes, simplifying the process of defining and managing Docker Compose configurations. """ +from __future__ import annotations + from pathlib import Path -from types import TracebackType -from typing import Any +from typing import TYPE_CHECKING, Any, Self import yaml +if TYPE_CHECKING: + from types import TracebackType + class DockerComposeManager: """A class to create and modify Docker Compose YAML files programmatically. @@ -47,7 +51,7 @@ class DockerComposeManager: ports: list[str] | None = None, environment: dict[str, str] | None = None, **kwargs: object, - ) -> "DockerComposeManager": + ) -> DockerComposeManager: """Create a new service in the compose file. Returns: @@ -65,7 +69,7 @@ class DockerComposeManager: self._dirty = True return self - def modify_service(self, name: str, **kwargs: object) -> "DockerComposeManager": + def modify_service(self, name: str, **kwargs: object) -> DockerComposeManager: """Modify an existing service. Raises KeyError if not found. Args: @@ -87,7 +91,7 @@ class DockerComposeManager: self._dirty = True return self - def remove_service(self, name: str) -> "DockerComposeManager": + def remove_service(self, name: str) -> DockerComposeManager: """Remove a service from the compose file. Returns: @@ -106,7 +110,7 @@ class DockerComposeManager: yaml.dump(self._data, f, sort_keys=False, indent=2) self._dirty = False - def __enter__(self) -> "DockerComposeManager": + def __enter__(self) -> Self: """Enter the context manager and return self. Returns: diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_compose_manager.py b/tests/test_compose_manager.py index 309cd8f..c626de3 100644 --- a/tests/test_compose_manager.py +++ b/tests/test_compose_manager.py @@ -1,10 +1,15 @@ -from pathlib import Path +from __future__ import annotations + +from typing import TYPE_CHECKING import pytest import yaml from compose import DockerComposeManager +if TYPE_CHECKING: + from pathlib import Path + def test_create_and_save_service(tmp_path: Path) -> None: compose_file: Path = tmp_path / "docker-compose.yml"