Opinionated Python project structure and code quality linter
Project description
kdaquila-structure-lint
Opinionated Python project structure and code quality linter.
Overview
kdaquila-structure-lint is a Python linter that enforces code quality and project structure conventions. It provides three validators that can be enabled independently:
- Line Limits Validator (enabled by default) - Enforces maximum line count per file
- One-Per-File Validator (enabled by default) - Ensures single function/class per file
- Structure Validator (opt-in) - Enforces opinionated folder structure rules
Installation
Install from PyPI using pip:
pip install kdaquila-structure-lint
For development installations:
git clone https://github.com/kdaquila/kdaquila-structure-lint.git
cd kdaquila-structure-lint
pip install -e ".[dev]"
Quick Start
Run the linter in your project directory:
structure-lint
The tool will:
- Auto-detect your project root by searching for
pyproject.toml - Load configuration from
[tool.structure-lint]section (or use defaults) - Run all enabled validators
- Report any violations with clear error messages
Basic Example
Add configuration to your pyproject.toml:
[tool.structure-lint]
enabled = true
[tool.structure-lint.validators]
line_limits = true
one_per_file = true
structure = false # Opt-in only
Run the linter:
structure-lint
Features
Line Limits Validator
Enforces a maximum number of lines per Python file to encourage modular, maintainable code.
Default: 150 lines per file
Configuration:
[tool.structure-lint.line_limits]
max_lines = 150
search_paths = ["src"]
Example Output:
============================================================
Running line limit validation...
============================================================
✗ src/features/data_processing/processor.py: 187 lines (exceeds 150 line limit)
✗ src/analysis/report_generator.py: 203 lines (exceeds 150 line limit)
2 files exceed the line limit
One-Per-File Validator
Ensures each Python file contains at most one top-level function or class definition, promoting better organization and discoverability.
Configuration:
[tool.structure-lint.one_per_file]
search_paths = ["src"]
Example Output:
============================================================
Running one-per-file validation...
============================================================
✗ src/utils/helpers.py: 3 definitions (expected 1)
- format_date (function)
- parse_date (function)
- DateFormatter (class)
1 file violates one-per-file rule
Structure Validator (Opt-in)
Enforces an opinionated folder structure based on feature-driven development principles. This validator is disabled by default as it's highly prescriptive.
Enable with:
[tool.structure-lint.validators]
structure = true
See docs/validators.md for detailed structure rules.
Configuration
Minimal Configuration
Create a minimal configuration in your pyproject.toml:
[tool.structure-lint]
enabled = true
This uses all default settings with line_limits and one_per_file enabled.
Full Configuration
See all available options:
[tool.structure-lint]
enabled = true
[tool.structure-lint.validators]
structure = false # Opt-in (default: disabled)
line_limits = true # Default: enabled
one_per_file = true # Default: enabled
[tool.structure-lint.line_limits]
max_lines = 150
search_paths = ["src"]
[tool.structure-lint.one_per_file]
search_paths = ["src"]
[tool.structure-lint.structure]
src_root = "src"
standard_folders = ["types", "utils", "constants", "tests"]
general_folder = "general"
free_form_roots = []
allowed_files = ["README.md"]
For detailed configuration options, see docs/configuration.md.
Example Configurations
Example configurations are available in the docs/examples/ directory:
minimal_config.toml- Bare minimum configurationfull_config.toml- All options with defaultscustom_structure.toml- Custom structure validation setup
Command-Line Interface
Basic Usage
structure-lint # Run in current directory
structure-lint --verbose # Show detailed output
structure-lint --version # Show version
structure-lint --help # Show help message
Advanced Options
# Specify project root explicitly
structure-lint --project-root /path/to/project
# Use a specific pyproject.toml file
structure-lint --config /path/to/pyproject.toml
# Verbose output (shows project root and detailed progress)
structure-lint --verbose
Exit Codes
The CLI returns different exit codes for automation and CI/CD integration:
0- All validations passed1- One or more validations failed2- Configuration error or unexpected error
Usage in CI/CD
GitHub Actions
Add to your .github/workflows/ci.yml:
name: CI
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install dependencies
run: |
pip install kdaquila-structure-lint
- name: Run structure linter
run: structure-lint
Pre-commit Hook
Add to your .pre-commit-config.yaml:
repos:
- repo: local
hooks:
- id: structure-lint
name: structure-lint
entry: structure-lint
language: system
pass_filenames: false
GitLab CI
Add to your .gitlab-ci.yml:
structure-lint:
image: python:3.11
script:
- pip install kdaquila-structure-lint
- structure-lint
Development
Running Tests
pip install -e ".[dev]"
pytest
Type Checking
mypy src/features
Linting
ruff check src/features tests
Documentation
- Configuration Reference - Complete schema and options
- Validator Details - In-depth validator documentation
- Examples - Sample configurations
Philosophy
This linter enforces opinions about code organization based on these principles:
- Modularity - Files should be small and focused
- Discoverability - One definition per file makes code easier to find
- Consistency - Predictable structure reduces cognitive load
- Flexibility - All rules are configurable and can be disabled
The structure validator is opt-in because it's highly opinionated. The other validators (line limits and one-per-file) represent more universally accepted best practices.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Author
Created by kdaquila
Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kdaquila_structure_lint-1.0.0.tar.gz.
File metadata
- Download URL: kdaquila_structure_lint-1.0.0.tar.gz
- Upload date:
- Size: 52.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a440bfd59acb4f92a2b2f2df782d2c6b37dd4f45b2b5c03ca80edfcf73567a04
|
|
| MD5 |
c2e60e58c1a88fa3ce1efab50332d50b
|
|
| BLAKE2b-256 |
9f00223c7269c2a0b74cb08c2cba07004c7b67e2224b333d0395465cc371bc63
|
File details
Details for the file kdaquila_structure_lint-1.0.0-py3-none-any.whl.
File metadata
- Download URL: kdaquila_structure_lint-1.0.0-py3-none-any.whl
- Upload date:
- Size: 53.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb9594458d9efbb39eaca8e0275fb9e2e12c2a416e3a730cefff716c32451d4a
|
|
| MD5 |
2c6e4b5f7d68ac51ac8ae4a8b254c186
|
|
| BLAKE2b-256 |
578ef4216b29b0e9e4cb9400b807730738ae73a656a7960e310cae8cbcbb5cbd
|