Skip to content

bpo-44896: drop lineno requirement on nodes for ast.unparse #27770

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

Closed
wants to merge 1 commit into from

Conversation

isidentical
Copy link
Member

@isidentical isidentical commented Aug 14, 2021

@isidentical
Copy link
Member Author

@pablogsal do you think we should backport this to 3.9? I don't see this as a bug, so not sure if we should document this as a change on 3.11 or just backport it.

@pablogsal
Copy link
Member

I'm +1 with backport, I see it more as a bigfix but I trust your decision :)

@xiaket
Copy link

xiaket commented Aug 14, 2021

As the original issue creator I hope I can way in to suggest we backport it, as I don’t think this is a feature, it’s more about fixing the unexpected behavior of the module.

Lib/ast.py Outdated
Comment on lines 791 to 795
lineno = getattr(node, 'lineno', None)
if lineno is None:
return None

comment = self._type_ignores.get(lineno) or node.type_comment
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not so sure about this. The crash before at least made the user call fix_missing_locations which solves the problem. Now you're suggesting to change the behavior in possibly invalid ways:

  • if there is a node.type_comment set but line number isn't, now it will be silently not returned;
  • if there is a matching type ignore in self._type_ignore, it won't be found because the location information is missing and no type comment will be returned.

Since the new behavior makes the code silently miss returning type comments without any indication as to why, the programmer might have trouble finding why this is.

@isidentical isidentical force-pushed the fix-ast-unparse-lineno branch from 6016538 to ba29911 Compare September 13, 2021 14:19
Copy link
Contributor

@ambv ambv left a comment

Choose a reason for hiding this comment

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

I think we should just let this go and instead advertise that if you put new synthetic nodes in a tree, you have to either provide lineno and col_offset yourself, or use fix_missing_locations() to fill out the information for you.

The problem with the logic that I commented on twice now is one reason for my opinion. Another is bigger though:

Suppose user code is replacing nodes or just inserting new ones. This operation not only creates nodes without location attributes. It also in all likelihood moves locations of type comments and those aren't updated (for example, _type_ignores[123] should now really be _type_ignores[125] to still point at the same tokens). So user code shouldn't be naive when it comes to missing locations, and we definitely shouldn't paper over missing locations.

Comment on lines +791 to +796
comment = None
if node.type_comment is not None:
comment = node.type_comment
elif (lineno := getattr(node, 'lineno', None)) is not None:
comment = self._type_ignores.get(lineno)

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's back up a little.

Assuming node.lineno exists, the old code behaved like this:

  • if there is a type ignore for the current line, use it
  • otherwise, use whatever is in node.type_comment

With your new code, node.type_comment is always used if it exists, reversing the priority.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, and this was intentional. If there is a type_comment attached, it should take the priority since type_ignores is a property of the module but on the other hand type_comment directly belongs to the node itself, so a change in it probably reflect / overwrite the specified type_ignores. Not sure if this deserves another PR with only this change (with still forcing for lineno), but I feel like closer to the node == better reflectiveness should hold up in this case.

@bedevere-bot
Copy link

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

@ambv ambv closed this Sep 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants