Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit afc14eb

Browse files
committed
add integration test (load all files in typeshed), fix some stuff it found
1 parent fcfa859 commit afc14eb

4 files changed

Lines changed: 39 additions & 3 deletions

File tree

tests/test.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
from pathlib import Path
23
from typed_ast import ast3
34
import typeshed_client
@@ -97,7 +98,8 @@ def test_conditions(self) -> None:
9798
self.check_conditions({'penguins', 'asyncio', 'new_stuff'}, version=(3, 4))
9899
self.check_conditions({'penguins', 'yield_from', 'new_stuff'}, version=(3, 3))
99100
self.check_conditions({'penguins', 'ages_long_past', 'new_stuff'}, version=(3, 2))
100-
self.check_conditions({'penguins', 'ages_long_past', 'old_stuff'}, version=(2, 7))
101+
self.check_conditions({'penguins', 'ages_long_past', 'old_stuff', 'more_old_stuff'},
102+
version=(2, 7))
101103

102104
def check_conditions(self, names: Set[str], *, version: Tuple[int, int] = (3, 6),
103105
platform: str = 'linux') -> None:
@@ -132,5 +134,25 @@ def test_simple(self) -> None:
132134
self.assertIsInstance(res.get_name(path, 'var'), typeshed_client.NameInfo)
133135

134136

137+
class IntegrationTest(unittest.TestCase):
138+
"""Tests that all files in typeshed are parsed without error."""
139+
fake_env = typeshed_client.parser.Env((3, 6), 'linux')
140+
fake_path = typeshed_client.ModulePath(('some', 'module'))
141+
142+
def test(self):
143+
typeshed_root = typeshed_client.finder.find_typeshed()
144+
for dirpath, _, filenames in os.walk(typeshed_root):
145+
for filename in filenames:
146+
path = Path(dirpath) / filename
147+
if path.suffix != '.pyi':
148+
continue
149+
with self.subTest(path=path):
150+
self.check_path(path)
151+
152+
def check_path(self, path: Path) -> None:
153+
ast = typeshed_client.finder.parse_stub_file(path)
154+
typeshed_client.parser.parse_ast(ast, self.fake_env, self.fake_path)
155+
156+
135157
if __name__ == '__main__':
136158
unittest.main()

tests/typeshed/stdlib/2and3/conditions.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@ if sys.version_info < (3, 0):
2222
old_stuff: int
2323
else:
2424
new_stuff: int
25+
26+
if sys.version_info[0] == 2:
27+
more_old_stuff: int

typeshed_client/finder.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ def get_stub_ast(module_name: str,
5858
path = get_stub_file(module_name, version=version)
5959
if path is None:
6060
return None
61+
return parse_stub_file(path)
62+
63+
64+
def parse_stub_file(path: Path) -> ast3.AST:
6165
text = path.read_text()
6266
# Always parse stubs as Python 3.6
6367
return ast3.parse(text, filename=str(path), feature_version=6)

typeshed_client/parser.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
"""This module is responsible for parsing a stub AST into a dictionary of names."""
22

3+
import logging
34
from mypy_extensions import NoReturn
45
import sys
56
from typed_ast import ast3
67
from typing import Any, Dict, Iterable, List, NamedTuple, NewType, Optional, Tuple, Union
78

89
from . import finder
910

11+
log = logging.getLogger(__name__)
12+
1013

1114
class InvalidStub(Exception):
1215
pass
@@ -54,10 +57,11 @@ def parse_ast(ast: ast3.AST, env: Env, module_name: ModulePath) -> NameDict:
5457
for info in names:
5558
if info.name in name_dict:
5659
if isinstance(info.ast, ImportedName) or info.child_nodes:
57-
raise InvalidStub('Cannot overload a class or an imported name')
60+
log.warning('Cannot overload a class or an imported name: %s', info)
61+
continue
5862
existing = name_dict[info.name]
5963
if isinstance(existing.ast, ImportedName) or existing.child_nodes:
60-
raise InvalidStub('Cannot overload a class or an imported name')
64+
log.warning('Cannot overload a class or an imported name: %s', existing)
6165
elif isinstance(existing.ast, OverloadedName):
6266
existing.ast.definitions.append(info.ast)
6367
else:
@@ -172,6 +176,9 @@ def visit_Num(self, node: ast3.Num) -> int:
172176
def visit_Str(self, node: ast3.Str) -> str:
173177
return node.s
174178

179+
def visit_Index(self, node: ast3.Index) -> int:
180+
return self.visit(node.value)
181+
175182
def visit_Tuple(self, node: ast3.Tuple) -> Tuple[Any, ...]:
176183
return tuple(self.visit(elt) for elt in node.elts)
177184

0 commit comments

Comments
 (0)