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-2022.3.6.2.tar.gz (17.0 kB view details)

Uploaded Source

Built Distribution

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

stolid-2022.3.6.2-py3-none-any.whl (18.9 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for stolid-2022.3.6.2.tar.gz
Algorithm Hash digest
SHA256 9c0b4610b95673b7873a61753f1a5464d9b5051281c8fe32da24160a35a1b94a
MD5 8499d1fe26b0ea7047c10806971ade1a
BLAKE2b-256 482f0d775e1a17f8e7dd09de70e08edba1be7ef4477cf81a27e69e0217605577

See more details on using hashes here.

File details

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

File metadata

  • Download URL: stolid-2022.3.6.2-py3-none-any.whl
  • Upload date:
  • Size: 18.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for stolid-2022.3.6.2-py3-none-any.whl
Algorithm Hash digest
SHA256 1cbbfff2ca9f87c17c0c1fb4a5e461d783f71baac52d488a86ea1fea1261c003
MD5 c94230a9c73659c014460514e7d69731
BLAKE2b-256 dbb883819c12e46ca0378ef4116cb8202368b4cfba1a0a431bac58beea1e9e70

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