diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..dcd335a --- /dev/null +++ b/.flake8 @@ -0,0 +1,57 @@ +[flake8] +# Match black's line length +max-line-length = 88 + +# Only ignore issues that conflict with black or are stylistic preferences +ignore = + # E203: whitespace before ':' (conflicts with black) + E203, + # W503: line break before binary operator (conflicts with black) + W503, + +# Per-file ignores for existing issues +# TODO: These should be fixed incrementally to improve code quality +per-file-ignores = + # Test files can have unused imports, variables, long lines, etc + tests/*.py:F401,F841,E501,W293,F541,F403,F405,E741 + # Source files with existing issues that need refactoring + src/eigenscript/evaluator/interpreter.py:F403,F405,C901,E501,F541,F401,F841 + src/eigenscript/compiler/cli/compile.py:C901,E501,F541,F401 + src/eigenscript/builtins.py:E501,F541,F401 + src/eigenscript/parser/ast_builder.py:C901,E501,F841 + src/eigenscript/compiler/codegen/llvm_backend.py:E501,F541,F401,C901 + src/eigenscript/__main__.py:C901,E501,F541,F401,F841 + src/eigenscript/compiler/runtime/build_runtime.py:E501,F541,E226,C901 + src/eigenscript/lexer/tokenizer.py:E501,C901,F841 + src/eigenscript/compiler/analysis/observer.py:E226,F541,C901,E501 + src/eigenscript/semantic/operations.py:E501,F401 + src/eigenscript/semantic/lrvm.py:E501 + src/eigenscript/compiler/analysis/resolver.py:F401,F841 + src/eigenscript/semantic/metric.py:E501 + src/eigenscript/runtime/eigencontrol.py:E741 + +# Exclude common directories +exclude = + .git, + __pycache__, + .pytest_cache, + .mypy_cache, + build, + dist, + *.egg-info, + .venv, + venv, + .tox, + docs/_build, + +# Set complexity threshold +max-complexity = 15 + +# Show source code for each error +show-source = True + +# Count the number of occurrences of each error/warning code +count = True + +# Print total number of errors +statistics = True diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dbe3d76..0bfd7b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,8 +36,12 @@ jobs: - name: Run flake8 run: | + # Stage 1: Check for critical errors only (syntax errors, undefined names) flake8 src/ tests/ --count --select=E9,F63,F7,F82 --show-source --statistics - flake8 src/ tests/ --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics + # Stage 2: Run full flake8 check with configuration from .flake8 + # This now properly fails the build on violations (no --exit-zero) + # Per-file ignores in .flake8 allow existing violations while catching new ones + flake8 src/ tests/ - name: Run tests with coverage run: | diff --git a/FLAKE8_ENFORCEMENT.md b/FLAKE8_ENFORCEMENT.md new file mode 100644 index 0000000..4ebdf37 --- /dev/null +++ b/FLAKE8_ENFORCEMENT.md @@ -0,0 +1,81 @@ +# Flake8 Enforcement + +## What Changed + +Previously, the CI workflow was running flake8 with the `--exit-zero` flag, which meant that flake8 violations **never failed the build**. This allowed code quality issues to accumulate silently. + +## Current Status + +Flake8 is now properly enforced in the CI pipeline: + +1. **Critical errors** (E9, F63, F7, F82) are checked first - these are syntax errors and undefined names +2. **Full flake8 check** now runs without `--exit-zero`, meaning violations will fail the build +3. A `.flake8` configuration file has been added with: + - Line length matching black's 88 characters + - Per-file ignores for existing violations + - Proper exclusions for build artifacts and cache directories + +## Existing Violations + +There were approximately **270 flake8 violations** in the codebase. These have been documented in `.flake8` using per-file ignores. This approach: + +- ✅ Prevents new violations from being introduced +- ✅ Documents existing tech debt +- ✅ Allows incremental cleanup +- ✅ Doesn't break existing functionality + +## Violation Categories (before enforcement) + +- 55 E501: Lines too long (> 88 characters) +- 55 F405: Undefined from star imports +- 42 W293: Blank lines with whitespace +- 30 F841: Local variables assigned but never used +- 29 F541: f-strings missing placeholders +- 28 F401: Imports not used +- 23 C901: Functions too complex +- 4 E226: Missing whitespace around operators +- 2 E741: Ambiguous variable names (I, l) +- 2 F403: Star imports + +## Next Steps (Recommended) + +To improve code quality, consider addressing these violations incrementally: + +1. **High Priority**: + - F403/F405: Replace star imports with explicit imports + - F401: Remove unused imports + - E741: Rename ambiguous variable names + +2. **Medium Priority**: + - F841: Remove or use unused variables + - F541: Fix f-strings without placeholders + - E226: Add whitespace around operators + +3. **Low Priority** (but good to do): + - E501: Break long lines + - W293: Remove whitespace from blank lines + - C901: Refactor complex functions + +## Testing Locally + +To run flake8 locally: + +```bash +# Install flake8 +pip install flake8 + +# Run flake8 +flake8 src/ tests/ + +# Run only on files you changed +flake8 src/eigenscript/yourfile.py +``` + +## Configuration + +The `.flake8` configuration file includes: +- Compatible with black's formatting (88 char lines, E203/W503 ignored) +- Per-file ignores for existing violations +- Excludes common directories (cache, build, dist, etc.) +- Max complexity threshold of 15 +- Shows source code and statistics for violations