Skip to content

Conversation

@ilevkivskyi
Copy link
Member

Fixes #6284
Fixes #6285

This doesn't add support for recursive definitions, but all the forward reference patterns that are supported in old semantic analyzer, should be also supported.

Some notes:

  • I moved one function to semanal_namedtuple.py
  • I never create new TypeInfos in multi-iteration scenario
  • I add a dummy type variable _NT to the bodies (otherwise type variable scope breaks), but it is probably fine because names starting with underscores are anyway prohibited in named tuples.

@ilevkivskyi ilevkivskyi requested a review from JukkaL February 4, 2019 20:00
Copy link
Collaborator

@JukkaL JukkaL left a comment

Choose a reason for hiding this comment

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

Looks good! Just one significant request (don't reanalyze if it was previously successful) and some minor things. The prior can be implemented in a separate PR.

@ilevkivskyi
Copy link
Member Author

@JukkaL Thanks for review!

Because you merged your PR first, it was necessary to update my implementation logic for assignment based named tuples (basically it is much closer to class based one now). I however discovered couple small bugs:

  • Wrong full name was set for named tuples nested in methods (this area around names with @line is still dark and will need some clean-up later).
  • Processing of functions/methods were stopping to soon.

I fixed them and added more tests.

Copy link
Collaborator

@JukkaL JukkaL left a comment

Choose a reason for hiding this comment

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

Thanks for the updates! Left some more comments.

return
# Yes, it's a valid namedtuple, but defer if it is not ready.
if not info:
self.add_symbol(name, PlaceholderNode(self.qualified_name(name), lvalue, True),
Copy link
Collaborator

Choose a reason for hiding this comment

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

mark_incomplete adds a PlaceholderNode. The logic is a bit delicate so it's important that all additions go through the same implementation.

while deferred and more_iterations:
iteration += 1
if not incomplete or iteration == MAX_ITERATIONS:
if not (deferred or incomplete) or iteration == MAX_ITERATIONS:
Copy link
Collaborator

Choose a reason for hiding this comment

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

A namespace can be deferred while it's incomplete. I think that we should also remove the namespace from incomplete namespaces if it's complete. Now it looks like that we sometimes don't remove the namespace from incomplete_namespaces even though we probably should.

In = NamedTuple('In', [('s', str), ('t', Other)])
class Other: pass

[case testNewAnalyzerNamedTupleMixed1]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a specific reason for adding these tests? It will be impractical to test all combinations of features anyway, as the number of test cases will grow too quickly. For example, is this more useful than a mixed named tuple vs. typed dict test case? It may be better to only test combinations that are known to be risky or have been broken previously.

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, these two tests cases were broken, but then the breakage had the same cause as for assignment based vs assignment based, so it is probably OK to remove them.

defn.info._fullname = self.cur_mod_id + '.' + local_name
if defn.info.is_named_tuple:
# Module already correctly set for named tuples.
defn.info._fullname += '@' + str(defn.line)
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's unclear why we need this special case. Even if the module was already correctly set, if it's always self.cur_mod_id, I think that it's better to avoid this if statement if it doesn't change behavior.

Copy link
Member Author

Choose a reason for hiding this comment

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

As discussed elsewhere this is (unfortunately) actually needed.

@JukkaL JukkaL changed the title New semantic analyzer: support named tuples. New semantic analyzer: support named tuples Feb 6, 2019
Copy link
Collaborator

@JukkaL JukkaL left a comment

Choose a reason for hiding this comment

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

Thanks for the updates! Looks good now, just one remaining nit.

name: The name that we weren't able to define (or '*' if the name is unknown)
node: The node that refers to the name (definition or lvalue)
becomes_typeinfo: Pass this to Placeholder (used by special forms like named tuples
that will create TypeInfos).
Copy link
Collaborator

Choose a reason for hiding this comment

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

Style nit: we generally further indent the second line of argument decsriptions.

@ilevkivskyi ilevkivskyi merged commit be6b6b1 into python:master Feb 6, 2019
@ilevkivskyi ilevkivskyi deleted the support-synthetic-new branch February 6, 2019 17:04
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