Metadata-Version: 2.4
Name: pylint-tyrant
Version: 0.6.0
Summary: Pylint plugin with documentation and architecture rules.
Author-email: otakutyrant <otakutyrant@gmail.com>
Project-URL: Homepage, https://github.com/otakutyrant/tyrant-rules/tree/main/implementations/pylint-tyrant
Project-URL: Repository, https://github.com/otakutyrant/tyrant-rules
Project-URL: Issues, https://github.com/otakutyrant/tyrant-rules/issues
Requires-Python: >=3.13
Description-Content-Type: text/markdown
Requires-Dist: pylint>=4.0.0
Requires-Dist: tomli>=2.0.1; python_version < "3.11"

# pylint-tyrant

Pylint plugin with documentation and architecture rules inspired by
`eslint-plugin-tyrant`.

In rule names, `doc` means Python docstrings.

The plugin currently ships these rules:

- `enforce-doc-tag-order`
- `enforce-project-layer-dependencies`
- `enforce-package-layer-dependencies`
- `no-direct-error-instantiation`
- `require-doc-for-public-api`
- `require-file-doc`
- `require-empty-line-after-file-doc`
- `require-relative-base-module-import`
- `prefer-single-line-doc`
- `restrict-relative-imports-to-base-module`

### `enforce-project-layer-dependencies`

Requires configured project directories to depend only on themselves or lower layers.

This rule uses `--tyrant-layers`:

```sh
pylint \
  --load-plugins=pylint_tyrant \
  --enable=enforce-project-layer-dependencies \
  --tyrant-layers=lib,services,app \
  path/to/your_package
```

### `enforce-package-layer-dependencies`

Requires same-package module layers to be declared in the entry-module docstring and to depend only on themselves or lower layers.

This rule uses `--tyrant-shared-modules`. `__init__.py` is treated as the entry module automatically, configured same-directory module names such as `base` or `types.py` are treated as shared low-level modules, and every other module in the directory is treated as a feature module.

Prefix inheritance is disabled by default. Set
`--tyrant-inherit-layers-from-module-prefixes=y` to let underscore-qualified
modules inherit the layer of their longest declared module-name prefix. For
example, `bbb_unit_test.py` and `bbb_integration_test.py` then inherit the layer
declared by `@module bbb`, so they do not need to be listed separately and
cannot import higher layers. Qualified entry modules such as
`__init___unit_test.py` inherit the entry layer, and qualified configured
shared modules such as `types_unit_test.py` inherit the shared layer.

Use `@module` for one ordered module layer and `@module-group` for one ordered flat peer layer:

```python
"""Package docs.

@module materials - Core data.
@module-group paragraphs, lexicons - Peer modules derived from the same inputs.
@module metrics - Aggregates.
"""
```

Every feature module must be listed exactly once. Missing modules, extra listed modules, repeated modules, and upward imports are violations.
Every `@module` and `@module-group` tag must also include a non-empty relationship description.

```sh
pylint \
  --load-plugins=pylint_tyrant \
  --enable=enforce-package-layer-dependencies \
  --tyrant-shared-modules=base,types.py \
  path/to/your_package
```

Add `--tyrant-inherit-layers-from-module-prefixes=y` to that command only when
prefix inheritance is wanted.

### `require-doc-for-public-api`

Requires public classes, functions, and methods to have docstrings.

This rule currently treats names that do not start with `_` as public. It checks:

- top-level public classes
- top-level public functions
- public methods on public classes

Valid:

```python
class UserService:
    """Load users."""

    def load_user(self) -> None:
        """Load one user."""
```

Also valid:

```python
def load_user() -> None:
    """Load one user."""
```

Invalid:

```python
def load_user() -> None:
    pass
```

### `enforce-doc-tag-order`

Requires recognized docstring tags to follow one configured order.

This rule reads tags written as `@tag - value` from module, class, and function docstrings. It only checks tags listed in `tyrant-doc-tag-order`.

Configure it in `pyproject.toml` like this:

```toml
[tool.pylint.main]
load-plugins = ["pylint_tyrant"]

[tool.pylint."messages control"]
enable = ["enforce-doc-tag-order"]

[tool.pylint.tyrant-doc-tag-order]
tyrant-doc-tag-order = ["@remarks", "@param", "@returns"]
```

Command-line equivalent:

```sh
pylint \
  --load-plugins=pylint_tyrant \
  --enable=enforce-doc-tag-order \
  --tyrant-doc-tag-order=@remarks,@param,@returns \
  path/to/your_package
```

Valid:

```python
def load_user() -> User:
    """Load one user.

    @remarks - Used by the public API.
    @param - User id.
    @returns - Loaded user.
    """
```

Invalid:

```python
def load_user() -> User:
    """Load one user.

    @returns - Loaded user.
    @param - User id.
    """
```
