Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
76a5d21
simplify patterns/behavioral/memento, changing Transactional from des…
May 24, 2023
53ba9bc
add build and dist folders to .gitignore
grimley517 May 8, 2024
11113ea
linter updates - changes to comply with black
grimley517 May 8, 2024
af6fc3e
Additional linting error in patterns/behavioral/strategy.py added spa…
grimley517 May 12, 2024
e0b0061
extract complexity from docstring line
grimley517 May 12, 2024
87a1777
linter reformats quote marks in strategy pattern
grimley517 May 12, 2024
ffb45ca
put lint into a single shell command
grimley517 May 12, 2024
b6ceef4
Removed Random Petshop tests from abstract_factory.py as per #418
grimley517 May 16, 2024
e05b35f
linted abstract_factory.py
grimley517 May 16, 2024
9581e5a
updated readme to describe purpose of lint.sh file
grimley517 May 16, 2024
81e78fe
Merge pull request #417 from grimley517/#415-linter-preventing-prs
faif May 18, 2024
1a94d1f
Update README.md
azarboon Jun 11, 2024
f401747
Merge pull request #419 from azarboon/patch-1
faif Jun 19, 2024
cffe6cd
Update README.md
faif Sep 5, 2024
fa56fde
Update README.md
faif Sep 5, 2024
328b2d4
Merge pull request #408 from LeiYangGH/master
faif Sep 5, 2024
a400094
Added routing
Apr 23, 2025
8f0a91c
Cleaned up lint.sh
Apr 23, 2025
821a4dc
Merge pull request #432 from cdorsman/mvc-routing
faif Apr 25, 2025
ac1b2b4
Merge pull request #434 from cdorsman/lint-sh-cleanup
faif Apr 25, 2025
9016858
Update README.md
faif Apr 25, 2025
ce06e8b
Highlight the need for a wrapper in delegate
danwald Apr 26, 2025
75c27bf
Merge pull request #436 from danwald/update-delegation
faif May 2, 2025
ab82cbe
Removed old Python versions
cdorsman May 3, 2025
3b58565
Added typing
cdorsman May 3, 2025
24f8dcd
Fixed bug
cdorsman May 3, 2025
93b4e16
Removed bugs and added more types
cdorsman May 3, 2025
ccc17b4
Fixed bug on check if controller is defined
cdorsman May 3, 2025
65fcf56
removed object definition from routes
cdorsman May 3, 2025
6af5a82
I fixed a bug
cdorsman May 3, 2025
f6bc58d
Ädded comments and lost types
cdorsman May 3, 2025
58bd201
Defined "random_animal" with random animal from list.
cdorsman May 3, 2025
a50bb54
- Moved AbstractExpert
cdorsman May 4, 2025
9ad7206
Removed object type from init
cdorsman May 4, 2025
e834385
Retry
cdorsman May 4, 2025
8c0b293
Retry2
cdorsman May 4, 2025
092fdd3
fix doctest
cdorsman May 4, 2025
049d555
Retry3
cdorsman May 4, 2025
79a41c7
Retry4
cdorsman May 4, 2025
871fd8a
Added type to random_animal
cdorsman May 4, 2025
7f4e266
Pet to type[Pet]
cdorsman May 4, 2025
84b4b7b
woof
cdorsman May 4, 2025
7db462e
t to T
cdorsman May 4, 2025
07a5f33
Merge pull request #443 from cdorsman/abstract-factory-fixes
faif May 7, 2025
ecc5e17
Remove old py versions (#440)
cdorsman May 7, 2025
879ac01
Mvc add typing (#441)
cdorsman May 7, 2025
bee048e
11 project format (#446)
grimley517 Jul 19, 2025
3c0725a
Servant pattern (#413)
lmiguelvargasf Jul 19, 2025
ef74d59
fix(docs): correct typos in top comment of catalog.py (#451)
partth-code Sep 5, 2025
25c7356
fix: :bug: Fix potential warning in factory.py (#455)
Sorrow-Scarlet Oct 17, 2025
d842d10
Fix typo in top comment of catalog.py (#453)
Demagalawrence Oct 17, 2025
931ed9f
Add type hints and standardized docstrings to observer.py (#454)
Sai-Sravya-Thumati Oct 17, 2025
a72dead
Cleanup pluggable-libs & fix CI file output (#433, #447) (#448)
PraveenMudalgeri Oct 17, 2025
d1e262f
Remove pluggable-libs submodule and cleanup (#433) (#447)
PraveenMudalgeri Oct 17, 2025
11132fc
Translate several doctest tests to pytest (#414)
germin8 Oct 17, 2025
90016f4
Add type hint to remaining pattern modules (#410)
debakarr Oct 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .codespellignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
__pycache__
*.pyc
.idea
*.egg-info/
.tox/
env/
venv/
.env
.venv
.vscode/
.python-version
.coverage
build/
dist/
6 changes: 0 additions & 6 deletions .coveragerc

This file was deleted.

288 changes: 288 additions & 0 deletions .github/workflows/lint_pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
name: lint_pull_request
on: [pull_request, push]
jobs:
check_changes:
runs-on: ubuntu-24.04
outputs:
has_python_changes: ${{ steps.changed-files.outputs.has_python_changes }}
files: ${{ steps.changed-files.outputs.files }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # To get all history for git diff commands

- name: Get changed Python files
id: changed-files
run: |
if [ "${{ github.event_name }}" == "pull_request" ]; then
# For PRs, compare against base branch
CHANGED_FILES=$(git diff --name-only --diff-filter=ACMRT origin/${{ github.base_ref }} HEAD | grep '\.py$' | grep -v "^setup\.py$" || echo "")
# Check if setup.py specifically changed
SETUP_PY_CHANGED=$(git diff --name-only --diff-filter=ACMRT origin/${{ github.base_ref }} HEAD | grep "^setup\.py$" || echo "")
if [ ! -z "$SETUP_PY_CHANGED" ]; then
CHANGED_FILES="$CHANGED_FILES $SETUP_PY_CHANGED"
fi
else
# For pushes, use the before/after SHAs
CHANGED_FILES=$(git diff --name-only --diff-filter=ACMRT ${{ github.event.before }} ${{ github.event.after }} | grep '\.py$' | grep -v "^setup\.py$" || echo "")
# Check if setup.py specifically changed
SETUP_PY_CHANGED=$(git diff --name-only --diff-filter=ACMRT ${{ github.event.before }} ${{ github.event.after }} | grep "^setup\.py$" || echo "")
if [ ! -z "$SETUP_PY_CHANGED" ]; then
CHANGED_FILES="$CHANGED_FILES $SETUP_PY_CHANGED"
fi
fi

# Check if any Python files were changed and set the output accordingly
if [ -z "$CHANGED_FILES" ]; then
echo "No Python files changed"
echo "has_python_changes=false" >> $GITHUB_OUTPUT
echo "files=" >> $GITHUB_OUTPUT
else
echo "Changed Python files: $CHANGED_FILES"
echo "has_python_changes=true" >> $GITHUB_OUTPUT
# Use proper delimiter formatting for GitHub Actions
FILES_SINGLE_LINE=$(echo "$CHANGED_FILES" | tr '\n' ' ' | sed 's/[[:space:]]\+/ /g' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//')
echo "files=$FILES_SINGLE_LINE" >> $GITHUB_OUTPUT
fi

- name: PR information
if: ${{ github.event_name == 'pull_request' }}
run: |
if [[ "${{ steps.changed-files.outputs.has_python_changes }}" == "true" ]]; then
echo "This PR contains Python changes that will be linted."
else
echo "This PR contains no Python changes, but still requires manual approval."
fi

lint:
needs: check_changes
if: ${{ needs.check_changes.outputs.has_python_changes == 'true' }}
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
tool: [flake8, format, mypy, pytest, pyupgrade, tox]
steps:
# Additional check to ensure we have Python files before proceeding
- name: Verify Python changes
run: |
if [[ "${{ needs.check_changes.outputs.has_python_changes }}" != "true" ]]; then
echo "No Python files were changed. Skipping linting."
exit 0
fi

- uses: actions/checkout@v3
with:
fetch-depth: 0

- uses: actions/setup-python@v4
with:
python-version: 3.12

- uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements-dev.txt') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt

# Flake8 linting
- name: Lint with flake8
if: ${{ matrix.tool == 'flake8' }}
id: flake8
run: |
echo "Linting files: ${{ needs.check_changes.outputs.files }}"
flake8 ${{ needs.check_changes.outputs.files }} --count --show-source --statistics

# Format checking with isort and black
- name: Format check
if: ${{ matrix.tool == 'format' }}
id: format
run: |
echo "Checking format with isort for: ${{ needs.check_changes.outputs.files }}"
isort --profile black --check ${{ needs.check_changes.outputs.files }}
echo "Checking format with black for: ${{ needs.check_changes.outputs.files }}"
black --check ${{ needs.check_changes.outputs.files }}

# Type checking with mypy
- name: Type check with mypy
if: ${{ matrix.tool == 'mypy' }}
id: mypy
run: |
echo "Type checking: ${{ needs.check_changes.outputs.files }}"
mypy --ignore-missing-imports ${{ needs.check_changes.outputs.files }}

# Run tests with pytest
- name: Run tests with pytest
if: ${{ matrix.tool == 'pytest' }}
id: pytest
run: |
echo "Running pytest discovery..."
python -m pytest --collect-only -v

# First run any test files that correspond to changed files
echo "Running tests for changed files..."
changed_files="${{ needs.check_changes.outputs.files }}"

# Extract module paths from changed files
modules=()
for file in $changed_files; do
# Convert file path to module path (remove .py and replace / with .)
if [[ $file == patterns/* ]]; then
module_path=${file%.py}
module_path=${module_path//\//.}
modules+=("$module_path")
fi
done

# Run tests for each module
for module in "${modules[@]}"; do
echo "Testing module: $module"
python -m pytest -xvs tests/ -k "$module" || true
done

# Then run doctests on the changed files
echo "Running doctests for changed files..."
for file in $changed_files; do
if [[ $file == *.py ]]; then
echo "Running doctest for $file"
python -m pytest --doctest-modules -v $file || true
fi
done

# Check Python version compatibility
- name: Check Python version compatibility
if: ${{ matrix.tool == 'pyupgrade' }}
id: pyupgrade
run: pyupgrade --py312-plus ${{ needs.check_changes.outputs.files }}

# Run tox
- name: Run tox
if: ${{ matrix.tool == 'tox' }}
id: tox
run: |
echo "Running tox integration for changed files..."
changed_files="${{ needs.check_changes.outputs.files }}"

# Create a temporary tox configuration that extends the original one
echo "[tox]" > tox_pr.ini
echo "envlist = py312" >> tox_pr.ini
echo "skip_missing_interpreters = true" >> tox_pr.ini

echo "[testenv]" >> tox_pr.ini
echo "setenv =" >> tox_pr.ini
echo " COVERAGE_FILE = .coverage.{envname}" >> tox_pr.ini
echo "deps =" >> tox_pr.ini
echo " -r requirements-dev.txt" >> tox_pr.ini
echo "allowlist_externals =" >> tox_pr.ini
echo " pytest" >> tox_pr.ini
echo " coverage" >> tox_pr.ini
echo " python" >> tox_pr.ini
echo "commands =" >> tox_pr.ini

# Check if we have any implementation files that changed
pattern_files=0
test_files=0

for file in $changed_files; do
if [[ $file == patterns/* ]]; then
pattern_files=1
elif [[ $file == tests/* ]]; then
test_files=1
fi
done

# Only run targeted tests, no baseline
echo " # Run specific tests for changed files" >> tox_pr.ini

has_tests=false

# Add coverage-focused test commands
for file in $changed_files; do
if [[ $file == *.py ]]; then
# Run coverage tests for implementation files
if [[ $file == patterns/* ]]; then
module_name=$(basename $file .py)

# Get the pattern type (behavioral, structural, etc.)
if [[ $file == patterns/behavioral/* ]]; then
pattern_dir="behavioral"
elif [[ $file == patterns/creational/* ]]; then
pattern_dir="creational"
elif [[ $file == patterns/structural/* ]]; then
pattern_dir="structural"
elif [[ $file == patterns/fundamental/* ]]; then
pattern_dir="fundamental"
elif [[ $file == patterns/other/* ]]; then
pattern_dir="other"
else
pattern_dir=""
fi

echo " # Testing $file" >> tox_pr.ini

# Check if specific test exists
if [ -n "$pattern_dir" ]; then
test_path="tests/${pattern_dir}/test_${module_name}.py"
echo " if [ -f \"${test_path}\" ]; then echo \"Test file ${test_path} exists: true\" && coverage run -m pytest -xvs --cov=patterns --cov-append ${test_path}; else echo \"Test file ${test_path} exists: false\"; fi" >> tox_pr.ini

# Also try to find any test that might include this module
echo " coverage run -m pytest -xvs --cov=patterns --cov-append tests/${pattern_dir}/ -k \"${module_name}\" --no-header" >> tox_pr.ini
fi

# Run doctests for the file
echo " coverage run -m pytest --doctest-modules -v --cov=patterns --cov-append $file" >> tox_pr.ini

has_tests=true
fi

# Run test files directly if modified
if [[ $file == tests/* ]]; then
echo " coverage run -m pytest -xvs --cov=patterns --cov-append $file" >> tox_pr.ini
has_tests=true
fi
fi
done

# If we didn't find any specific tests to run, mention it
if [ "$has_tests" = false ]; then
echo " python -c \"print('No specific tests found for changed files. Consider adding tests.')\"" >> tox_pr.ini
# Add a minimal test to avoid failure, but ensure it generates coverage data
echo " coverage run -m pytest -xvs --cov=patterns --cov-append -k \"not integration\" --no-header" >> tox_pr.ini
fi

# Add coverage report command
echo " coverage combine" >> tox_pr.ini
echo " coverage report -m" >> tox_pr.ini

# Run tox with the custom configuration
echo "Running tox with custom PR configuration..."
echo "======================== TOX CONFIG ========================"
cat tox_pr.ini
echo "==========================================================="
tox -c tox_pr.ini

summary:
needs: [check_changes, lint]
# Run summary in all cases, regardless of whether lint job ran
if: ${{ always() }}
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v3

- name: Summarize results
run: |
echo "## Pull Request Lint Results" >> $GITHUB_STEP_SUMMARY
if [[ "${{ needs.check_changes.outputs.has_python_changes }}" == "true" ]]; then
echo "Linting has completed for all Python files changed in this PR." >> $GITHUB_STEP_SUMMARY
echo "See individual job logs for detailed results." >> $GITHUB_STEP_SUMMARY
else
echo "No Python files were changed in this PR. Linting was skipped." >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "⚠️ **Note:** This PR still requires manual approval regardless of linting results." >> $GITHUB_STEP_SUMMARY
42 changes: 28 additions & 14 deletions .github/workflows/lint_python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,35 @@ name: lint_python
on: [pull_request, push]
jobs:
lint_python:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.x
- run: pip install --upgrade pip
- run: pip install black codespell flake8 isort mypy pytest pyupgrade tox
- run: black --check .
- run: codespell --quiet-level=2 # --ignore-words-list="" --skip=""
- run: flake8 . --count --show-source --statistics
- run: isort --profile black .
- run: tox
- run: pip install -e .
- run: mypy --ignore-missing-imports . || true
- run: pytest .
- run: pytest --doctest-modules . || true
- run: shopt -s globstar && pyupgrade --py37-plus **/*.py
python-version: 3.12
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install .[dev]
- name: Lint with flake8
run: flake8 ./patterns --count --show-source --statistics
continue-on-error: true
- name: Format check with isort and black
run: |
isort --profile black --check ./patterns
black --check ./patterns
continue-on-error: true
- name: Type check with mypy
run: mypy --ignore-missing-imports ./patterns || true
continue-on-error: true
- name: Run tests with pytest
run: |
pytest ./patterns
pytest --doctest-modules ./patterns || true
continue-on-error: true
- name: Check Python version compatibility
run: shopt -s globstar && pyupgrade --py312-plus ./patterns/**/*.py
continue-on-error: true
- name: Run tox
run: tox
continue-on-error: true
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ venv/
.vscode/
.python-version
.coverage
.project
.pydevproject
/.pytest_cache/
build/
dist/
8 changes: 3 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
os: linux
dist: focal
dist: noble
language: python

jobs:
include:
- python: "3.8"
env: TOXENV=py38
- python: "3.9"
env: TOXENV=py39
- python: "3.12"
env: TOXENV=py312

cache:
- pip
Expand Down
Loading