Releases: data-science-extensions/docstring-format-checker
v1.11.4
📋 Overview
Significantly expand the project documentation with comprehensive usage guides and detailed CLI walkthroughs. This release also introduces performance optimisations for file discovery on Linux systems, refines the integration instructions for pre-commit, and standardises the grammatical tone across the entire codebase.
✨ New Features
📘 Introduce comprehensive usage documentation
Create three new major documentation sections to assist developers at all experience levels.
- Provide a clear installation path and a guided first check in the getting_started.md guide.
- Detail every global and section-specific configuration option with practical examples and troubleshooting tips in the configuration.md page.
- Deliver an extensive walkthrough of command-line interactions, including sample terminal outputs and format comparisons, in the command_line_interface.md guide.
🚀 Optimise file discovery performance
Refactor the get_all_files() function in scripts.py to utilise the Linux find command for significantly faster file retrieval in large repositories. Maintain a robust fallback to the Path.glob() method to ensure cross-platform compatibility.
⚙️ Technical Improvements
🛡️ Refine file exclusion logic for documentation
Enhance the check_blacken_docs() and run_blacken_docs() functions to exclude documentation markdown files from the blacken-docs process. This ensures that intentional "bad" code examples used for demonstration purposes remain unfixed by the formatter, preserving their educational value.
🔗 Improve pre-commit and installation guides
Update the README.md with modern installation instructions for every major package manager, referencing the latest 1.* version. Introduce a dedicated section for pre-commit integration with an example configuration for .pre-commit-config.yaml to help users automate their docstring validation.
🛠️ Clean up internal callbacks and metadata
Remove redundant parameter descriptions for ctx, param, and value within the _show_usage_examples_callback() and _show_config_example_callback() functions in cli.py. Update the GlobalConfig() and SectionConfig() dataclasses in config.py with descriptive field() metadata to improve IDE tooltip clarity.
✍️ Documentation and Styling
🎨 Enhance visual documentation styling
Introduce custom CSS styling in code_chunks.css to display the TOML logo icon next to configuration code blocks. Update the mkdocs.yaml configuration to enable the content.code.select and content.code.copy features, and standardise the code font to improve readability.
📋 Standardise internal grammatical tone
Perform a comprehensive linguistic sweep to ensure that all internal docstrings and comments follow a consistent grammatical structure. Standardise descriptions of dfc behaviour to use the third-person singular (e.g., "reports", "fails", "checks") to provide a professional and unified tone throughout the project.
💪 Pull Requests
- Enhance documentation, introduce comprehensive usage guides, and improve file discovery performance by @chrimaho in #39
Full Changelog: v1.11.3...v1.11.4
v1.11.3
📃 Overview
Introduce a comprehensive JSON Schema generation pipeline to automate the validation of pyproject.toml configurations. This release also enhances the configuration models with rich metadata for improved IDE support and refines the CI workflow to ensure schema integrity across the codebase.
✨ New Features
🏗️ Implement JSON Schema Generation Pipeline
Introduce the DFCSchemaGenerator() and PyprojectSchemaGenerator() classes to automatically generate JSON schemas from internal Python configuration models. This ensures that the configuration options are always synchronised with the current implementation.
⚙️ Technical Improvements
📝 Enhance Configuration Metadata
Extend the GlobalConfig() and SectionConfig() dataclasses in config.py with descriptive metadata using the field() function. This enables modern IDEs such as VS Code to provide real-time tooltips and autocomplete for the [tool.dfc] section in pyproject.toml.
🛡️ Integrate Schema Integrity Workflow in CI
Update the CI pipeline in ci.yml to automatically generate and verify JSON schemas. The workflow now ensures that any changes to configuration models are reflected in the generated schemas, preventing documentation drift.
⚙️ Refine Schema Generator Robustness
Improve the reliability of the generate_config_schema.py utility with several robust enhancements.
- Handle
OptionalandUniontypes more effectively, ensuring correct mapping to JSON Schema type arrays andnullvalues. - Standardise the detection of
Literaltypes using theget_origin()function. - Optimise package information retrieval by replacing the
lru_cache()decorator with thecached_property()decorator for better performance. - Implement conditional imports for
tomllibto maintain compatibility with Python versions below 3.11 using thetomlipackage.
🐛 Fix Documentation and Formatting
Resolve issues with broken URLs and standardise formatting across documentation files to improve clarity and maintainability.
📙 Documentation
📘 Document the JSON Schema System
Initialise a comprehensive README.md in the src/schemas/json/ directory to guide developers on how to enable and maintain JSON Schema validation for their local project configurations.
💪 Pull Requests
- Introduce automated JSON Schema generation for
pyproject.tomlconfiguration validation by @chrimaho in #38
Full Changelog: v1.11.2...v1.11.3
v1.11.2 - Doctest Utilities and Configuration Refinement
📃 Overview
Introduce new utility functions for executing doctests and refine the configuration loading process to better handle unordered sections. This release also standardises documentation metadata and improves the reliability of the coverage reporting workflow.
✨ New Features
🔍 Integrate Doctest Checking Functions
Introduce automated doctest execution to verify code examples within docstrings.
- Implement the
check_doctest()function insrc/utils/scripts.pyto run doctests across all Python files in the package. - Implement the
check_doctest_module()function to target specific modules for doctest validation. - Implement the
check_doctest_cli()function to provide a command-line interface for module-specific doctest checking.
🐛 Bug Fixes
⚙️ Refine Configuration Order Validation
Resolve an issue where multiple sections without an explicit order value caused duplicate key errors.
- Update the
SectionConfig()class to consistently allowNonefor theorderattribute. - Update the
_parse_sections_config()function inconfig.pyto remove the default value of0when extractingorderfrom configuration data. - Ensure that sections without an explicit order are correctly sorted to the end of the validation sequence.
⚙️ Technical Improvements
🚀 Enhance Project Workflow
Improve the robustness of the development and documentation workflows.
- Update the
git_add_coverage_report()function to use the--forceflag when adding the coverage report directory, ensuring reports are captured regardless of ignore rules. - Fix typographical errors and standardise the project title to
docstring-format-checkeracross documentation files. - Refine the documentation home page to use a dedicated
coverpage_icon_sourcevariable inmkdocs.yamlfor better maintainability.
💪 Pull Requests
Full Changelog: v1.11.1...v1.11.2
v1.11.1 - Static Type Checking and Robust Sorting
📃 Overview
Introduce static type checking with Pyright and refine the section sorting logic to improve the robustness and reliability of the docstring validation process. This release also enhances the test suite with more explicit assertions and optimises the development workflow.
✨ New Features
🔍 Integrate Pyright Static Analysis
Integrate pyright into the development workflow to ensure strict type safety across the codebase.
- Add
pyrightto thedevdependency group inpyproject.toml. - Implement the
check_pyright()function insrc/utils/scripts.pyto perform automated static analysis. - Update the
check()function to include Pyright validation as a standard step in the project's quality assurance process.
🐛 Bug Fixes
⚙️ Refine Section Sorting Logic
Improve the robustness of the section sorting mechanism when handling optional order values.
- Update the
_parse_sections_config()function inconfig.pyto handleNonevalues for section orders by defaulting tofloat("inf"). This ensures that unordered sections are consistently placed at the end of the sequence. - Standardise the sorting logic within the
._build_section_patterns()and._build_expected_section_order()methods in theDocstringChecker()class to handle optional orders gracefully.
⚙️ Technical Improvements
🧪 Enhance Test Assertions
Strengthen the test suite by introducing more explicit assertions and type validations.
- Add assertions to verify that
func_nodeis an instance of theast.FunctionDef()orast.AsyncFunctionDef()class in various test cases. - Update the
TestParameterMismatch()class to verify thatdocstringanderror_messageare notNonebefore performing string operations, resolving potential type errors and improving test reliability.
🧹 Optimise Validation Workflow
Refine the project's validation script and repository maintenance.
- Reorder the
check()function inscripts.pyto executecheck_mkdocs()aftercheck_build(), ensuring that the documentation build is verified after the package build. - Update the
.gitignorefile to include the.complexipy_cache/*pattern, preventing local cache artefacts from being tracked.
💪 Pull Requests
Full Changelog: v1.11.0...v1.11.1
v1.11.0 - Flexible Section Ordering and Multi-word Headers
📃 Overview
Introduce support for unordered docstring sections and multi-word section headers to provide greater flexibility in docstring formatting. This release also includes bug fixes for section name validation and improvements to the test suite.
✨ New Features
🔓 Support Unordered Sections
Allow sections to be defined with order = null in the configuration. These sections can appear anywhere within a docstring without triggering sequence validation errors. This is particularly useful for sections like Deprecation Warning or Note that may appear at different positions depending on the context.
📝 Support Multi-word Section Headers
Update the section detection logic to support headers containing multiple words. This enables the use of descriptive section names such as Custom List or Deprecation Warning while maintaining strict validation of other rules like colon usage and title casing.
🐛 Bug Fixes
🐛 Fix Multi-word Section Validation
Resolve an issue where multi-word section names were incorrectly triggering "requires parenthesized types" errors. The validation regex now correctly handles spaces within section headers.
🛠️ Fix Test Suite Syntax Error
Correct a SyntaxError in the test helper _check_docstring() caused by improper indentation of generated Python content.
⚙️ Technical Improvements
🧪 Expand Test Coverage
Add a comprehensive suite of tests for unordered sections, covering various placements, case-insensitivity, and interaction with required sections. Maintain 100% code coverage across the entire project.
📖 Update Documentation
Update the README.md to include details and examples for the new flexible section ordering feature.
💪 Pull Requests
Full Changelog: v1.10.1...v1.11.0
v1.10.1 - Standardise Dependencies and Modernise CI/CD Workflows
📝 Summary
This release focuses on standardising the project's dependency management and modernising the CI/CD workflows to ensure robust support across multiple Python versions. Introduce environment markers in pyproject.toml to allow for version-specific package requirements, specifically supporting Python 3.9 while leveraging newer package versions for Python 3.10 and above. Upgrade several key GitHub Actions to their latest versions to improve security, performance, and reliability. Ensure a more consistent and maintainable development environment through these targeted enhancements.
📊 Release Statistics
| Attribute | Note |
|---|---|
| Version: | v1.10.1 |
| Python Support: | 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 |
| Test Coverage: | 100% (1035 statements) |
| Pylint Score: | 10.00/10 |
| Complexity: | All functions ≤13 threshold |
| Functions: | 106 |
| Tests Passing: | 250/250 |
| Files Changed: | 3 |
| Lines Added: | 37 |
| Lines Removed: | 30 |
| Commits: | 12 |
| Pull Requests Merged: | 6 (PR #29, #30, #31, #32, #33, #34) |
🎯 Standardise Dependencies with Python Version Markers
🔍 Overview
Improve the project's dependency management by introducing environment markers that allow for version-specific package requirements. This ensures that the project remains compatible with Python 3.9 while taking advantage of newer features and bug fixes available in more recent package versions for Python 3.10 and above.
🛠️ Key Improvements
Introduce Environment Markers
Refactor pyproject.toml to use environment markers for several key dependencies. This allows the project to specify different version ranges based on the Python runtime version.
- Update
devdependencies:ipykernel: Use6.*for Python <3.10 and7.*for Python >=3.10.isort: Use6.*for Python <3.10 and7.*for Python >=3.10.pylint: Use3.*for Python <3.10 and4.*for Python >=3.10.
- Adjust
docsrequirements:docstring-inheritance: Use2.*for Python <3.10 and3.*for Python >=3.10.mkdocstrings: Use0.*for Python <3.10 and1.*for Python >=3.10.mkdocstrings-python: Use1.*for Python <3.10 and2.*for Python >=3.10.
- Bump
testdependencies:pytest: Use8.*for Python <3.10 and9.*for Python >=3.10.complexipy: Upgrade to5.*to leverage the latest complexity analysis features.
Standardise Dependency Formatting
Ensure consistent formatting across all dependency definitions. Standardise the whitespace and structure of environment markers to improve readability and maintainability.
⚙️ Modernise CI/CD Workflows and GitHub Actions
🔍 Overview
Upgrade the project's CI/CD infrastructure by bumping several key GitHub Actions to their latest versions. This ensures that the project benefits from the latest security patches, performance improvements, and feature updates provided by the action maintainers.
🛠️ Key Improvements
Upgrade GitHub Actions
Bump the versions of several essential GitHub Actions used in the ci.yml and cd.yml workflows:
actions/checkout: Upgrade fromv5tov6.actions/setup-python: Upgrade fromv5tov6.actions/upload-artifact: Upgrade fromv4tov6.actions/download-artifact: Upgrade fromv5tov7.astral-sh/setup-uv: Upgrade fromv6tov7.
Refine Workflow Configurations
Update the workflow files to ensure consistent environment handling and version referencing. Standardise the use of ${{ env.VERSION }} and other environment variables to improve the reliability of the automated build and release processes.
💪 Pull Requests
- Bump actions/checkout from 5 to 6 by @dependabot[bot] in #32
- Bump astral-sh/setup-uv from 6 to 7 by @dependabot[bot] in #33
- Bump actions/upload-artifact from 4 to 6 by @dependabot[bot] in #31
- Bump actions/setup-python from 5 to 6 by @dependabot[bot] in #29
- Bump actions/download-artifact from 5 to 7 by @dependabot[bot] in #30
- Standardise Dependency Versioning Across Python Versions by @chrimaho in #34
New Contributors
- @dependabot[bot] made their first contribution in #32
Full Changelog: v1.10.0...v1.10.1
v1.10.0 - Enhance Section Validation and Update Dependencies
📝 Summary
This release focuses on improving the robustness of docstring section validation, particularly regarding case sensitivity and error reporting. Standardise section header detection to handle various capitalisation styles while preserving original casing in error messages. Modernise the project's dependency management by introducing Dependabot and upgrading several pre-commit hooks. Refactor utility scripts for better clarity and update package metadata to align with standard practices. Ensure a more consistent and user-friendly experience through these enhancements.
📊 Release Statistics
| Attribute | Note |
|---|---|
| Version: | v1.10.0 |
| Python Support: | 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 |
| Test Coverage: | 100% (1035 statements, +2 from v1.9.0) |
| Pylint Score: | 10.00/10 |
| Complexity: | All functions ≤13 threshold |
| Functions: | 106 (unchanged from v1.9.0) |
| Tests Passing: | 250/250 (unchanged from v1.9.0) |
| Files Changed: | 8 |
| Lines Added: | 76 |
| Lines Removed: | 53 |
| Commits: | 10 |
| Pull Requests Merged: | 1 (PR #29) |
🎯 Enhance Docstring Section Validation
🔍 Overview
Improve the reliability of section detection and validation within docstrings. Ensure that the tool correctly identifies configured sections regardless of their case in the docstring, while providing clearer error messages.
🛠️ Key Improvements
Case-Insensitive Matching
Refactor several internal methods to handle section names more robustly. Lowercase section names for configuration lookups but preserve the original case when reporting errors to the user.
- Update
._validate_single_admonition()to use a lowercased version of the section title for configuration checks. - Refactor
._validate_admonition_has_no_colon()to ensure consistent case-insensitive lookup. - Improve
._check_non_admonition_colon_usage()to correctly identify non-admonition sections regardless of case. - Standardise section header detection in
._detect_any_section_header()and._detect_section_header().
Clearer Error Reporting
Update ._validate_all_required_sections() to wrap missing section names in single quotes. This makes the error messages more readable and consistent with other validation errors.
Example of new output:
Missing required section: 'summary'
⚙️ Update Dependencies and CI/CD Workflows
🔍 Overview
Modernise the development environment and automate dependency maintenance to ensure the project remains secure and up-to-date.
🛠️ Key Improvements
Automate Dependency Updates
Introduce a new .github/dependabot.yml configuration to enable weekly automated updates for GitHub Actions. Include custom labels and designated reviewers to streamline the maintenance process.
Upgrade Pre-commit Hooks
Bump the versions of several key pre-commit hooks to leverage the latest improvements and bug fixes:
| Hook | Old Version | New Version |
|---|---|---|
black |
25.1.0 |
25.12.0 |
blacken-docs |
1.19.1 |
1.20.0 |
isort |
6.0.1 |
7.0.0 |
pyupgrade |
v3.20.0 |
v3.21.2 |
pycln |
v2.5.0 |
v2.6.0 |
uv-pre-commit |
0.8.8 |
0.9.21 |
Refine CI/CD Workflow
Update the .github/workflows/cd.yml workflow to use ${{ env.VERSION }} consistently for version references. Expose GITHUB_TOKEN and REPOSITORY_NAME to the changelog generation step to ensure it has the necessary context.
🧹 Refactor Utility Scripts and Metadata
🔍 Overview
Clean up internal utility scripts and ensure package metadata is correctly defined.
🛠️ Key Improvements
Improve Script Clarity
Add a comprehensive file header to src/utils/scripts.py that outlines its purpose, usage, and provides examples. Improve the discoverability and usability of the internal tooling.
Simplify Git Operations
Refactor git_fix_tag_reference() to remove redundant comments and simplify the implementation. Fix a minor formatting issue in git_refresh_current_branch() by removing an extra space in the git pull command.
Update Package Metadata
Refactor src/docstring_format_checker/__init__.py to use the correct Author-email metadata key. Ensure that the author's email is correctly exposed in the package metadata as __author_email__.
🧪 Improve Test Consistency
🔍 Overview
Update the test suite to align with the improved error message formatting.
🛠️ Key Improvements
Update Assertions
Refactor tests in src/tests/test_cli.py and src/tests/test_core.py to expect the new quoted format for missing section errors. Ensure that the test suite remains in sync with the core validation logic.
What's Changed
Full Changelog: v1.9.0...v1.10.0
v1.9.0 - Improve Parameter Mismatch Reporting and Test Robustness
📝 Summary
The focus of this release is on improving the clarity of parameter mismatch error messages and enhancing the robustness of the test suite. Introduce targeted detection for variadic parameters (*args, **kwargs) documented with leading asterisks in docstrings, and provide actionable guidance to remove them. Refactor test assertions to use native Python assert statements, standardise return type annotations in tests, and fix various formatting issues in test data generation. Ensure a more user-friendly experience and a more maintainable codebase through these enhancements.
📊 Release Statistics
| Attribute | Note |
|---|---|
| Version: | v1.9.0 |
| Python Support: | 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 |
| Test Coverage: | 100% (1033 statements, +11 from v1.8.0) |
| Pylint Score: | 10.00/10 |
| Complexity: | All functions ≤13 threshold |
| Functions: | 106 (unchanged from v1.8.0) |
| Tests Passing: | 250/250 (+2 from v1.8.0) |
| Files Changed: | 6 |
| Lines Added: | 119 |
| Lines Removed: | 20 |
| Commits: | 12 |
| Pull Requests Merged: | 1 (PR #27) |
🎯 Improve Parameter Mismatch Reporting
🔍 Overview
Enhance the parameter mismatch error output to provide clearer, more actionable feedback when variadic parameters are documented with leading asterisks. Reduce confusion by identifying that the parameter names match once the asterisks are ignored, rather than reporting them as entirely separate missing and extra parameters.
❓ Problem Statement
When validating functions with *args or **kwargs, the tool previously reported a mismatch if the docstring included the asterisks (e.g., *args (Any):). This resulted in a confusing error message that listed the parameter as both missing from the docstring (without asterisks) and extra in the docstring (with asterisks).
Example of previous confusing output:
Params section mismatch:
- In signature but not in docstring: 'args', 'kwargs'
- In docstring but not in signature: '*args', '**kwargs'
💡 Solution
Update the mismatch detection logic to recognise when a parameter name in the docstring matches a signature parameter after stripping leading asterisks.
Targeted Asterisk Detection
Update ._build_param_mismatch_error() to detect asterisk-only mismatches. When found, the tool now emits a specific message:
Parameter mismatch:
- Parameter 'args' found in docstring as '*args'. Please remove the asterisk.
- Parameter 'kwargs' found in docstring as '**kwargs'. Please remove the asterisks.
Robust Parameter Extraction
Strengthen the regex pattern in ._extract_documented_params() to correctly capture parameters with exactly zero, one, or two leading asterisks using \*{0,2}. Ensure that only valid Python parameter prefix patterns are matched.
🧪 Enhance Test Suite Robustness
🔍 Overview
Refactor the test suite to improve readability, maintainability, and alignment with modern Python testing standards. Standardise assertions, improve type safety, and fix formatting issues in test data.
🛠️ Key Improvements
Standardise Assertions
Replace unittest style assertions (e.g., .assertIn(), .assertFalse()) with native Python assert statements across the test suite. Align the codebase with pytest conventions and improve the readability of test failures.
Improve Type Safety
Add explicit None return type annotations to various test methods in src/tests/test_core.py. Ensure better type checking and consistency across the test suite.
Fix Test Data Formatting
Utilise dedent() for all dynamically generated Python file content in tests. Ensure that leading whitespace is correctly handled, preventing potential parsing issues or incorrect indentation in temporary test files.
Resolve Syntax Conflicts
Fix nested docstring syntax in test cases by replacing inner triple double quotes with triple single quotes. Prevent syntax errors when parsing code blocks that contain their own docstrings.
⚙️ Internal Refactorings
🛡️ Avoid Input Mutation
Refactor ._build_param_mismatch_error() to work with local copies of the missing_in_docstring and extra_in_docstring lists. Prevent unintended side effects on caller functions that might rely on the original lists remaining unchanged.
📏 Improve Test Output Visibility
Increase the default diff width for test output to 120 characters in pyproject.toml. Ensure that long error messages and diffs are clearly visible in the terminal without being prematurely wrapped.
💪 Pull Requests
Full Changelog: v1.8.0...v1.9.0
v1.8.0 - Support All Python Function Parameter Types
Summary
This release introduces comprehensive support for all Python function parameter types, ensuring accurate docstring validation for complex function signatures. It adds recognition for positional-only parameters (before /), keyword-only parameters (after *), variable positional arguments (*args), and variable keyword arguments (**kwargs). Additionally, this release fixes default value detection for positional-only arguments and updates the package configuration. These enhancements ensure that the docstring format checker correctly identifies and validates parameters across all modern Python function definitions.
Release Statistics
| Attribute | Note |
|---|---|
| Version: | v1.8.0 |
| Python Support: | 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 |
| Test Coverage: | 100% (1022 statements, +23 from v1.7.0) |
| Pylint Score: | 10.00/10 |
| Complexity: | All functions ≤13 threshold |
| Functions: | 106 (-3 from v1.7.0) |
| Tests Passing: | 248/248 (+7 from v1.7.0) |
| Files Changed: | 3 |
| Lines Added: | 2520 |
| Lines Removed: | 2168 |
| Commits: | 4 |
| Pull Requests Merged: | 1 (PR #26) |
🎯 Enhance Parameter Extraction
Overview
Introduce comprehensive parameter extraction logic to support all five Python parameter types: positional-only, positional-or-keyword, variable positional, keyword-only, and variable keyword arguments. This ensures that the docstring format checker correctly identifies and validates parameters in complex function signatures, including those using / and * separators.
Problem Statement
Incomplete Parameter Extraction
The docstring format checker previously only extracted standard positional parameters (args.args) from function signatures. It failed to recognise:
- Positional-Only Parameters (before
/): Parameters that must be passed by position. - Keyword-Only Parameters (after
*): Parameters that must be passed by name. - Variable Positional Arguments (
*args): Arbitrary positional arguments. - Variable Keyword Arguments (
**kwargs): Arbitrary keyword arguments.
This limitation caused validation errors or false positives when checking functions that utilised these modern Python features.
Real-World Example:
Consider this function using keyword-only parameters:
@overload
def print_or_log_output(message: str, print_or_log: Literal["print"]) -> None: ...
@overload
def print_or_log_output(
message: str,
print_or_log: Literal["log"],
*,
log: Logger,
log_level: log_levels = "info",
) -> None: ...
def print_or_log_output(
message: str,
print_or_log: Literal["print", "log"] = "print",
*,
log: Optional[Logger] = None,
log_level: log_levels = "info",
) -> None:
"""
Print or log the output.
Params:
message (str): The message to print or log.
print_or_log (Literal["print", "log"]): The action to perform.
log (Optional[Logger]): The logger to use.
log_level (log_levels): The log level to use.
"""
...Previously, the checker would fail to find log and log_level in the function signature, reporting them as undocumented parameters or extra parameters in the docstring.
Solution
Comprehensive Parameter Extraction
Implement a new ._extract_all_params() method in the DocstringChecker class that iterates through all parameter categories in the AST arguments node:
posonlyargs: Positional-only arguments.args: Positional-or-keyword arguments.vararg: Variable positional arguments (*args).kwonlyargs: Keyword-only arguments.kwarg: Variable keyword arguments (**kwargs).
Enhanced Type Annotation Capture
Update the ._extract_param_types() method to utilise ._extract_all_params(), ensuring that type annotations are captured for every parameter found. This allows the validator to correctly match docstring types with signature types for all parameter kinds.
Improved Validation Logic
Refactor ._is_params_section_required() and ._validate_param_types() to account for the presence of any parameter type, ensuring that docstrings are required and validated whenever any parameters exist in the signature.
💪 Pull Requests
Full Changelog: v1.7.0...v1.8.0
v1.7.0 - Add Configurable Optional Suffix Validation
Summary
This release introduces a major new feature: configurable validation for the , optional suffix in parameter docstrings through three distinct modes ("silent", "validate", "strict") that accommodate different documentation styles from legacy codebases to strict standards. Additionally, this release modernises the type checking infrastructure by migrating from [mypy] to [ty], delivering faster performance and better Python 3.14 support. GitHub Actions workflows are updated to Python 3.14, removing deprecated configuration parameters whilst maintaining comprehensive CI/CD coverage. The implementation includes five new validation methods with complete test coverage, bringing the total to 241 passing tests whilst maintaining 100% code coverage (999 statements) and a perfect Pylint score of 10.00/10. These enhancements enable fine-grained control over optional parameter documentation patterns whilst modernising the project's tooling infrastructure for continued Python evolution.
Release Statistics
| Attribute | Note |
|---|---|
| Version: | [v1.7.0] |
| Python Support: | 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 |
| Test Coverage: | 100% (999 statements, +48 from v1.6.3) |
| Pylint Score: | 10.00/10 |
| Complexity: | All functions ≤13 threshold |
| Functions: | 109 (+3 validation methods) |
| Tests Passing: | 241/241 (+18 from v1.6.3) |
| Files Changed: | 9 |
| Lines Added: | 684 |
| Lines Removed: | 48 |
| Commits: | 4 (3 feature commits + 1 merge) |
| Pull Requests Merged: | 1 (PR #25) |
| Type Checker: | Ty v0.0.4 (migrated from MyPy v1.14.1) |
| Python Version: | 3.14 (upgraded from 3.13 in workflows) |
🎯 Configurable Optional Suffix Validation
Overview
Introduce comprehensive validation system for the , optional suffix in parameter docstrings with three configurable modes that accommodate different documentation philosophies: from legacy compatibility to strict enforcement. This feature addresses the long-standing inconsistency in Python docstring conventions where some projects require explicit , optional suffixes for parameters with default values whilst others omit them entirely, relying on type hints or default value mentions.
Problem Statement
Documentation Inconsistency Challenge
Python docstrings lack a standardised convention for indicating optional parameters (those with default values). Different projects adopt varying approaches:
- NumPy Style Projects: Use
, optionalsuffix explicitly (e.g.,param (int, optional):) - Google Style Projects: Often omit suffix, rely on default value mention in description
- Sphinx Style Projects: Inconsistent usage across different codebases
- Modern Type Hint Projects: Already specify optionality via
Optional[]or defaults
This inconsistency creates several challenges:
- No Tool Support: Existing docstring validators don't enforce
, optionalusage patterns - Maintenance Burden: Manually tracking which parameters need
, optionalis error-prone - Refactoring Risk: Adding/removing defaults doesn't automatically update docstrings
- False Positives: Type checkers may report mismatches when
, optionalis present - Unclear Requirements: Teams lack guidance on whether to use
, optionalsuffix
Real-World Example:
Consider this function evolution during refactoring:
# Initial implementation
def create_report(data: pd.DataFrame, format: str) -> Report:
"""
Create a report from data.
Params:
data (pd.DataFrame):
The input data.
format (str):
Output format.
"""
...
# After refactoring - added optional parameter
def create_report(data: pd.DataFrame, format: str = "pdf") -> Report:
"""
Create a report from data.
Params:
data (pd.DataFrame):
The input data.
format (str):
Output format. # <-- Should this be 'str, optional'?
"""
...Questions Development Teams Face:
- Should the docstring be updated to
format (str, optional):? - If yes, who ensures consistency across the entire codebase?
- If no, how do documentation readers know which parameters are optional?
- What about existing docstrings with
, optionalon required parameters?
Type Mismatch Confusion
When , optional suffix appears in docstrings, it creates type annotation mismatches:
def example(x: int, y: int = 0) -> None:
"""
Example function.
Params:
x (int):
Required parameter.
y (int, optional): # <-- Type checker sees: "int, optional" ≠ "int"
Optional parameter.
"""
...DFC's parameter type validation (introduced in v1.6.0) would report:
Parameter type mismatch for 'y':
- Signature: int
- Docstring: int, optional
This is a "false positive" - the types match, but the , optional suffix causes validation to fail. Teams needed a way to handle this suffix appropriately based on their documentation standards.
Solution Architecture
Three Validation Modes
Implement three distinct validation modes to accommodate different project requirements and documentation philosophies:
| Mode | Behaviour | Use Case |
|---|---|---|
"silent" |
Strip , optional from docstring types before comparison |
Legacy codebases with inconsistent , optional usage |
"validate" |
Error if , optional appears on required parameters |
Ensure , optional only used correctly when present |
"strict" |
Require , optional for all parameters with defaults |
Enforce consistent , optional usage across entire codebase |
Mode Comparison:
def example(x: int, y: int = 0) -> None:
"""
Params:
x (int, optional): Wrong - x is required
y (int): Missing optional suffix
"""
...
# "silent" mode: No errors (strips all ', optional' suffixes)
# "validate" mode: Error - x has ', optional' but no default value
# "strict" mode: Two errors - x has ', optional' but no default, y missing ', optional'Configuration Integration
Add new optional_style configuration field to GlobalConfig class:
Files Modified:
src/docstring_format_checker/config.pysrc/docstring_format_checker/cli.py
Configuration Changes:
# In src/docstring_format_checker/config.py
@dataclass
class GlobalConfig:
allow_undefined_sections: bool = False
require_docstrings: bool = True
check_private: bool = False
validate_param_types: bool = True
optional_style: Literal["silent", "validate", "strict"] = "validate"Location: Lines 115-118 in src/docstring_format_checker/config.py
Configuration File Example:
# In pyproject.toml
[tool.dfc]
allow_undefined_sections = false
require_docstrings = true
check_private = true
validate_param_types = true
optional_style = "validate" # Options: "silent", "validate", "strict"
sections = [...]Configuration Validation
Add validation logic in _parse_global_config() function to ensure optional_style contains valid values:
# In src/docstring_format_checker/config.py
def _parse_global_config(tool_config: dict[str, Any]) -> GlobalConfig:
# Validate optional_style if provided
optional_style: str = tool_config.get("optional_style", "validate")
valid_styles: tuple[str, str, str] = ("silent", "validate", "strict")
if optional_style not in valid_styles:
raise InvalidConfigError(
f"Invalid optional_style: '{optional_style}'. Must be one of: {', '.join(valid_styles)}"
)
return GlobalConfig(
allow_undefined_sections=tool_config.get("allow_undefined_sections", False),
require_docstrings=tool_config.get("require_docstrings", True),
check_private=tool_config.get("check_private", False),
validate_param_types=tool_config.get("validate_param_types", True),
optional_style=optional_style, # type:ignore
)Location: Lines 452-464 in src/docstring_format_checker/config.py
Validation Benefits:
- Fail fast with clear error message for invalid configuration values
- Prevent runtime errors from configuration typos
- Provide explicit list of valid options in error message
- Maintain type safety with
Literaltype hint in dataclass
Implementation Details
Method 1: Parameter Default Detection
Implement _get_params_with_defaults() method to identify which parameters have default values:
# In src/docstring_format_checker/core.py
def _get_params_with_defaults(
self,
node: Union[ast.FunctionDef, ast.AsyncFunctionDef]
) -> set[str]:
"""
Get set of parameter names that have default val...