Skip to content

Conversation

@ilevkivskyi
Copy link
Member

This allows supporting forward references within function namespaces. The logic is very simple, go over and over each top-level function/method until everything inside it is resolved, plus one more pass to report errors.

The big diff in _visit_func_def() is because of whitespace, I didn't change any function body analysis logic apart from removing previous two-pass special-casing for functions (GitHub has an option to ignore whitespace in the diff).

@ilevkivskyi ilevkivskyi requested a review from JukkaL January 31, 2019 16:54
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.

This is a very clean way to deal with forward references! Left a few comments. Also, it's not clear if this will we able to catch references to variables before their definition, similar to the old semantic analyzer. I mean things like x; x = 1 currently generate an error. If this is a regression that is non-trivial to fix, it's okay to fix it later.

if 'optional' in testcase.file:
options.strict_optional = True
if 'newsemanal' in testcase.file:
options.new_semantic_analyzer = True
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a good idea!

active_type)
assert not deferred # There can't be cross-function forward refs
assert not incomplete # Ditto
iteration = 0
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be better to move the new logic to a separate function. I think that process_functions is now too big.

types = []
non_overload_indexes = []
impl = None # type: Optional[OverloadPart]
if defn.impl:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ew the way this works is ugly (the existing logic, not this change in particular). Add TODO item about not modifying the items list.

return int()
def other() -> str:
reveal_type(one()) # E: Revealed type is 'builtins.int'
return str()
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be good to have a test case where we hit the maximum iteration count (cyclic definition).

errors: Report analysis errors using this instance
"""
self.locals = [None]
# Saved namespaces from previous passes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

A more detailed explanation would be nice here. Also, avoid the use of the term 'pass' since this means a different thing in the old semantic analyzer (maybe 'iteration'?).

def enter(self) -> None:
self.locals.append(SymbolTable())
def enter(self, function: Optional[FuncItem] = None) -> None:
if function:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add docstring and describe the argument. Also discuss when it's okay to leave it out.

assert not deferred # There can't be cross-function forward refs
assert not incomplete # Ditto
iteration = 0
# We need one more pass after incomplete is False.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Similar to above, it's probably better to avoid the term 'pass' here. Also consider renaming the more_passes variable.

@ilevkivskyi
Copy link
Member Author

I mean things like x; x = 1 currently generate an error.

Yes, it looks like non-trivial to fix in general, I will open an issue.

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 now!

@ilevkivskyi ilevkivskyi merged commit b027308 into python:master Feb 1, 2019
@ilevkivskyi ilevkivskyi deleted the support-nested-stuff branch February 1, 2019 19:36
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