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

control setting nodes as local outside of the constructor #2588

Merged

Conversation

temyurchenko
Copy link
Contributor

  1. The main reason is that a node might be assigned to its parent via an «alias»:

Sometimes a class accesses a member by a different name than
"name" of that member: in pypy3 list.__mul__.__name__ == "__rmul__".

As a result, in the example above we weren't able to find
"list.mul", because it was recorded only as "list.rmul".

  1. Sometimes we want to have a parent semantically, but we don't want to add it to the list of locals. For example, when inferring properties we are creating ad-hoc properties. We wouldn't want to add another symbol to the locals every time we do an inference. (actually, there's a very good question as to why we are doing those ad-hoc properties but that's out of scope)

it's a part of the campaign to get rid of non-module roots

No pylint regressions.

@temyurchenko
Copy link
Contributor Author

Unfortunately, this PR turned out to be a bit big. A big part of changes is renaming name to alias in InspectBuilder.object_build. I felt that name was quite confusing as to what relation it had to the object being built. In fact, it is just an alias for an object within its parent. The object itself might have a completely different, very own name.

Copy link

codecov bot commented Sep 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 93.20%. Comparing base (32cb29e) to head (87305dc).
Report is 2 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #2588   +/-   ##
=======================================
  Coverage   93.20%   93.20%           
=======================================
  Files          93       93           
  Lines       11065    11052   -13     
=======================================
- Hits        10313    10301   -12     
+ Misses        752      751    -1     
Flag Coverage Δ
linux 93.08% <100.00%> (+<0.01%) ⬆️
pypy 93.20% <100.00%> (+<0.01%) ⬆️
windows 93.18% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
astroid/nodes/scoped_nodes/scoped_nodes.py 93.34% <ø> (+0.07%) ⬆️
astroid/raw_building.py 94.58% <100.00%> (-0.31%) ⬇️
astroid/rebuilder.py 98.21% <100.00%> (+<0.01%) ⬆️

@temyurchenko
Copy link
Contributor Author

Supersedes #2564, quoting my comment from there for clarity:

I've digged and I found an answer for why we have to prefer name for classes. The classes are cached in builder._done. So, when we build a class once with a localname, all the other builds reuse that class with the same localname. Which is incorrect.

There are ways to deal with that. I feel like the clearest one is to separate attachment to the locals of a parent from the constructor. Since any object can be attached to the parent by a variety of different names that have no relation to the object itself, it would be clearer to not make it the object's responsibility.

So, I am creating a different PR meant to supersede this one. In that PR, I split out adding symbols to the locals of a parent from the constructor to the outside. So, closing this one in favour of #2588.

DanielNoord
DanielNoord previously approved these changes Sep 30, 2024
Copy link
Collaborator

@DanielNoord DanielNoord left a comment

Choose a reason for hiding this comment

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

Changes make sense to me!

I have asked Jacob for review as he has looked into this pattern before and might know of edge cases that I don't know about.
Awesome work on the investigation!

@jacobtylerwalls
Copy link
Member

Thanks for this! Does this close #1490? If so, can you add a changelog?

No pylint regressions.

Thank you for checking the pylint test suite. I think these are the kinds of PRs that would also benefit from a pylint primer run. I've toyed with adding a github action to astroid to run the pylint primer action. I need to just finish it up and get it in. Would you mind waiting for me to do that? I promise I won't hold this up for weeks.

@temyurchenko
Copy link
Contributor Author

Thank you for checking the pylint test suite. I think these are the kinds of PRs that would also benefit from a pylint primer

I've ran the primer as well.

I need to just finish it up and get it in. Would you mind waiting for me to do that? I promise I won't hold this up for weeks.

There are a few other PRs dependent on this one (#2562, and, eventually #2536), but if it doesn't take too long, I'm happy to wait.

@jacobtylerwalls
Copy link
Member

Oh that's great news that you ran the primer. No need to wait then.

@temyurchenko
Copy link
Contributor Author

Oh that's great news that you ran the primer. No need to wait then.

Let me give it just one more try, to be safe

@temyurchenko
Copy link
Contributor Author

Oh that's great news that you ran the primer. No need to wait then.

Let me give it just one more try, to be safe

Yep, all good

@temyurchenko
Copy link
Contributor Author

temyurchenko commented Sep 30, 2024

Thanks for this! Does this close #1490? If so, can you add a changelog?

The wording of #1490 is confusing. It says that the problem is that the parent is added to the locals of the child, but the problem solved by this PR is that the child is added to the locals of the parent. Looking at #1489, indeed it is the latter that is the problem.

I initially intended for #2536 (comment) to close #1490, but this one can probably also be considered to be closing #1490.

What should changelog look like? Can I just add the following to the ./ChangeLog file?

* Control setting local nodes outside of the supposed local's constructor.

  Closes pylint-dev/astroid/issues/1490

1. The main reason is that a node might be assigned to its parent via
   an «alias»:

Sometimes a class accesses a member by a different name than
   "__name__" of that member: in pypy3 `list.__mul__.__name__ ==
   "__rmul__"`.

As a result, in the example above we weren't able to find
   "list.__mul__", because it was recorded only as "list.__rmul__".

2. Sometimes we want to have a parent semantically, but we don't want
   to add it to the list of locals. For example, when inferring
   properties we are creating ad-hoc properties. We wouldn't want to
   add another symbol to the locals every time we do an
   inference. (actually, there's a very good question as to why we are
   doing those ad-hoc properties but that's out of scope)

it's a part of the campaign to get rid of non-module roots
@Pierre-Sassoulas
Copy link
Member

Yes, only this syntax is used for pylint issues, for issues from astroid it can be simplified to:

* Control setting local nodes outside of the supposed local's constructor.

  Closes #1490

@temyurchenko
Copy link
Contributor Author

Yes, only this syntax is used for pylint issues, for issues from astroid it can be simplified to:

* Control setting local nodes outside of the supposed local's constructor.

  Closes #1490

Thanks, I'll note this for the future.

Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

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

I'm drowning in astroid myself, so take this approve for what it's worth but I think this change is pretty good and going into the right direction design wise.

Copy link
Member

@jacobtylerwalls jacobtylerwalls left a comment

Choose a reason for hiding this comment

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

Wonderful, I can remove the workarounds that stemmed from #1490 in another PR, and many thanks for noticing that the wording was wrong 👍 .

@jacobtylerwalls jacobtylerwalls merged commit 36094ed into pylint-dev:main Sep 30, 2024
20 checks passed
@temyurchenko temyurchenko deleted the move-set_local-out-of-constructor branch October 1, 2024 05:05
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