Skip to content

Comments

[flake8-type-checking] Add test cases for TC004#3

Open
gpilikin wants to merge 10 commits intofix/unused_importsfrom
fix/tc004
Open

[flake8-type-checking] Add test cases for TC004#3
gpilikin wants to merge 10 commits intofix/unused_importsfrom
fix/tc004

Conversation

@gpilikin
Copy link
Owner

Add test cases for astral-sh#13965 (comment)

Copy link

@Daverball Daverball left a comment

Choose a reason for hiding this comment

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

LGTM

Choose a reason for hiding this comment

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

Are you getting a false negative with your approach here as well or did you just copy over the snapshots from my PR?

I was kind of hoping your approach wouldn't lead to source order dependent false negatives.

Copy link
Owner Author

Choose a reason for hiding this comment

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

I haven't dug deep into this yet - just added some test cases and ran cargo insta review.

Choose a reason for hiding this comment

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

You'd need to run cargo insta test once to get updated snapshots. cargo insta review doesn't really do anything on its own without the temporary diff snapshot files.

But you can also just merge this and let the CI tell you if some of the snapshots need to be updated. (Or enable GitHub actions on your fork and trigger the CI using a force push)

Copy link
Owner Author

Choose a reason for hiding this comment

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

Thanks, I'll try to do it later.

Copy link
Owner Author

@gpilikin gpilikin May 22, 2025

Choose a reason for hiding this comment

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

Hello. Ah, I see. I was doing it by creating snapshots via cargo test and then running cargo insta review. I didn’t know you could just run cargo insta test to create snapshots.

Choose a reason for hiding this comment

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

That's a shame, but it's still better than without the fix, so I'll take what I can get. Maybe the source order dependency will be easier to fix as a follow-up with the additional contextual information your fix provides.

Choose a reason for hiding this comment

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

Also cargo test does work, yes. But cargo insta test is more convenient, especially if there are multiple snapshots that need to be updated.

Copy link
Owner Author

@gpilikin gpilikin May 22, 2025

Choose a reason for hiding this comment

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

Lol)

I actually ran into this when fixing a rule related to unused imports. The solution was to search for all bindings by explicitly using the module name.
From what I understand, the imports are shadowing each other, making them harder to access.

Check the last two commits.
If I understand correctly, is this like in your PR?

Choose a reason for hiding this comment

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

I think I used a similar approach in one of my attempts to fix this. I'm worried there are still other corner-cases that aren't handled correctly though, like the following example:

import a.b.c

TYPE_CHECKING = False
if TYPE_CHECKING:
    import a.b

class Foo(a.b.c.Bar):
    def baz() -> a.b.x: ...

Or the reverse or if you add more imports with different levels. Making each reference prioritize binding to the correct import for the purposes of this check is challenging.

It looks like a good start towards further improving results though.

Choose a reason for hiding this comment

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

Actually, if what your fix does, is ensure that references point to the correct import, then you can probably make a much smaller patch and just iterate over all the bindings in the outermost loop, i.e. replace for binding_id in scope.binding_ids() with for _, binding_id in scope.all_bindings(), that should be faster than going from each binding back to its shadowed bindings.

@gpilikin gpilikin force-pushed the fix/unused_imports branch from 2f238e1 to 8e09a96 Compare May 22, 2025 10:19
Comment on lines +119 to +129
let binding_name = top_binding
.name(checker.source())
.split('.')
.next()
.unwrap_or("");

// NOTE: It’s necessary to go through all bindings, including shadowed ones,
// using the module name.
for binding in scope
.get_all(&binding_name.nfkc().collect::<String>())
.map(|binding_id| checker.semantic().binding(binding_id))

Choose a reason for hiding this comment

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

It might be more efficient to use the existing method on the semantic model to iterate through the shadowed bindings (unless your change makes those bindings not always shadow each other):

https://github.com/astral-sh/ruff/blob/91b7a570c2bd1c9e1cab894ded866e885f28946a/crates/ruff_python_semantic/src/model.rs#L2038-L2075

Choose a reason for hiding this comment

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

Or rather as pointed out above, you might be able to revert everything and only have to replace scope.binding_ids() with scope.all_bindings().

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.

2 participants