Skip to content

Conversation

@marcorudolphflex
Copy link
Contributor

@marcorudolphflex marcorudolphflex commented Dec 16, 2025

  • adds script for auto-detecting moving from type-checking imports with fix and check mode
  • use fix mode for pre-commit hook
  • use check mode for CI

looks good (see move-type-imports):
https://github.com/flexcompute/tidy3d/actions/runs/20262172636/job/58176641591

Greptile Overview

Greptile Summary

Added automated tooling to enforce TYPE_CHECKING guards for type-only imports across the codebase. The implementation includes a new script that analyzes Python files to identify imports used solely in type annotations and automatically moves them behind if TYPE_CHECKING: blocks. This optimization reduces runtime import overhead while maintaining type checking correctness.

Key changes:

  • Created scripts/move_type_imports.py with fix mode (auto-repairs) and check mode (validation only)
  • Integrated as pre-commit hook (fix mode, changed files only) for automatic local enforcement
  • Added CI job (check mode, all files) to validate PRs before merge
  • Correctly handles edge cases: pydantic field annotations, re-exports, Any from typing, and allows skip comments
  • Applied the script to tidy3d/web/tests/conftest.py as demonstration, moving Generator import behind TYPE_CHECKING

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk - it adds development tooling without modifying production code
  • The changes are well-contained to development infrastructure (pre-commit hooks, CI, and a utility script). The script implementation is thorough with proper edge case handling for pydantic fields, re-exports, and runtime typing needs. The dual-mode approach (fix locally, check in CI) is a sound pattern. The only production code change is a demonstration in a test fixture that correctly moves a type-only import.
  • No files require special attention

Important Files Changed

File Analysis

Filename Score Overview
scripts/move_type_imports.py 4/5 New script added to automatically detect and move type-only imports behind TYPE_CHECKING guards with both fix and check modes
.github/workflows/tidy3d-python-client-tests.yml 5/5 Added CI job move-type-imports to verify type-only imports are properly guarded, integrated into workflow status checks
.pre-commit-config.yaml 5/5 Added pre-commit hook to auto-fix type-only imports during commit, runs in fix mode on changed files only
tidy3d/web/tests/conftest.py 5/5 Moved Generator import behind TYPE_CHECKING guard as it's only used in type annotations

Sequence Diagram

sequenceDiagram
    participant Dev as Developer
    participant PreCommit as Pre-commit Hook
    participant Script as move_type_imports.py
    participant CI as GitHub Actions
    participant Check as Check Mode
    
    Note over Dev,Check: Local Development Flow
    Dev->>Dev: Modify Python files
    Dev->>PreCommit: git commit
    PreCommit->>Script: --mode fix --only-changed
    Script->>Script: Analyze changed files
    Script->>Script: Move type-only imports to TYPE_CHECKING
    Script->>Dev: Auto-fix files
    Dev->>Dev: Commit succeeds with fixed imports
    
    Note over Dev,Check: CI Validation Flow
    Dev->>CI: Push to PR
    CI->>CI: determine-test-scope
    CI->>Check: Run move-type-imports job
    Check->>Script: --mode check_on_change
    Script->>Script: Analyze all tidy3d files
    Script->>Script: Check for unguarded type imports
    alt All imports properly guarded
        Script->>Check: Exit 0 (success)
        Check->>CI: Job passes
    else Type imports not guarded
        Script->>Check: Exit 1 with error list
        Check->>CI: Job fails
        CI->>Dev: PR check fails
    end
Loading

Base automatically changed from FXC-4545-move-type-hints-imports-behind-type-checking to yaugenst-flex/pydantic-v2 December 16, 2025 08:14
@marcorudolphflex marcorudolphflex force-pushed the FXC-4559-add-type-checking-import-moving-and-checking-to-pre-commit-and-ci branch 3 times, most recently from 96baf60 to 0157641 Compare December 16, 2025 08:59
@marcorudolphflex
Copy link
Contributor Author

@greptile

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

5 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@marcorudolphflex marcorudolphflex force-pushed the FXC-4559-add-type-checking-import-moving-and-checking-to-pre-commit-and-ci branch from 0157641 to d80cef2 Compare December 16, 2025 09:48
@marcorudolphflex marcorudolphflex marked this pull request as ready for review December 16, 2025 09:48
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

5 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

hooks:
- id: move-type-imports
name: move type-only imports under TYPE_CHECKING
entry: poetry run python scripts/move_type_imports.py --mode fix --only-changed
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a way we can do this without using poetry? Just because not everyone has it installed?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thinking about it, should we just avoid it in the precommit but keep it in CI?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Was not expecting that...
Either we might skip it or do this one?

  - repo: local
    hooks:
      - id: move-type-imports
        name: move type-only imports under TYPE_CHECKING
        entry: python scripts/move_type_imports.py --mode fix --only-changed
        language: python
        additional_dependencies:
          - "libcst==1.4.0"
        pass_filenames: false
        stages: [ pre-commit ]

Copy link
Collaborator

@daquinteroflex daquinteroflex Dec 16, 2025

Choose a reason for hiding this comment

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

Do you think this will work for people who don't even have python installed in the system? Just checking how standalone it is? Is it fully self contained?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It only requires python with the libcst package.
So it's not perfectly standalone, but I would not assume that these users use the pre-commit hook? I mean there is no force to do it...

Comment on lines +6 to +9
The script scans module-level imports and moves those referenced only in
annotations or existing ``if TYPE_CHECKING`` blocks into a consolidated
``if TYPE_CHECKING:`` section. Imports used in class-level annotations are
left in place to avoid breaking pydantic field evaluation.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I feel this is part of a wider conversation about how we do dependency managements and typing. For now sounds good to use it but in the long run we can evaluate how we do this between the planned packages

@mahlau-flex mahlau-flex force-pushed the yaugenst-flex/pydantic-v2 branch 2 times, most recently from 6cc521f to 95adf41 Compare December 18, 2025 10:10
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.

4 participants