Skip to content

v1.5.1 - Stricter Code Quality Standards

Choose a tag to compare

@chrimaho chrimaho released this 22 Oct 10:34
· 226 commits to main since this release

Summary

This release strengthens code quality enforcement through stricter complexity thresholds and comprehensive import hygiene checks. Building upon the extensive refactoring work completed in v1.5.0, this release reduces the maximum allowed cognitive complexity from 15 to 13, establishing proactive quality gates that prevent technical debt accumulation. The release also re-enables pycln checks in both linting and validation workflows, ensuring unused imports are automatically detected and removed throughout the development lifecycle. Additionally, complexity reporting verbosity has been optimised with the introduction of the details = "low" configuration option, reducing noise in CI/CD logs whilst maintaining actionable feedback. These enhancements maintain the codebase's excellent quality standards (100% test coverage, Pylint 10.00/10) whilst preventing regression of the refactoring achievements from v1.5.0. All changes are non-breaking and require no migration effort from users.

Release Statistics

Attribute Note
Version: v1.5.1
Python Support: 3.9, 3.10, 3.11, 3.12, 3.13, 3.14
Test Coverage: 100% (834 statements)
Pylint Score: 10.00/10
Complexity: 309 (max threshold now 13, was 15)
Functions: 98
Tests Passing: 183/183
Files Changed: 3
Lines Added: 3,119
Lines Removed: 185
Commits: 4
Pull Requests Merged: 1 (PR #20)

🎯 Stricter Complexity Threshold

Overview

Reduce the maximum allowed cognitive complexity threshold from 15 to 13 in the complexipy configuration, establishing stricter quality standards that preserve the refactoring achievements from v1.5.0 and prevent future complexity regression.

Motivation

The comprehensive refactoring work completed in v1.5.0 successfully eliminated all functions with complexity β‰₯15, reducing total cognitive complexity from 332 to 309 points (6.9% reduction). The current codebase distribution demonstrates excellent quality:

  • 0 functions with complexity β‰₯15 (all eliminated through refactoring)
  • 1 function with complexity 13 (_extract_items - justified Visitor Pattern implementation)
  • 4 functions with complexity 10-12 (all documented and justified)
  • 93+ functions with complexity ≀9 (excellent maintainability)

With all high-complexity functions eliminated, maintaining a threshold of 15 would allow gradual complexity creep back toward problematic levels. Reducing the threshold to 13 establishes a proactive quality gate that:

  1. Prevents Complexity Regression: Catches functions approaching the 15+ range before they become maintenance burdens
  2. Maintains Current Quality Baseline: All existing functions pass the 13 threshold, so no immediate refactoring required
  3. Encourages Best Practices: Developers receive early warnings at complexity 13, prompting consideration of Extract Method and other refactoring patterns
  4. Aligns with Industry Standards: Industry guidance suggests complexity 10-15 as "moderate" - setting threshold at 13 keeps code in the simpler half of this range

Implementation Details

Files Modified:

  • pyproject.toml

Configuration Changes:

[tool.complexipy]
paths = "src/docstring_format_checker"
-max-complexity-allowed = 15
+max-complexity-allowed = 13
quiet = false
ignore-complexity = false
sort = "asc"

Technical Benefits

Proactive Quality Management:

  • Automated checks prevent introduction of complex code before it reaches the main branch
  • Pull requests exceeding complexity 13 are blocked until refactored
  • Continuous monitoring ensures quality standards maintained across all contributions

Data-Driven Development:

  • Objective metrics enable data-driven decisions about refactoring priorities
  • Quantitative complexity scores provide discussion anchors during code review
  • Removes subjectivity from "this code feels complex" assessments

Developer Guidance:

  • Clear complexity targets guide development practices and code structure
  • Early warnings at complexity 13 encourage proactive simplification
  • Establishes shared understanding of acceptable complexity levels across team

Impact on Development Workflow

CI/CD Pipeline:

# Automated complexity checks now enforce threshold of 13
# Functions with complexity >13 fail the build
βœ— Complexity check failed: function 'example()' has complexity 14 (max: 13)

Local Development:

# Run complexity check locally
uv run check-complexity

# Output shows functions approaching threshold
# Functions with complexity 10-13 appear with metrics
# Functions with complexity >13 trigger failures

Code Review:

  • Reviewers see objective complexity metrics in PR status checks
  • Complexity scores visible before detailed review begins
  • Enables focused discussion on specific functions exceeding thresholds

🧹 Import Hygiene Re-enablement

Overview

Re-enable pycln checks in both the lint() and check() functions, ensuring unused imports are automatically detected and removed throughout the development lifecycle. This re-enablement follows resolution of Python 3.14 compatibility issues that previously required temporary disabling.

Background

The pycln tool was temporarily disabled in both linting and validation workflows due to compatibility issues with Python 3.14. Comments in the code indicated:

# check_pycln()  # <-- pycln is currently incompatible with python 3.14

Recent dependency updates or compatibility fixes have resolved this issue, enabling safe re-enablement across all supported Python versions (3.9-3.14).

Implementation Details

Files Modified:

  • src/utils/scripts.py

Changes in lint() function:

def lint() -> None:
    run_black()
    run_blacken_docs()
    run_isort()
-   # run_pycln()
+   run_pycln()

Changes in check() function:

def check() -> None:
    check_black()
    check_blacken_docs()
    check_mypy()
    check_isort()
    check_codespell()
-   # check_pycln()  # <-- pycln is currently incompatible with python 3.14
+   check_pycln()
    check_pylint()
    check_complexity()
    check_docstrings()
    check_pytest()
    check_mkdocs()
    check_build()

What is pycln?

pycln is a formatter for finding and removing unused import statements in Python code. It performs static analysis to identify imports that are never referenced in the module, then safely removes them to improve code cleanliness and reduce cognitive load when reading import sections.

Dual Integration Points

1. Automated Cleanup via lint():

  • Runs run_pycln() during code formatting workflow
  • Automatically removes unused imports when developers run uv run lint
  • Executes alongside black and isort for comprehensive code formatting
  • Enables developers to clean up imports before committing changes

2. Validation via check():

  • Runs check_pycln() during comprehensive quality validation
  • Verifies no unused imports exist in the codebase
  • Fails CI/CD pipeline if unused imports detected
  • Provides specific error messages identifying which imports to remove
  • Ensures all code in main branch maintains import hygiene

Technical Benefits

Code Quality Improvements:

  • Cleaner Import Sections: Automatically remove unused import statements, reducing clutter
  • Reduced Cognitive Load: Shorter import lists easier to understand and maintain
  • Dependency Hygiene: Prevent accumulation of unnecessary import dependencies
  • Consistent Standards: Enforce import cleanliness across entire codebase

Developer Experience Enhancements:

  • Automated Cleanup: Developers don't manually track which imports are unused
  • Pre-commit Safety: Running lint() cleans up imports before commits
  • CI/CD Validation: Automated checks catch any missed unused imports
  • Clear Error Messages: Specific feedback identifies exactly which imports to remove

Maintainability Benefits:

  • Reduced Noise: Fewer imports means easier code navigation
  • Faster Comprehension: Developers quickly identify actual dependencies
  • Simpler Refactoring: Unused imports don't confuse refactoring efforts
  • Better IDE Performance: Fewer imports reduce IDE analysis overhead

Usage Examples

Local Development Workflow:

# Run linting to automatically remove unused imports
uv run lint

# Runs black, blacken-docs, isort, and pycln
# Unused imports automatically removed from all files

Validation Workflow:

# Run comprehensive quality checks
uv run check

# Validates no unused imports exist
# Fails if any unused imports detected

What Gets Cleaned:

# Before: Module with unused imports
import sys          # ← unused
import os           # ← unused
from typing import Dict, List, Optional  # ← Optional unused
from pathlib import Path

def process_file(path: str) -> Dict[str, List[str]]:
    p = Path(path)
    return {"file": [str(p)]}

# After: pycln cleanup
from typing import Dict, List
from pathlib import Path

def process_file(path: str) -> Dict[str, List[str]]:
    p = Path(path)
    return {"file": [str(p)]}

πŸ“Š Complexity Reporting Optimisation

Overview

Add details = "low" configuration option to the complexipy tool configuration, optimising complexity report verbosity for improved signal-to-noise ratio in CI/CD logs whilst maintaining actionable feedback for developers.

Implementation Details

Files Modified:

  • pyproject.toml

Configuration Changes:

[tool.complexipy]
paths = "src/docstring_format_checker"
max-complexity-allowed = 13
quiet = false
ignore-complexity = false
+details = "low"
sort = "asc"

Configuration Option Details

details = "low":

  • Reduces verbosity of complexity analysis output
  • Focuses reporting on essential complexity metrics
  • Displays function names, complexity scores, and threshold violations
  • Omits detailed breakdown of complexity contributors (conditionals, loops, etc.)
  • Maintains actionable information whilst reducing log volume

Benefits

Improved CI/CD Logs:

  • Reduced Noise: Shorter complexity reports easier to scan in CI/CD output
  • Faster Diagnosis: Essential information highlighted without detailed breakdowns
  • Better Signal-to-Noise Ratio: Developers quickly identify functions exceeding thresholds
  • Maintained Actionability: Still provides function names and complexity scores for refactoring

Developer Productivity:

  • Quicker Log Review: Developers spend less time scrolling through verbose complexity output
  • Focused Feedback: Attention directed to functions requiring refactoring
  • Efficient Troubleshooting: Key metrics visible without information overload

Workflow Integration:

  • Local Development: Developers can still run verbose analysis when needed using command-line flags
  • CI/CD Pipeline: Automated checks provide concise, actionable feedback
  • Code Review: Reviewers see essential complexity metrics without overwhelming detail

Verbosity Levels

Before (details not set - defaults to "normal"):

Function: _validate_docstring_sections
Complexity: 12
  - If statements: 5
  - Loops: 2
  - Boolean operators: 3
  - Nested functions: 0
  ...detailed breakdown...

After (details = "low"):

Function: _validate_docstring_sections | Complexity: 12 | Status: βœ“ Pass

πŸ“ CHANGELOG Comprehensive Update

Overview

Comprehensive update to CHANGELOG.md documenting the entire v1.5.0 release with detailed sections covering all major improvements, refactoring efforts, and technical achievements.

Files Modified:

  • CHANGELOG.md

Changes:

  • Added 3,119 lines documenting v1.5.0 release
  • Removed 185 lines of placeholder or outdated content
  • Structured sections covering:
    • Complexity monitoring integration
    • CLI error display refactoring
    • Core module comprehensive refactoring
    • Documentation improvements (37 docstrings added)
    • CI/CD workflow enhancements
    • Developer experience improvements
    • Complete metrics and statistics tables
    • Detailed commit history
    • Migration guidance

The comprehensive changelog ensures users and maintainers have complete visibility into the evolution of the package, understanding both what changed and why those changes improve the codebase.

πŸ” Breaking Changes

None. This release maintains full backward compatibility with v1.5.0. All changes are internal quality enforcement mechanisms that do not affect:

  • Public APIs or interfaces
  • Command-line arguments or options
  • Configuration file formats
  • Runtime behaviour or output
  • Package functionality or features

🎯 Migration Guide

Upgrading from v1.5.0

No migration required. Users can upgrade directly from v1.5.0 to v1.5.1 without any configuration changes or code modifications.

# Upgrade with pip
pip install --upgrade docstring-format-checker

# Upgrade with uv
uv pip install --upgrade docstring-format-checker

# Verify version
python -c "import docstring_format_checker; print(docstring_format_checker.__version__)"
# Output: 1.5.1

Impact on Existing Projects

For Package Users:

  • No action required
  • All existing configurations continue working
  • Docstring validation behaviour unchanged
  • Command-line interfaces unchanged

For Contributors/Maintainers:

  • New contributions must pass stricter complexity threshold (13 instead of 15)
  • New contributions must have no unused imports (pycln checks enabled)
  • Existing code already complies with new standards
  • No immediate refactoring required

πŸš€ Installation and Upgrade

New Installation

# Install with pip
pip install docstring-format-checker==1.5.1

# Install with uv
uv pip install docstring-format-checker==1.5.1

# Install from GitHub
pip install git+https://github.com/data-science-extensions/docstring-format-checker.git@v1.5.1

Upgrade from Previous Version

# Upgrade with pip
pip install --upgrade docstring-format-checker

# Upgrade with uv
uv pip install --upgrade docstring-format-checker

# Verify upgrade successful
dfc --version
# Output: docstring-format-checker v1.5.1

πŸ“Š Quality Metrics

Code Quality Standards

Metric Value Change from v1.5.0
Test Coverage 100% No change βœ“
Total Statements 834 No change
Tests Passing 183/183 No change βœ“
Pylint Score 10.00/10 No change βœ“
Total Complexity 309 No change
Max Complexity Threshold 13 -2 (was 15) ⬇️
Functions β‰₯15 Complexity 0 No change βœ“
Functions ≀9 Complexity 93+ No change βœ“

Quality Gate Comparison

Quality Gate v1.5.0 v1.5.1 Change
Complexity Threshold 15 13 Stricter ⬆️
pycln Checks ❌ Off βœ… On Enabled βœ…
Complexity Verbosity Normal Low Optimised
Test Coverage Required 100% 100% No change
Pylint Score Required 10/10 10/10 No change

Validation Results

All quality checks pass with new stricter standards:

$ uv run check

βœ… Black formatting: PASSED
βœ… Blacken-docs: PASSED  
βœ… MyPy type checking: PASSED
βœ… isort import sorting: PASSED
βœ… codespell spelling: PASSED
βœ… pycln unused imports: PASSED (re-enabled)
βœ… Pylint static analysis: PASSED (10.00/10)
βœ… Complexity analysis: PASSED (max threshold 13)
βœ… Docstring validation: PASSED
βœ… Pytest test suite: PASSED (183/183 tests)
βœ… MkDocs documentation: PASSED
βœ… Package build: PASSED

All checks passed! βœ“

πŸ› οΈ Developer Experience

Strengthened Quality Assurance

Proactive Prevention:

  • Stricter complexity threshold catches potential issues earlier
  • Automated import cleaning eliminates manual tracking burden
  • Optimised verbosity improves log readability and debugging efficiency

Clear Feedback Loops:

  • Complexity violations provide specific function names and scores
  • pycln errors identify exact import statements to remove
  • CI/CD failures include actionable guidance for resolution

Maintained Productivity:

  • Automated cleanup via uv run lint handles routine maintenance
  • Validation via uv run check ensures quality before pushing
  • No additional manual steps required in development workflow

Quality Enforcement Workflow

# 1. Develop feature
vim src/docstring_format_checker/new_module.py

# 2. Run automated cleanup
uv run lint
# β†’ Formats code with black
# β†’ Sorts imports with isort  
# β†’ Removes unused imports with pycln

# 3. Validate quality standards
uv run check
# β†’ Validates complexity ≀13
# β†’ Confirms no unused imports
# β†’ Runs full test suite
# β†’ All quality gates must pass

# 4. Commit clean, validated code
git add .
git commit -m "Add new feature"

# 5. CI/CD validates on push
# β†’ Same checks run automatically
# β†’ Pull request blocked if any check fails
# β†’ Immediate feedback for corrections

πŸ“š Additional Resources

Documentation

Configuration Reference

Recommended pyproject.toml Configuration:

[tool.docstring_format_checker]
exclude_patterns = ["test_*.py", "*_test.py"]

[tool.docstring_format_checker.sections.Summary]
required = true
format = "free_text"

[tool.complexipy]
paths = "src/your_package"
max-complexity-allowed = 13  # Stricter threshold
quiet = false
ignore-complexity = false
details = "low"  # Optimised verbosity
sort = "asc"

Running Quality Checks

# Run all quality checks
uv run check

# Run specific checks
uv run check-black          # Code formatting
uv run check-mypy           # Type checking
uv run check-isort          # Import sorting
uv run check-pycln          # Unused imports (re-enabled)
uv run check-pylint         # Static analysis
uv run check-complexity     # Cognitive complexity (threshold 13)
uv run check-docstrings     # Docstring validation
uv run check-pytest         # Test suite

# Run automated cleanup
uv run lint                 # Formats code and removes unused imports

πŸ”— Related Releases

Version History

v1.5.1 (Current):

  • Stricter complexity threshold (15 β†’ 13)
  • Re-enabled pycln import cleaning
  • Optimised complexity reporting verbosity

v1.5.0 (Previous):

  • Complexity monitoring integration with complexipy
  • Seven major refactoring efforts reducing complexity 6.9%
  • 37 docstrings added across three modules
  • 24 new focused helper methods created
  • CI/CD workflow parallelism improvements

v1.4.0:

  • Python 3.14 support added
  • 100% test coverage achieved (783 statements)
  • Pylint integration with comprehensive configuration
  • Pre-commit hook integration

πŸ“ Detailed Commit History

Commits Since v1.5.0

  1. b935a81 - Merge pull request #20 from data-science-extensions/updates

    • Merged comprehensive quality standards enhancements
    • Integrated stricter complexity thresholds
    • Re-enabled import hygiene checks
  2. 257cfa2 - Tweak the config for complexipy

    • Reduced max-complexity-allowed from 15 to 13
    • Added details = "low" for optimised reporting verbosity
    • Enforces stricter complexity standards preventing regression
  3. 36d50e1 - Add pycln checks back in

    • Re-enabled run_pycln() in lint() function
    • Re-enabled check_pycln() in check() function
    • Removed Python 3.14 incompatibility comment
    • Ensures automated unused import detection and removal
  4. 0f856a3 - Fix formatting

    • Minor formatting adjustments for code consistency

πŸ’ͺ Pull Requests

  • Enhance Code Quality Standards: Stricter Complexity Thresholds and Re-Enable pycln checks by @chrimaho in #20

Full Changelog: v1.5.0...v1.5.1