Skip to main content

Linter enforcing the conventions of the Python standard template

Project description

A flake8 plugin that enforces opinionated Python coding conventions for clean, maintainable code.

Stolid encourages:

  • Composition over inheritance

  • Dependency injection over mocking

  • Protocol-based typing over abstract base classes

  • Immutable dataclasses

  • Small, focused functions and classes

Installation

pip install stolid

Usage

Stolid integrates directly with flake8:

flake8 your_code.py

Error Codes

SLD1xx - Testing

SLD102: Prohibits use of patch and patch.object from unittest.mock.

Use dependency injection instead of mocking:

# Bad
from unittest.mock import patch

@patch("mymodule.requests.get")
def test_fetch(mock_get):
    ...

# Good
class TestFetch(unittest.TestCase):
    def test_fetch(self) -> None:
        fake_client = FakeHTTPClient(response={"data": 1})
        fetcher = DataFetcher(client=fake_client)
        result = fetcher.fetch()
        assert_that(result, equal_to(1))

SLD2xx - Abstract Base Classes

SLD201: Prohibits importing ABC from the abc module.

SLD202: Prohibits using @abstractmethod decorator.

Use typing.Protocol for interfaces instead:

# Bad
from abc import ABC, abstractmethod

class HTTPClient(ABC):
    @abstractmethod
    def get(self, url: str) -> Response:
        ...

# Good
from typing import Protocol

class HTTPClient(Protocol):
    def get(self, url: str) -> Response:
        ...

SLD3xx - Object-Oriented Design

SLD301: Prohibits __init__ methods.

Use @dataclass with default_factory for attributes, or @classmethod for parameter computation:

# Bad
class Processor:
    def __init__(self, client, config):
        self.client = client
        self.config = config

# Good
from dataclasses import dataclass

@dataclass(frozen=True, slots=True, kw_only=True)
class Processor:
    client: HTTPClient
    config: Config

SLD302: Prohibits private methods (starting with _).

Extract private methods into separate classes:

# Bad
class Processor:
    def _validate(self, data):
        ...

# Good
class Validator:
    def validate(self, data):
        ...

SLD303: Flags methods that only access public members of self.

Convert to module-level functions or use functools.singledispatch:

# Bad
class User:
    name: str

    def display_name(self) -> str:
        return self.name.title()

# Good
def display_name(user: User) -> str:
    return user.name.title()

SLD4xx - Inheritance

SLD401: Prohibits inheritance from concrete classes.

Allowed base classes:

  • Typing: Protocol, Generic

  • Exceptions: Exception, BaseException

  • Testing: TestCase

  • Enums: Enum, IntEnum, StrEnum, Flag, IntFlag

  • Other: TypedDict, NamedTuple

# Bad
class MyHandler(BaseHandler):
    ...

# Good
@dataclass(frozen=True, slots=True, kw_only=True)
class MyHandler:
    validator: Validator
    processor: Processor

SLD5xx - Dataclass Configuration

All dataclasses must have:

SLD501: frozen=True (immutability)

SLD502: slots=True (memory efficiency)

SLD503: kw_only=True (keyword-only arguments)

# Bad
@dataclass
class Settings:
    timeout: int

# Good
@dataclass(frozen=True, slots=True, kw_only=True)
class Settings:
    timeout: int

SLD6xx - Code Complexity

SLD601: Functions limited to 30 lines

SLD602: Functions limited to 4 arguments (excludes self/cls)

SLD603: Classes limited to 15 methods (excludes dunder methods)

SLD604: Modules limited to 400 lines

Configuration

Stolid follows standard flake8 configuration. Add to your setup.cfg or .flake8:

[flake8]
extend-ignore = SLD301,SLD302

Or use per-file ignores:

[flake8]
per-file-ignores =
    tests/*:SLD301,SLD302

Development

pip install nox

# Run all checks
nox

# Run specific sessions
nox -s tests    # Run tests with coverage
nox -s lint     # Run black and flake8
nox -s mypy     # Run type checking

License

MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stolid-2026.1.24.80598.tar.gz (18.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stolid-2026.1.24.80598-py3-none-any.whl (21.3 kB view details)

Uploaded Python 3

File details

Details for the file stolid-2026.1.24.80598.tar.gz.

File metadata

  • Download URL: stolid-2026.1.24.80598.tar.gz
  • Upload date:
  • Size: 18.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for stolid-2026.1.24.80598.tar.gz
Algorithm Hash digest
SHA256 df1ff334c6783b6ef1ac5788009d92c8ba5abd5f1d5fc35baee7f1aa71273540
MD5 e11139182f2a7d36ecf165064330c30b
BLAKE2b-256 924d8a455dbd8578f16142e490324e8c1d7aa8efba24d6f109f8788515bdbb03

See more details on using hashes here.

File details

Details for the file stolid-2026.1.24.80598-py3-none-any.whl.

File metadata

File hashes

Hashes for stolid-2026.1.24.80598-py3-none-any.whl
Algorithm Hash digest
SHA256 4e23e7d8ac6d39e73f947b4c50b0d59c8d6c1863a47cf6d941e52be0ebbb0920
MD5 1c5ab561ea6358ab5b7dfeada1860e99
BLAKE2b-256 7f297dc66409831dd939421a322794691d4a4b1278b341fd7135b47b7afa96c5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page