Skip to content

feat(linter): add PINJ041 rule to explain IProxy transformations in stub files#117

Open
proboscis wants to merge 1 commit intomainfrom
nameissoap/arc-383-add-pinj041-linter-rule-to-explain-iproxy-transformations-in
Open

feat(linter): add PINJ041 rule to explain IProxy transformations in stub files#117
proboscis wants to merge 1 commit intomainfrom
nameissoap/arc-383-add-pinj041-linter-rule-to-explain-iproxy-transformations-in

Conversation

@proboscis
Copy link
Owner

Summary

Adds a new educational linter rule PINJ041 that validates correct IProxy usage in .pyi stub files and provides detailed explanations about WHY these transformations occur.

Changes

  • Added PINJ041 rule implementation in Rust
  • Created comprehensive documentation explaining IProxy transformations
  • Added unit tests for all validation scenarios
  • Registered rule in linter

Purpose

Many developers don't understand why:

  • @instance functions that return T in .py files are typed as IProxy[T] in .pyi files
  • @injected functions that return T should still return T in .pyi files (not IProxy[T])

This rule helps educate users about pinjected's type transformation behavior while ensuring stub files are correct.

How It Works

The rule:

  1. Reads both .py and .pyi files
  2. Analyzes decorators in the .py file
  3. Validates type annotations in the .pyi file
  4. Provides educational error messages explaining the transformations

Example Error Messages

For @instance:

@instance function 'database' should be typed as 'database: IProxy[Database]' in the .pyi file.

Why? The @instance decorator transforms your function into a dependency provider. Instead of eagerly executing the function, pinjected wraps it as IProxy[Database] to enable lazy evaluation and dependency injection at runtime.

For @injected:

@injected function 'fetch_user' should NOT have IProxy in its return type in the .pyi file.

Why? While the @injected decorator makes the function itself an IProxy[Callable[[args], User]], the stub file shows the signature from the user's perspective. When they call the function with runtime arguments, they get back User, not IProxy[User].

Test Plan

[x] Unit tests pass (8 test cases covering all scenarios)
[x] Documentation created
[x] Rule registered and builds successfully

Also Found

Bug in PINJ014: Currently wraps @injected return types as IProxy[T] in stub files, which is incorrect according to documentation. Should be fixed separately.

Closes Linear issue ARC-383

🤖 Generated with Claude Code

… stub files

Adds a new educational linter rule that validates correct IProxy usage in .pyi stub files
and provides detailed explanations about WHY these transformations occur.

Key features:
- Validates @instance functions are typed as IProxy[T] variables in stub files
- Ensures @injected functions use @overload with original return types (not IProxy[T])
- Provides educational error messages explaining the pinjected type transformation behavior
- Helps users understand why stub files differ from source files

The rule reads both .py and .pyi files to compare decorators and type annotations,
ensuring stub files correctly represent the user-facing interface after pinjected's
dependency injection transformations.

Closes Linear issue ARC-383

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.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.

1 participant