Skip to content

bpo: improve type hints and Dependabot configuration for clarity#36

Open
Aasyaco wants to merge 8 commits intomainfrom
fix
Open

bpo: improve type hints and Dependabot configuration for clarity#36
Aasyaco wants to merge 8 commits intomainfrom
fix

Conversation

@Aasyaco
Copy link
Collaborator

@Aasyaco Aasyaco commented Mar 5, 2026

Summary

This pull request makes several non-functional improvements to Python's source and tooling.

Changes included

  1. Add precise type hint for orig_threading_excepthook

    • File: Lib/test/libregrtest/utils.py
    • Updated type annotation to:
      orig_threading_excepthook: Callable[[threading.ExceptHookArgs], None] | None
    • Improves static type checking and compatibility with tools like mypy.
  2. Expose libclinic.cpp and update __all__

    • File: Tools/clinic/libclinic/__init__.py
    • Explicitly import cpp and include "cpp" in __all__.
    • Ensures that type checkers recognize libclinic.cpp as part of the public API.
  3. Enable explicit auto-rebasing in Dependabot configuration

    • File: .github/dependabot.yml
    • Adds rebase-strategy: "auto" to make Dependabot PRs rebase automatically.
    • Improves dependency management workflow.

Impact

  • ✅ No runtime changes.
  • ✅ Purely type, static analysis, and tooling improvements.
  • ✅ Improves developer experience for contributors using type checkers.

Testing

  • Existing tests pass; no runtime behavior changed.
  • Type hints validated via mypy.

Notes

  • Fully backward-compatible.
  • Reduces false positives and improves clarity in type-checked code and CI automation.

Commits

  • 65b0f43 — Enable explicit auto-rebasing in Dependabot config
  • 42e6543 — Add type hint for orig_threading_excepthook
  • 1d53e04 — Expose libclinic.cpp and update __all__ for mypy

Summary by Sourcery

Clarify typing around test threading exception hooks, expose an internal Clinic submodule as part of its public API, and adjust Dependabot behavior for automated rebasing.

New Features:

  • Expose the libclinic.cpp submodule via the libclinic package all for type checkers and consumers.

Enhancements:

  • Tighten the type annotation for orig_threading_excepthook in libregrtest utilities to use threading.ExceptHookArgs.

CI:

  • Configure Dependabot to use automatic rebasing for GitHub Actions and Tools pip updates.

Summary by CodeRabbit

  • Chores
    • Improved automated dependency management workflows with an enhanced rebasing strategy for more reliable CI updates
  • Tests
    • Strengthened test-suite checks to avoid false positives and provide clearer assertion messages and safer handling of optional test inputs
    • Tightened a test utility’s exception-hook typing for clearer expectations
  • Refactor
    • Exposed an additional tooling submodule in the public API to improve tooling organization
  • Bug Fixes
    • Hardened temp‑dir handling: sanitizes paths, falls back to secure temp creation on failure, and ignores errors during cleanup

@Aasyaco Aasyaco requested a review from a team as a code owner March 5, 2026 07:20
@sourcery-ai
Copy link

sourcery-ai bot commented Mar 5, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

This PR makes non-functional improvements by tightening a threading excepthook type annotation, exposing the libclinic.cpp submodule as part of the public API for tooling, and updating Dependabot configuration to auto-rebase its PRs.

Class diagram for updated type hints and libclinic public API

classDiagram
    class libregrtest_utils {
        +orig_threading_excepthook: Callable[threading_ExceptHookArgs, None] | None
    }

    class threading_ExceptHookArgs {
        <<dataclass-like>>
    }

    class libclinic {
        +__all__: ["Block", "Command", "ClinicError", "format_escape", "CPPFile", "cpp", "FormatCounterFormatter", "NULL"]
    }

    class cpp {
    }

    libregrtest_utils ..> threading_ExceptHookArgs : uses
    libclinic o-- cpp : exposes_submodule
Loading

File-Level Changes

Change Details Files
Tighten the type annotation for the original threading excepthook used in libregrtest.
  • Change orig_threading_excepthook from a variadic Callable[..., None] to Callable[[threading.ExceptHookArgs], None]
None to match the actual threading excepthook signature
  • Retain the existing initialization pattern with a module-level variable, preserving runtime behavior
  • Expose the libclinic.cpp submodule explicitly through the libclinic package’s public API.
    • Import cpp within the libclinic package to make the submodule directly accessible to importers and type checkers
    • Add "cpp" to the all list so static analysis tools treat libclinic.cpp as part of the documented public interface
    Tools/clinic/libclinic/__init__.py
    Configure Dependabot to use explicit auto-rebasing for its pull requests.
    • Add rebase-strategy: "auto" to the existing GitHub Actions Dependabot configuration blocks for the root and Tools/ pip ecosystems
    • Keep all existing schedule, labels, and cooldown settings unchanged while layering in the new rebase behavior
    .github/dependabot.yml

    Tips and commands

    Interacting with Sourcery

    • Trigger a new review: Comment @sourcery-ai review on the pull request.
    • Continue discussions: Reply directly to Sourcery's review comments.
    • Generate a GitHub issue from a review comment: Ask Sourcery to create an
      issue from a review comment by replying to it. You can also reply to a
      review comment with @sourcery-ai issue to create an issue from it.
    • Generate a pull request title: Write @sourcery-ai anywhere in the pull
      request title to generate a title at any time. You can also comment
      @sourcery-ai title on the pull request to (re-)generate the title at any time.
    • Generate a pull request summary: Write @sourcery-ai summary anywhere in
      the pull request body to generate a PR summary at any time exactly where you
      want it. You can also comment @sourcery-ai summary on the pull request to
      (re-)generate the summary at any time.
    • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
      request to (re-)generate the reviewer's guide at any time.
    • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
      pull request to resolve all Sourcery comments. Useful if you've already
      addressed all the comments and don't want to see them anymore.
    • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
      request to dismiss all existing Sourcery reviews. Especially useful if you
      want to start fresh with a new review - don't forget to comment
      @sourcery-ai review to trigger a new review!

    Customizing Your Experience

    Access your dashboard to:

    • Enable or disable review features such as the Sourcery-generated pull request
      summary, the reviewer's guide, and others.
    • Change the review language.
    • Add, remove or edit custom review instructions.
    • Adjust other review settings.

    Getting Help

    @coderabbitai
    Copy link

    coderabbitai bot commented Mar 5, 2026

    Important

    Review skipped

    This PR was authored by the user configured for CodeRabbit reviews. CodeRabbit does not review PRs authored by this user. It's recommended to use a dedicated user account to post CodeRabbit review feedback.

    ⚙️ Run configuration

    Configuration used: defaults

    Review profile: CHILL

    Plan: Pro

    Run ID: c29bf36d-9ada-4e1c-8bde-31dac469d8da

    You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

    Use the checkbox below for a quick retry:

    • 🔍 Trigger review
    📝 Walkthrough

    Walkthrough

    Added Dependabot rebase automation; narrowed a threading excepthook type annotation; exported a new cpp submodule from Tools/clinic; hardened a test and made temp_dir path handling and cleanup more defensive and tolerant.

    Changes

    Cohort / File(s) Summary
    Dependency Management
    \.github/dependabot.yml
    Added rebase-strategy: "auto" to Dependabot update blocks for Actions and Pip.
    Type Annotation Refinement
    Lib/test/libregrtest/utils.py
    Added import threading; changed orig_threading_excepthook type to Callable[[threading.ExceptHookArgs], None] | None.
    Module Export
    Tools/clinic/libclinic/__init__.py
    Imported cpp and added "cpp" to __all__ to expose the submodule.
    Test robustness
    Lib/test/test_tools/test_compute_changes.py
    Initialized f = None, added file-existence checks, and guarded assertions to skip missing candidates with descriptive messages.
    Temp dir robustness
    Lib/test/support/os_helper.py
    Sanitized provided paths, added fallback to tempfile.mkdtemp on mkdir/path issues, and made cleanup resilient by swallowing rmtree errors.

    Estimated code review effort

    🎯 3 (Moderate) | ⏱️ ~20 minutes

    Possibly related PRs

    Suggested labels

    dependencies, type-bug

    Suggested reviewers

    • plfj
    • Ansyso

    Poem

    🐰 I hopped through lines both new and old,

    Rebasing set to auto, tidy and bold,
    A cpp hello, a hook more tight,
    Tests that skip when files take flight,
    I nibble crumbs and leave the code bright.

    🚥 Pre-merge checks | ✅ 2 | ❌ 1

    ❌ Failed checks (1 warning)

    Check name Status Explanation Resolution
    Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
    ✅ Passed checks (2 passed)
    Check name Status Explanation
    Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
    Title check ✅ Passed The title 'bpo: improve type hints and Dependabot configuration for clarity' accurately captures the main changes: type hint improvements and Dependabot configuration updates across multiple files.

    ✏️ Tip: You can configure your own custom pre-merge checks in the settings.


    Comment @coderabbitai help to get the list of available commands and usage tips.

    Copy link

    @sourcery-ai sourcery-ai bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Hey - I've left some high level feedback:

    • If libclinic.cpp is meant to be part of the public API, make sure it is actually imported in Tools/clinic/libclinic/__init__.py (not just listed in __all__), otherwise from libclinic import cpp will fail at runtime.
    • Now that orig_threading_excepthook is annotated with threading.ExceptHookArgs, consider updating the regrtest_threading_excepthook signature to accept threading.ExceptHookArgs as well to keep the typing consistent end-to-end.
    Prompt for AI Agents
    Please address the comments from this code review:
    
    ## Overall Comments
    - If `libclinic.cpp` is meant to be part of the public API, make sure it is actually imported in `Tools/clinic/libclinic/__init__.py` (not just listed in `__all__`), otherwise `from libclinic import cpp` will fail at runtime.
    - Now that `orig_threading_excepthook` is annotated with `threading.ExceptHookArgs`, consider updating the `regrtest_threading_excepthook` signature to accept `threading.ExceptHookArgs` as well to keep the typing consistent end-to-end.

    Sourcery is free for open source - if you like our reviews please consider sharing them ✨
    Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

    plfj added 3 commits March 5, 2026 13:22
    Dependabot uses "auto" as the default rebasing behavior, but declaring it explicitly:
    - Improves configuration readability and maintainability
    - Protects against potential future default changes
    - Aligns with best practices for declarative dependency management
    
    No functional change in current behavior, but increases long-term robustness.
    Add explicit import of the `cpp` submodule in Tools/clinic/libclinic/__init__.py
    so that both runtime and static type checking via mypy recognize `libclinic.cpp`.
    
    Also, include "cpp" in __all__ to mark it as part of the public API.
    
    This fixes the mypy error in clanguage.py:
        Module has no attribute "cpp" [attr-defined]
    
    No functional behavior is changed.
    Copy link
    Collaborator

    @Ansyso Ansyso left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Great

    In test.test_tools.test_compute_changes.TestProcessChangedFiles,
    the variable 'f' could be referenced before assignment if a path in
    LIBRARY_FUZZER_PATHS was neither a file nor a directory. This caused
    UnboundLocalError in CI runs.
    
    The test is now fixed by:
    
    - Initializing 'f' to None before conditional assignment.
    - Skipping paths that are neither valid files nor directories.
    - Verifying that candidate files exist before passing them to process_changed_files().
    - Adding assertion messages for better CI debugging.
    - Preserving the working directory context with os_helper.change_cwd(basepath).
    
    This ensures the test safely iterates over all fuzzable library files
    and properly verifies CI fuzzing logic without triggering UnboundLocalError.
    Copy link

    @coderabbitai coderabbitai bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 1

    🤖 Prompt for all review comments with AI agents
    Verify each finding against the current code and only fix it if needed.
    
    Inline comments:
    In `@Lib/test/test_tools/test_compute_changes.py`:
    - Around line 56-57: The assignment "f = candidate" is not indented under the
    if-statement checking "candidate.exists()", causing a SyntaxError; fix it by
    indenting "f = candidate" so it is inside the "if candidate.exists():" block
    (and ensure any subsequent uses of "f" handle the case where the if-body doesn't
    run), locating the lines with the "candidate.exists()" check and the "f =
    candidate" assignment in test_compute_changes.py to apply the indentation
    change.
    

    ℹ️ Review info
    ⚙️ Run configuration

    Configuration used: defaults

    Review profile: CHILL

    Plan: Pro

    Run ID: e428cec0-e4a1-41f2-b799-17c0ba5105f1

    📥 Commits

    Reviewing files that changed from the base of the PR and between 004bc37 and 9a922c2.

    📒 Files selected for processing (1)
    • Lib/test/test_tools/test_compute_changes.py

    Copy link
    Collaborator

    @Ansyso Ansyso left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Try

    @Aasyaco Aasyaco requested a review from Ansyso March 5, 2026 08:32
    Copy link
    Collaborator

    @plfj plfj left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Try

    Copy link
    Collaborator

    @plfj plfj left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Try

    Copy link
    Collaborator

    @plfj plfj left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Try

    The assertion lines in test.test_tools.test_compute_changes.
    TestProcessChangedFiles.test_ci_fuzz_stdlib contained trailing
    whitespace and inconsistent formatting, which triggered lint errors.
    
    This commit:
    
    - Rewrites the assertion statements using parentheses.
    - Aligns arguments and adds explicit assertion messages.
    - Ensures the code is lint-clean while preserving the working
      directory context and test logic.
    
    No functional changes are introduced; this is purely a style/lint fix.
    @Aasyaco Aasyaco requested a review from plfj March 5, 2026 10:32
    …emp()
    
    The test helper temp_dir() may receive a directory name containing
    invalid or corrupted characters during parallel test execution.
    
    On Windows CI (e.g. Azure Pipelines), this can lead to failures such as:
    
        FileNotFoundError: [WinError 3] The system cannot find the path specified
    
    when os.mkdir() attempts to create directories like
    "test_python_6744æ".  These paths can appear when worker directory
    names become mis-decoded during high parallelism test runs.
    
    Sanitize the provided path by replacing non-ASCII and unsafe filesystem
    characters with "_" before attempting to create the directory.  If
    directory creation still fails, fall back to tempfile.mkdtemp() to
    ensure the test run can proceed.
    
    This change preserves the existing behavior of temp_dir(), including
    its logging and fork-safety semantics, while making it more robust in
    CI environments.
    Copy link

    @coderabbitai coderabbitai bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Actionable comments posted: 4

    🤖 Prompt for all review comments with AI agents
    Verify each finding against the current code and only fix it if needed.
    
    Inline comments:
    In `@Lib/test/support/os_helper.py`:
    - Around line 547-565: Preserve the original path before calling
    tempfile.mkdtemp and narrow the broad except to specific exceptions so the
    warning logs the failing original path and not the newly-created temp path:
    store original_path = path immediately after the OSError handler begins, replace
    the bare "except Exception:" with a more specific exception (e.g., OSError or
    tempfile-specific exceptions) around tempfile.mkdtemp, and update the logging
    call to reference original_path and include exc/exception info; ensure
    dir_created is only set True after mkdtemp succeeds and that exc is what's
    logged.
    - Around line 576-579: The cleanup block around rmtree(path) currently swallows
    all exceptions; change it to catch Exception as e and log a warning/debug
    message including the path and exception details (e.g., using the module logger
    or Python's logging) instead of silently passing, so failures like
    permission/disk issues are visible during CI; keep the cleanup attempt but
    record the error from rmtree(path) for diagnostics.
    - Around line 555-571: The except Exception block that logs a warning when
    creating the temporary directory fails should not allow the function to proceed
    to yield an invalid path; after logging the warning (in the branch where quiet
    is True) re-raise the caught exception instead of falling through so callers
    never receive a non-existent path. Locate the except Exception handling around
    os.mkdir(path) / tempfile.mkdtemp() (the block that logs via
    logging.getLogger(__name__).warning and references path, exc, dir_created) and
    add a raise (or re-raise the captured exception) immediately after the warning
    so the generator does not reach the yield of path when directory creation
    failed.
    - Around line 528-531: The sanitization currently runs two regexes on the
    variable path and strips ':' causing Windows drive letters to become invalid;
    remove the redundant non-ASCII replacement (the first re.sub on path) and update
    the second regex to allow colons so drive letters are preserved (e.g. change
    r'[^A-Za-z0-9._\\/-]' to r'[^A-Za-z0-9._\\/:-]'), leaving the rest of the
    allowed characters intact; ensure these edits are applied where path is
    sanitized so absolute Windows paths like "C:\temp\test" keep their drive letter.
    

    ℹ️ Review info
    ⚙️ Run configuration

    Configuration used: defaults

    Review profile: CHILL

    Plan: Pro

    Run ID: 350dbd16-2e0a-45e5-bd24-b63011b4b444

    📥 Commits

    Reviewing files that changed from the base of the PR and between d2ec3f8 and d8002fa.

    📒 Files selected for processing (1)
    • Lib/test/support/os_helper.py

    Refactor path sanitization and error handling in os_helper.py.
    # Prevent empty or broken names
    if not path.strip():
    path = None
    except BaseException:
    path = tempfile.mkdtemp(prefix="test_python_")
    dir_created = True
    path = os.path.realpath(path)
    except BaseException as exc:
    Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Labels

    None yet

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    3 participants