-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix --export-ref-info with type variable with value restrictions (#15285
) The regular function body has no type information if the function uses a type variable with a value restriction in its signature. Instead look at the expanded versions of the function body. This will produce duplicate references for some expressions, but that seems benign. Also add a foundation for writing tests for --export-ref-info and add a few test cases.
- Loading branch information
Showing
4 changed files
with
152 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
"""Test exporting line-level reference information (undocumented feature)""" | ||
|
||
from __future__ import annotations | ||
|
||
import json | ||
import os | ||
import sys | ||
|
||
from mypy import build | ||
from mypy.modulefinder import BuildSource | ||
from mypy.options import Options | ||
from mypy.test.config import test_temp_dir | ||
from mypy.test.data import DataDrivenTestCase, DataSuite | ||
from mypy.test.helpers import assert_string_arrays_equal | ||
|
||
|
||
class RefInfoSuite(DataSuite): | ||
required_out_section = True | ||
files = ["ref-info.test"] | ||
|
||
def run_case(self, testcase: DataDrivenTestCase) -> None: | ||
options = Options() | ||
options.use_builtins_fixtures = True | ||
options.show_traceback = True | ||
options.export_ref_info = True # This is the flag we are testing | ||
|
||
src = "\n".join(testcase.input) | ||
result = build.build( | ||
sources=[BuildSource("main", None, src)], options=options, alt_lib_path=test_temp_dir | ||
) | ||
assert not result.errors | ||
|
||
major, minor = sys.version_info[:2] | ||
ref_path = os.path.join(options.cache_dir, f"{major}.{minor}", "__main__.refs.json") | ||
|
||
with open(ref_path) as refs_file: | ||
data = json.load(refs_file) | ||
|
||
a = [] | ||
for item in data: | ||
a.append(f"{item['line']}:{item['column']}:{item['target']}") | ||
|
||
assert_string_arrays_equal( | ||
testcase.output, a, f"Invalid output ({testcase.file}, line {testcase.line})" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
[case testCallGlobalFunction] | ||
def f() -> None: | ||
g() | ||
|
||
def g() -> None: | ||
pass | ||
[out] | ||
2:4:__main__.g | ||
|
||
[case testCallMethod] | ||
def f() -> None: | ||
c = C() | ||
if int(): | ||
c.method() | ||
|
||
class C: | ||
def method(self) -> None: pass | ||
[out] | ||
2:8:__main__.C | ||
3:7:builtins.int | ||
4:8:__main__.C.method | ||
|
||
[case testCallStaticMethod] | ||
class C: | ||
def f(self) -> None: | ||
C.static() | ||
self.static() | ||
|
||
@classmethod | ||
def cm(cls) -> None: | ||
cls.static() | ||
|
||
@staticmethod | ||
def static() -> None: pass | ||
[builtins fixtures/classmethod.pyi] | ||
[out] | ||
3:8:__main__.C | ||
3:8:__main__.C.static | ||
4:8:__main__.C.static | ||
8:8:__main__.C.static | ||
|
||
[case testCallClassMethod] | ||
class C: | ||
def f(self) -> None: | ||
C.cm() | ||
self.cm() | ||
|
||
@classmethod | ||
def cm(cls) -> None: | ||
cls.cm() | ||
[builtins fixtures/classmethod.pyi] | ||
[out] | ||
3:8:__main__.C | ||
3:8:__main__.C.cm | ||
4:8:__main__.C.cm | ||
8:8:__main__.C.cm | ||
|
||
[case testTypeVarWithValueRestriction] | ||
from typing import TypeVar | ||
|
||
T = TypeVar("T", "C", "D") | ||
|
||
def f(o: T) -> None: | ||
f(o) | ||
o.m() | ||
o.x | ||
|
||
class C: | ||
x: int | ||
def m(self) -> None: pass | ||
|
||
class D: | ||
x: str | ||
def m(self) -> None: pass | ||
[out] | ||
3:4:typing.TypeVar | ||
3:0:__main__.T | ||
6:4:__main__.f | ||
7:4:__main__.C.m | ||
8:4:__main__.C.x | ||
6:4:__main__.f | ||
7:4:__main__.D.m | ||
8:4:__main__.D.x |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters