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

Fix bug in assignments #68

Conversation

tristanlatr
Copy link
Contributor

Fixes #66

'x -> ()'])

def test_call_assignment(self):
code = "NameError().name = 't'"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here the ast.Call instance will never be analyzed because it's not part of the supported nodes for assignments.

Choose a reason for hiding this comment

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

Yeah, it's not bound to any identifier... We could create temporary identifier for unbound expression that get assigned, but let's keep that for another patch.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But it won't be visited at all, so the ast.Call instance uses won't be part of the chains at all, even if we could argue that it's still a user of NameError, the same manner NameError won't be added to the uses of the builtins NameError symbol. This is why I think we should unconditionally visit this part.

Comment on lines 1190 to 1191
elif isinstance(elt, (ast.Subscript, ast.Attribute)):
self.visit(elt)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could remove these isinstance checks and simply call visit() for all other node types?

Choose a reason for hiding this comment

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

I like the conservative checks we are currently doing. That way if another case pop ups we don't have a default (and maybe unexpected) behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See my other comment about the node being completely ignored if we don’t include a catch all case

@tristanlatr
Copy link
Contributor Author

@paugier , maybe you have a moment to look at the pending PRs ?

Thanks a lot,

Comment on lines 1190 to 1191
elif isinstance(elt, (ast.Subscript, ast.Attribute)):
self.visit(elt)

Choose a reason for hiding this comment

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

I like the conservative checks we are currently doing. That way if another case pop ups we don't have a default (and maybe unexpected) behavior.

self.visit(elt)
elif isinstance(elt, ast.Starred) and isinstance(elt.value, ast.Name):

Choose a reason for hiding this comment

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

group that with if isinstance(elt, ast.Name): above as it's the same body?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not exactly the same code, though.

tests/test_chains.py Show resolved Hide resolved
break
'''
self.checkChains(code, ['curr -> (curr -> (), curr -> (Call -> ()))',
'parts -> (Starred -> (), parts -> (), parts -> ())']*2)

Choose a reason for hiding this comment

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

I'm a bit puzzled by the Starred here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you develop ?

Choose a reason for hiding this comment

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

Why is the Starred in the def-use chain? It's not a user, right?

Choose a reason for hiding this comment

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

OK, I dive a bit and I now understand the situation a bit better. When we use * to expand a container as part of an argument call, the Starred is clearly a user. And it' has a Load context. When it's used to unpack a tuple, it has a Store context and it's just used to specify the nature of the operation. It is debatable whether that's a use or not... I'd rather see that as a property of the def, but we don't have that concept. I don't see it as a new Def either. Let me submit a new PR for that particular behavior

tests/test_chains.py Show resolved Hide resolved
'x -> ()'])

def test_call_assignment(self):
code = "NameError().name = 't'"

Choose a reason for hiding this comment

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

Yeah, it's not bound to any identifier... We could create temporary identifier for unbound expression that get assigned, but let's keep that for another patch.

@serge-sans-paille
Copy link
Owner

Can you rebase that one on the master branch? Thanks!

@serge-sans-paille serge-sans-paille merged commit f53330b into serge-sans-paille:master Aug 22, 2023
8 checks passed
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.

Bug in starred assignments
2 participants