From 1fe190edae17e1ff3c2102500118108bd89b86a4 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Sat, 12 Jul 2025 12:59:58 -0400 Subject: [PATCH 1/2] Test commit - Broken code Signed-off-by: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> --- .pre-commit-config.yaml | 8 +++++--- src/hello_world/main.py | 12 +++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 27a6403..dd9b62b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,11 +4,13 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-yaml - id: check-added-large-files - id: check-merge-conflict + - id: check-toml + - id: check-yaml + - id: detect-private-key + - id: end-of-file-fixer + - id: trailing-whitespace - repo: https://github.com/psf/black rev: 24.0.0 diff --git a/src/hello_world/main.py b/src/hello_world/main.py index c6cd51f..235a25e 100644 --- a/src/hello_world/main.py +++ b/src/hello_world/main.py @@ -34,14 +34,16 @@ def greet(name: Optional[str] = None) -> str: return f"Hello, {name}!" -def main() -> None: +def main( + +): """ Main entry point for the application. - - Prints a default greeting message to stdout. - """ + +Prints a default greeting message to stdout. +""" print(greet()) -if __name__ == "__main__": +if __name__ = __main__: main() From c81a3d48583ee8a1ca87f09a553a5b6ee56fea56 Mon Sep 17 00:00:00 2001 From: JacobPEvans <20714140+JacobPEvans@users.noreply.github.com> Date: Sat, 12 Jul 2025 14:22:04 -0400 Subject: [PATCH 2/2] feat: update pre-commit hooks, dependencies, and bump versions; enhance README, and improve test coverage --- .pre-commit-config.yaml | 15 ++++---- README.md | 45 ++++++++++++------------ pyproject.toml | 13 +++---- requirements.txt => requirements-dev.txt | 11 +++--- src/hello_world/main.py | 10 +++--- tests/test_main.py | 24 +++++++------ 6 files changed, 62 insertions(+), 56 deletions(-) rename requirements.txt => requirements-dev.txt (65%) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dd9b62b..50e389c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # Install: pip install pre-commit && pre-commit install repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v5.0.0 hooks: - id: check-added-large-files - id: check-merge-conflict @@ -10,26 +10,27 @@ repos: - id: check-yaml - id: detect-private-key - id: end-of-file-fixer + - id: no-commit-to-branch + args: ['--branch', 'main'] - id: trailing-whitespace - repo: https://github.com/psf/black - rev: 24.0.0 + rev: 25.1.0 hooks: - id: black - language_version: python3 - repo: https://github.com/pycqa/isort - rev: 5.13.0 + rev: 6.0.1 hooks: - id: isort - repo: https://github.com/pycqa/flake8 - rev: 7.0.0 + rev: 7.3.0 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.16.0 + rev: v1.16.1 hooks: - id: mypy - additional_dependencies: [types-all] + additional_dependencies: [pytest] diff --git a/README.md b/README.md index b008dae..878a9bb 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,18 @@ A minimal Python project template following modern best practices and industry s pip install -e . ``` +4. **Set up pre-commit hooks** + ```bash + # Install pre-commit + pip install pre-commit + + # Install the git hook scripts + pre-commit install + + # (Optional) Run on all files to test setup + pre-commit run --all-files + ``` + ## ๐Ÿงช Running Tests ```bash @@ -59,33 +71,22 @@ pytest tests/test_main.py -v ## ๐Ÿ› ๏ธ Development Tools -### Code Formatting & Linting -```bash -# Format code with Black -black src/ tests/ +### Pre-commit Hooks Setup -# Sort imports with isort -isort src/ tests/ - -# Lint with flake8 -flake8 src/ tests/ - -# Type checking with mypy -mypy src/ -``` - -### Pre-commit Hooks +Pre-commit hooks automatically run code formatting, linting, and type checking before each commit to ensure code quality. ```bash # Install pre-commit pip install pre-commit -# Install hooks +# Install the git hook scripts pre-commit install -# Run hooks manually +# Test the setup pre-commit run --all-files ``` +> **Note**: Once installed, pre-commit will automatically run on every `git commit`. If any checks fail, the commit will be blocked until issues are fixed. Code formatting tools like Black and isort will auto-fix many issues. + ## Features - โœ… Modern Python packaging with `pyproject.toml` @@ -112,7 +113,7 @@ python-template/ โ”œโ”€โ”€ .gitignore # Git ignore rules โ”œโ”€โ”€ README.md # Project documentation โ”œโ”€โ”€ pyproject.toml # Modern Python packaging -โ””โ”€โ”€ requirements.txt # Dependencies +โ””โ”€โ”€ requirements-dev.txt # Development dependencies ``` ## Installation @@ -131,7 +132,7 @@ python-template/ 3. Install dependencies: ```bash - pip install -r requirements.txt + pip install -r requirements-dev.txt ``` ## Usage @@ -139,15 +140,15 @@ python-template/ Run the hello world application: ```bash -python -m src.hello_world.main +python -m hello_world.main ``` Or import and use in your code: ```python -from src.hello_world import hello_world +from hello_world import greet -print(hello_world("Python")) # Output: Hello, Python! +print(greet("Python")) # Output: Hello, Python! ``` ## Development diff --git a/pyproject.toml b/pyproject.toml index 0186e15..1f15ba1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,16 +20,17 @@ classifiers = [ [project.optional-dependencies] dev = [ - "pytest>=8.3.0", + "black>=25.1.0", + "flake8>=7.3.0", + "isort>=6.0.1", + "mypy>=1.16.1", + "pre-commit>=4.2.0", "pytest-cov>=6.2.0", - "black>=24.0.0", - "isort>=5.13.0", - "flake8>=7.0.0", - "mypy>=1.16.0" + "pytest>=8.4.1", ] [tool.pytest.ini_options] -minversion = "6.0" +minversion = "8.4" addopts = "-ra -q --strict-markers --strict-config" testpaths = ["tests"] python_files = ["test_*.py", "*_test.py"] diff --git a/requirements.txt b/requirements-dev.txt similarity index 65% rename from requirements.txt rename to requirements-dev.txt index d94758a..5463ff2 100644 --- a/requirements.txt +++ b/requirements-dev.txt @@ -2,9 +2,10 @@ # Add your production dependencies here # Development dependencies (optional - can also use pip install -e ".[dev]") -pytest>=8.3.0 +black>=25.1.0 +flake8>=7.3.0 +isort>=6.0.1 +mypy>=1.16.1 +pre-commit>=4.2.0 pytest-cov>=6.2.0 -black>=24.0.0 -isort>=5.13.0 -flake8>=7.0.0 -mypy>=1.16.0 +pytest>=8.4.1 diff --git a/src/hello_world/main.py b/src/hello_world/main.py index 235a25e..1d82b75 100644 --- a/src/hello_world/main.py +++ b/src/hello_world/main.py @@ -34,16 +34,14 @@ def greet(name: Optional[str] = None) -> str: return f"Hello, {name}!" -def main( - -): +def main() -> None: """ Main entry point for the application. -Prints a default greeting message to stdout. -""" + Prints a default greeting message to stdout. + """ print(greet()) -if __name__ = __main__: +if __name__ == "__main__": main() diff --git a/tests/test_main.py b/tests/test_main.py index 9e7414e..bc6ad2c 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -6,34 +6,38 @@ """ import pytest + from hello_world.main import greet class TestGreetFunction: """Test cases for the greet function.""" - def test_greet_default(self): + def test_greet_default(self) -> None: """Test greet function with default parameter (None).""" assert greet() == "Hello, World!" - def test_greet_custom(self): + def test_greet_custom(self) -> None: """Test greet function with custom name.""" assert greet("Python") == "Hello, Python!" - def test_greet_empty_string(self): + def test_greet_empty_string(self) -> None: """Test greet function with empty string should default to World.""" assert greet("") == "Hello, World!" - def test_greet_none_explicit(self): + def test_greet_none_explicit(self) -> None: """Test greet function with explicit None parameter.""" assert greet(None) == "Hello, World!" - @pytest.mark.parametrize("name,expected", [ - ("Alice", "Hello, Alice!"), - ("Bob", "Hello, Bob!"), - ("123", "Hello, 123!"), - ("Test User", "Hello, Test User!"), - ]) + @pytest.mark.parametrize( + "name,expected", + [ + ("Alice", "Hello, Alice!"), + ("Bob", "Hello, Bob!"), + ("123", "Hello, 123!"), + ("Test User", "Hello, Test User!"), + ], + ) def test_greet_parametrized(self, name: str, expected: str) -> None: """Test greet function with various inputs using parametrization.""" assert greet(name) == expected