Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[red-knot] Add symbols for for loop variables #13075

Merged
merged 4 commits into from
Aug 23, 2024

Conversation

AlexWaygood
Copy link
Member

Summary

This PR adds symbols introduced by for loops to red-knot:

  • x in for x in range(10): pass
  • x and y in for x, y in d.items(): pass
  • a, b, c and d in for [((a,), b), (c, d)] in foo: pass

This is the first one of these PRs that I've done, so I hope I haven't missed anything!

Test Plan

Several tests added, and the assertion in the benchmarks has been updated.

@AlexWaygood AlexWaygood added the red-knot Multi-file analysis & type inference label Aug 23, 2024
@AlexWaygood AlexWaygood force-pushed the alex/redknot-for-symbols branch 2 times, most recently from 060e167 to 2a7f191 Compare August 23, 2024 11:49
Copy link

codspeed-hq bot commented Aug 23, 2024

CodSpeed Performance Report

Merging #13075 will improve performances by 9.06%

Comparing alex/redknot-for-symbols (3fc3db2) with main (99df859)

Summary

⚡ 1 improvements
✅ 31 untouched benchmarks

Benchmarks breakdown

Benchmark main alex/redknot-for-symbols Change
linter/all-with-preview-rules[numpy/globals.py] 904.1 µs 829 µs +9.06%

Copy link
Contributor

github-actions bot commented Aug 23, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@AlexWaygood AlexWaygood marked this pull request as draft August 23, 2024 16:09
@AlexWaygood AlexWaygood force-pushed the alex/redknot-for-symbols branch 2 times, most recently from c81aa5c to be08b16 Compare August 23, 2024 18:14
@AlexWaygood AlexWaygood force-pushed the alex/redknot-for-symbols branch from be08b16 to 3fc3db2 Compare August 23, 2024 18:18
Comment on lines +897 to +908
// TODO(Alex): only a valid iterable if the *type* of `iterable_ty` has an `__iter__`
// member (dunders are never looked up on an instance)
let _dunder_iter_ty = iterable_ty.member(self.db, &ast::name::Name::from("__iter__"));

// TODO(Alex):
// - infer the return type of the `__iter__` method, which gives us the iterator
// - lookup the `__next__` method on the iterator
// - infer the return type of the iterator's `__next__` method,
// which gives us the type of the variable being bound here
// (...or the type of the object being unpacked into multiple definitions, if it's something like
// `for k, v in d.items(): ...`)
let loop_var_value_ty = Type::Unknown;
Copy link
Member Author

@AlexWaygood AlexWaygood Aug 23, 2024

Choose a reason for hiding this comment

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

I think this is probably not really the right place for this TODO? Since the inferring of the iterator type (and the unpacking of whatever is returned from the iterator's __next__ method) really needs to be done at a higher level? but I'm also not really sure where else to put this TODO?

Copy link
Contributor

Choose a reason for hiding this comment

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

In the current architecture, this is the right place for the TODO; we will have to repeat this logic for each definition, in the case of unpacking. We don't currently have another layer available at which to cache it. Caching also has an overhead and sometimes it's better to just repeat some work. But we can also re-evaluate this when we implement unpacking.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not 100% sure we're on the same page here (but this may also just be me still getting used to this architecture) — anyway, I don't think it's massively important where this TODO lives, so I'll leave this for now!

@AlexWaygood AlexWaygood marked this pull request as ready for review August 23, 2024 18:25
@AlexWaygood
Copy link
Member Author

Thanks @dhruvmanila and @carljm! Pushed some changes. Lmk if it's still not quite right.

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

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

Looks great, thank you!!

Comment on lines +897 to +908
// TODO(Alex): only a valid iterable if the *type* of `iterable_ty` has an `__iter__`
// member (dunders are never looked up on an instance)
let _dunder_iter_ty = iterable_ty.member(self.db, &ast::name::Name::from("__iter__"));

// TODO(Alex):
// - infer the return type of the `__iter__` method, which gives us the iterator
// - lookup the `__next__` method on the iterator
// - infer the return type of the iterator's `__next__` method,
// which gives us the type of the variable being bound here
// (...or the type of the object being unpacked into multiple definitions, if it's something like
// `for k, v in d.items(): ...`)
let loop_var_value_ty = Type::Unknown;
Copy link
Contributor

Choose a reason for hiding this comment

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

In the current architecture, this is the right place for the TODO; we will have to repeat this logic for each definition, in the case of unpacking. We don't currently have another layer available at which to cache it. Caching also has an overhead and sometimes it's better to just repeat some work. But we can also re-evaluate this when we implement unpacking.

@AlexWaygood AlexWaygood merged commit d19fd1b into main Aug 23, 2024
20 checks passed
@AlexWaygood AlexWaygood deleted the alex/redknot-for-symbols branch August 23, 2024 22:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
red-knot Multi-file analysis & type inference
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants