Uh oh!
There was an error while loading. Please reload this page.
Check deferred nodes after all first passes in an import cycle - #2264
Conversation
| [file b.py] | ||
| import a | ||
| def g() -> int: | ||
| return a.y |
There was a problem hiding this comment.
Reveal the type of a.y (to verify that it doesn't somehow fall back to Any).
| [file a.py] | ||
| import b | ||
| def f() -> int: | ||
| return b.x |
| in options.strict_optional_whitelist) | ||
| def check_first_pass(self) -> None: | ||
| """Type check the entire file, but defer functions with forward references.""" |
There was a problem hiding this comment.
Be more explicit about forward reference mean. In particular, they mean references to definitions whose types haven't been inferred yet.
JukkaL
commented
Oct 19, 2016
Looks good to me! This hopefully fixes one of the biggest pain points mypy users with large code bases have had. I'd like to see some more test cases before merging:
|
gvanrossum
commented
Oct 19, 2016
I'll add more tests. I also discovered that reveal_type() needs to check for current_node_deferred. |
e5b8733 to
1471cb4Comparegvanrossum
commented
Oct 22, 2016
Rebased, generalized the multi-pass machinery, and added a test that would require 3 passes. Still needs tests for (2) and (3). Also, there are still some print() calls left. |
gvanrossum
commented
Oct 22, 2016
I could use a hint for (2). |
gvanrossum
commented
Oct 23, 2016
I think I have all the required tests now. Jukka, can you double-check? |
Current coverage is 84.90% (diff: 100%)@@ master #2264 diff @@
==========================================
Files 72 72 Lines 19037 20953 +1916 Methods 0 0 Messages 0 0 Branches 3919 4824 +905 ==========================================
+ Hits 15819 17790 +1971 + Misses 2618 2588 -30 + Partials 600 575 -25
|
| return False | ||
| self.errors.set_file(self.path) | ||
| self.pass_num += 1 | ||
| print('---', self.path, 'pass', self.pass_num + 1, '---') |
| for node, type_name in todo: | ||
| if node in done: | ||
| continue | ||
| print(type_name, '.', node.fullname() or node.name()) |
| tmp/a.py:4: error: Cannot determine type of 'x2' | ||
| [case testErrorInPassTwo] | ||
| # flags: --hide-error-context |
There was a problem hiding this comment.
Don't hide error context to test the it works correctly for errors reported in the second pass.
| import a | ||
| x = 1 + 1 | ||
| [out] | ||
| tmp/a.py:4: error: Unsupported operand types for + ("int" and "str") |
There was a problem hiding this comment.
Maybe also test this the other way as well (error reported in b.py in addition a.py).
| [file b.py] | ||
| from typing import Any | ||
| import a | ||
| def deco(f: Any) -> Any: |
There was a problem hiding this comment.
This decorator probably doesn't trigger a second pass, since simple decorator signatures are special cased in semantic analysis. A more complex decorator signature such as Callable[[T], int] -> Callable[[T]], str] is needed.
| [file a.py] | ||
| import b | ||
| def g() -> None: | ||
| f() |
There was a problem hiding this comment.
Make sure that the decorator function returns an interesting type (not Any) and do reveal_type(f()) here to verify that decorator got applied correctly.
These verify that deferral due to a cross-module dependency works.
f1b8872 to
3357393Compare3357393 to
d1778daComparegvanrossum
commented
Oct 24, 2016
Ready for review/merge. |
JukkaL
commented
Oct 24, 2016
LGTM now -- thanks for the updates! |
gvanrossum
commented
Oct 25, 2016
via email
OK, rebased and made all requested amendments. |
Might fix#481.