Skip to content

Restrict PYI034 for in-place operations to enclosing class#24511

Open
charliermarsh wants to merge 2 commits intomainfrom
charlie/pyi034
Open

Restrict PYI034 for in-place operations to enclosing class#24511
charliermarsh wants to merge 2 commits intomainfrom
charlie/pyi034

Conversation

@charliermarsh
Copy link
Copy Markdown
Member

@charliermarsh charliermarsh commented Apr 9, 2026

Summary

In .py and .pyi files, we now only flag cases in which the return type is the enclosing class, like:

class A:
    def __iadd__(self) -> A:
        return self

As opposed to:

class A:
    def __iadd__(self) -> int:
        return self

Closes #24462.

@charliermarsh charliermarsh added the rule Implementing or modifying a lint rule label Apr 9, 2026
@charliermarsh charliermarsh marked this pull request as ready for review April 9, 2026 02:13
@astral-sh-bot astral-sh-bot Bot requested a review from ntBre April 9, 2026 02:13
@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot Bot commented Apr 9, 2026

ruff-ecosystem results

Linter (stable)

ℹ️ ecosystem check detected linter changes. (+0 -2 violations, +0 -0 fixes in 1 projects; 55 projects unchanged)

python/typeshed (+0 -2 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --no-preview --select E,F,FA,I,PYI,RUF,UP,W

- stdlib/typing_extensions.pyi:265:9: PYI034 `__ior__` methods in classes like `_TypedDict` usually return `self` at runtime
- stubs/boltons/boltons/dictutils.pyi:96:9: PYI034 `__ior__` methods in classes like `FrozenDict` usually return `self` at runtime

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
PYI034 2 0 2 0 0

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+0 -2 violations, +0 -0 fixes in 1 projects; 55 projects unchanged)

python/typeshed (+0 -2 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview --select E,F,FA,I,PYI,RUF,UP,W

- stdlib/typing_extensions.pyi:265:9: PYI034 `__ior__` methods in classes like `_TypedDict` usually return `self` at runtime
- stubs/boltons/boltons/dictutils.pyi:96:9: PYI034 `__ior__` methods in classes like `FrozenDict` usually return `self` at runtime

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
PYI034 2 0 2 0 0

/// Return `true` if the return type for an in-place operator should be replaced with `Self`.
fn is_bad_inplace_return_type(checker: &Checker, returns: &ast::Expr, class_name: &str) -> bool {
if checker.source_type.is_stub() {
!is_self(returns, checker)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do you think the special case is worth it? To me, defining __iadd__(self, other: A) -> int seems a pretty high signal that using Self here is not what the user wants.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Hmm, not sure. I was following @AlexWaygood's guidance in #24462 (comment) where he said it did make sense to enforce this in stub files, though I also agree that (without that guidance) I would've made this change for both .py and .pyi files.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The least confusing thing for Ruff might be just to make the rule consistent between .py and .pyi files. If the rule only supported .pyi files, I think there probably would not be a strong motivation for any change. But if Ruff makes this change for both .py files and .pyi files, maybe it makes sense for us to make the same change upstream in flake8-pyi, so that Ruff and flake8-pyi continue to be consistent about how they enforce the rule.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

(I updated the PR to match that logic.)

@MichaReiser MichaReiser assigned MichaReiser and unassigned ntBre Apr 9, 2026
@charliermarsh charliermarsh changed the title Restrict PYI034 for in-place operations in .py files to enclosing class Restrict PYI034 for in-place operations to enclosing class Apr 10, 2026
@charliermarsh charliermarsh marked this pull request as draft April 10, 2026 02:34
@charliermarsh charliermarsh marked this pull request as ready for review April 10, 2026 02:36
@astral-sh-bot astral-sh-bot Bot requested a review from MichaReiser April 10, 2026 02:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rule Implementing or modifying a lint rule

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PYI034: false positive for in-place operations with return type annotation

4 participants