-
Notifications
You must be signed in to change notification settings - Fork 6
Enhance cookiecutter template with stricter code quality standards #84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
dguido
wants to merge
16
commits into
main
Choose a base branch
from
enhance-cookiecutter-standards
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 15 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
f537826
feat: enhance cookiecutter template with stricter standards
dguido c975cb8
feat: add FastAPI as preferred web framework option
dguido f6dee7f
Merge branch 'main' into enhance-cookiecutter-standards
dguido 6fa0b6a
fix: correct ty version and remove unsupported --strict flag
dguido 517395b
fix: apply ruff formatting to pre_gen_project.py
dguido 08fb765
refactor: remove data library option from cookiecutter
dguido e805061
refactor: simplify PR by removing FastAPI and consolidating config
dguido 330cbb9
fix: restore 'reformat' target as alias to fix CI
dguido 2fbd39b
fix: correct license field syntax in pyproject.toml
dguido d405f81
fix: correct ty configuration field name
dguido d481298
fix: remove ty configuration section to use defaults
dguido 2902ab9
test commit
dguido 67244e8
refactor: replace ty with pyright and improve configurations
dguido a249f00
test commit
dguido 0030cef
fix: address all code review issues
dguido d7c9bbf
Fix the PR
DarkaMaul File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,8 +13,6 @@ jobs: | |
| strategy: | ||
| matrix: | ||
| python: | ||
| - "3.9" | ||
| - "3.10" | ||
| - "3.11" | ||
| - "3.12" | ||
| runs-on: ubuntu-latest | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # Pre-commit hooks for code quality | ||
| # See https://pre-commit.com for more information | ||
| repos: | ||
| - repo: https://github.com/astral-sh/ruff-pre-commit | ||
| rev: v0.6.2 | ||
| hooks: | ||
| # Run the formatter | ||
| - id: ruff-format | ||
| # Run the linter | ||
| - id: ruff | ||
| args: [--fix] | ||
|
|
||
| - repo: local | ||
| hooks: | ||
| - id: pyright | ||
| name: pyright type check | ||
| entry: uv run pyright | ||
| language: system | ||
| types: [python] | ||
| pass_filenames: false | ||
| require_serial: true | ||
|
|
||
| {%- if cookiecutter.docstring_coverage %} | ||
| - id: interrogate | ||
| name: interrogate docstring coverage | ||
| entry: uv run interrogate -c pyproject.toml | ||
| language: system | ||
| types: [python] | ||
| pass_filenames: false | ||
| {%- endif %} | ||
|
|
||
| - id: pytest | ||
| name: pytest (fast tests only) | ||
| entry: uv run pytest -x --tb=short -k "not slow" | ||
| language: system | ||
| types: [python] | ||
| pass_filenames: false | ||
| require_serial: true | ||
| # Only run on pre-commit, not on push | ||
| stages: [pre-commit] | ||
|
|
||
| # Configuration | ||
| ci: | ||
| autofix_prs: true | ||
| autoupdate_schedule: weekly |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,167 @@ | ||
| # {{ cookiecutter.project_name }} - Claude Instructions | ||
|
|
||
| This document contains project-specific instructions for Claude when working on this codebase. | ||
|
|
||
| ## Project Overview | ||
|
|
||
| {{ cookiecutter.project_description }} | ||
|
|
||
| ## Code Standards | ||
|
|
||
| This project enforces strict code quality standards: | ||
|
|
||
| ### Code Complexity Limits | ||
| - **Max 50 lines per function** - Split larger functions | ||
| - **Cyclomatic complexity ≤ 8** - Simplify complex logic | ||
| - **Max 5 positional parameters** - Use keyword arguments or dataclasses | ||
| - **Max 12 branches per function** - Extract to helper functions | ||
| - **Max 6 return statements** - Consolidate exit points | ||
|
|
||
| ### Style Guidelines | ||
| - **Line length**: 100 characters max | ||
| - **Docstrings**: Google style on all public functions/classes | ||
| - **Type hints**: Required for all function signatures | ||
| - **Tests**: Must live beside code (`test_*.py` or `*_test.py`) | ||
DarkaMaul marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Quick Commands | ||
|
|
||
| ```bash | ||
| # Development setup | ||
| make dev | ||
|
|
||
| # Run all checks | ||
| make check # Runs lint + tests | ||
|
|
||
| # Code quality | ||
| make lint # ruff format --check + ruff check + pyright | ||
| make fix # Auto-fix formatting and lint issues | ||
| make typecheck # Run pyright type checker | ||
|
|
||
| # Testing | ||
| make test # Run pytest with coverage | ||
|
|
||
| # Development | ||
| {% if cookiecutter.entry_point -%} | ||
| make run ARGS="--help" # Run the CLI | ||
| {%- endif %} | ||
| make doc # Build documentation | ||
| ``` | ||
| ## Project Structure | ||
| ``` | ||
| src/ | ||
| └── {{ cookiecutter.__project_import.replace('.', '/') }}/ | ||
| ├── __init__.py | ||
| {%- if cookiecutter.entry_point %} | ||
| ├── __main__.py # CLI entry point | ||
| ├── _cli.py # CLI implementation | ||
| {%- endif %} | ||
| └── py.typed # Type checking marker | ||
|
|
||
| test/ | ||
| └── test_*.py # Traditional test location | ||
| ``` | ||
| Tests can also live beside source files as `test_*.py` or `*_test.py`. | ||
| ## General Python Guidelines | ||
| These are general preferences for Python development: | ||
| - **Web frameworks**: Prefer FastAPI over Flask for new projects | ||
| - **Data processing**: Consider Polars for performance-critical data operations | ||
| - **Async programming**: Use native async/await instead of threading | ||
| - **Type checking**: Always use type hints and run pyright | ||
| ## Common Patterns | ||
| ### Error Handling | ||
| ```python | ||
| from typing import Result # If using result types | ||
DarkaMaul marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| def process_data(path: str) -> Result[Data, str]: | ||
| """Process data from file. | ||
| Args: | ||
| path: Path to data file. | ||
| Returns: | ||
| Result with Data on success, error message on failure. | ||
| """ | ||
| try: | ||
| # Implementation | ||
| return Ok(data) | ||
| except Exception as e: | ||
| return Err(f"Failed to process: {e}") | ||
| ``` | ||
| ### Logging | ||
| ```python | ||
| import logging | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
| ``` | ||
| {%- if cookiecutter.entry_point %} | ||
| ### CLI Arguments | ||
| Use the existing `_cli.py` structure: | ||
| ```python | ||
| parser.add_argument( | ||
| "--verbose", "-v", | ||
| action="store_true", | ||
| help="Enable verbose output" | ||
| ) | ||
| ``` | ||
| {%- endif %} | ||
| ## Testing Guidelines | ||
| - Aim for 100% test coverage (enforced by CI) | ||
| - Use `pytest.mark.parametrize` for multiple test cases | ||
| - Mock external dependencies | ||
| - Test both success and error paths | ||
| ### Test Markers | ||
| Mark slow tests to exclude them from pre-commit hooks: | ||
| ```python | ||
| import pytest | ||
| @pytest.mark.slow | ||
| def test_integration_with_external_api(): | ||
| """This test won't run during pre-commit hooks.""" | ||
| ... | ||
| def test_fast_unit_test(): | ||
| """This test will run during pre-commit hooks.""" | ||
| ... | ||
| ``` | ||
| The pre-commit hook runs `pytest -k "not slow"` to skip slow tests. | ||
| ## CI/CD | ||
| GitHub Actions run on every push/PR: | ||
| 1. **Linting**: ruff format/check + pyright type checking | ||
| 2. **Tests**: pytest with coverage | ||
| 3. **Security**: zizmor workflow scanning | ||
| {%- if cookiecutter.documentation == "pdoc" %} | ||
| 4. **Docs**: Auto-deploy to GitHub Pages | ||
| {%- endif %} | ||
| ## Important Notes | ||
| 1. **Never commit code that violates the quality standards** - refactor instead | ||
| 2. **All public APIs need Google-style docstrings** | ||
| 3. **Type hints are mandatory** - use `pyright` | ||
| 4. **Tests can live beside code** - prefer colocated tests for better maintainability | ||
| ## Project-Specific Instructions | ||
| <!-- Add any project-specific Claude instructions here --> | ||
| --- | ||
| *This file helps Claude understand project conventions. Update it as patterns emerge.* | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,6 +44,7 @@ all: | |
|
|
||
| .PHONY: dev | ||
| dev: $(VENV)/pyvenv.cfg | ||
| uv run pre-commit install | ||
|
|
||
| {%- if cookiecutter.entry_point %} | ||
| .PHONY: run | ||
|
|
@@ -59,17 +60,28 @@ $(VENV)/pyvenv.cfg: pyproject.toml | |
| lint: $(VENV)/pyvenv.cfg | ||
| uv run ruff format --check && \ | ||
| uv run ruff check && \ | ||
| uv run mypy | ||
| uv run pyright | ||
|
|
||
| {%- if cookiecutter.docstring_coverage %} | ||
| uv run interrogate -c pyproject.toml . | ||
| {%- endif %} | ||
|
|
||
| .PHONY: reformat | ||
| reformat: | ||
| .PHONY: check | ||
| check: lint test | ||
|
|
||
| .PHONY: typecheck | ||
| typecheck: $(VENV)/pyvenv.cfg | ||
| uv run pyright | ||
|
Comment on lines
+69
to
+71
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this needed? Running |
||
|
|
||
| .PHONY: fix | ||
| fix: | ||
| uv run ruff format && \ | ||
| uv run ruff check --fix | ||
|
|
||
| # Alias for backwards compatibility | ||
| .PHONY: reformat | ||
| reformat: fix | ||
|
|
||
| .PHONY: test tests | ||
| test tests: $(VENV)/pyvenv.cfg | ||
| uv run pytest --cov=$(PY_IMPORT) $(T) $(TEST_ARGS) | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.