def test_get_module_name(tmp_path: Path): root = tmp_path / 'project' root.mkdir() path = root / 'example.py' path.touch() assert StubsManager._get_module_name(path=path) == 'example' (root / '__init__.py').touch() assert StubsManager._get_module_name(path=path) == 'project.example'
def test_stubs_next_to_imported_module(tmp_path: Path): root = tmp_path / 'project' root.mkdir() (root / '__init__.py').touch() (root / 'other.py').write_text('def parent(): pass') stub = {'parent': {'raises': ['ZeroDivisionError', 'SomeError']}} (root / 'other.json').write_text(json.dumps(stub)) stubs = StubsManager() text = """ from project.other import parent @deal.raises() def child(): parent() """ sys.path.append(str(tmp_path)) try: tree = astroid.parse(dedent(text)) print(tree.repr_tree()) func_tree = tree.body[-1].body returns = tuple( r.value for r in get_exceptions_stubs(body=func_tree, stubs=stubs)) assert set(returns) == {ZeroDivisionError, 'SomeError'} finally: sys.path = sys.path[:-1]
def test_no_stubs_for_module(): stubs = StubsManager() text = """ from astroid import inference_tip @deal.raises() def child(): inference_tip() """ tree = astroid.parse(dedent(text)) print(tree.repr_tree()) func_tree = tree.body[-1].body returns = tuple(r.value for r in get_exceptions_stubs(body=func_tree, stubs=stubs)) assert returns == ()
def test_built_in_stubs(): stubs = StubsManager() text = """ from inspect import getfile @deal.raises() def child(): getfile(1) """ tree = astroid.parse(dedent(text)) print(tree.repr_tree()) func_tree = tree.body[-1].body returns = tuple(r.value for r in get_exceptions_stubs(body=func_tree, stubs=stubs)) assert returns == (TypeError, )
def test_marhsmallow_stubs(): stubs = StubsManager() text = """ from marshmallow.utils import from_iso_datetime @deal.raises() def child(): return from_iso_datetime('example') """ tree = astroid.parse(dedent(text)) print(tree.repr_tree()) func_tree = tree.body[-1].body returns = tuple(r.value for r in get_exceptions_stubs(body=func_tree, stubs=stubs)) assert returns == (ValueError, )
def test_infer_junk(): stubs = StubsManager() text = """ def another(): return 2 number = 3 @deal.raises() def child(): another() number() return unknown() # uninferrable """ tree = astroid.parse(dedent(text)) print(tree.repr_tree()) func_tree = tree.body[-1].body returns = tuple(r.value for r in get_exceptions_stubs(body=func_tree, stubs=stubs)) assert returns == ()
def test_stubs_in_the_root(tmp_path: Path): root = tmp_path / 'project' root.mkdir() (root / '__init__.py').touch() # (root / 'other.py').touch() stub = {'isnan': {'raises': ['ZeroDivisionError']}} (root / 'math.json').write_text(json.dumps(stub)) stubs = StubsManager(paths=[root]) text = """ from math import isnan @deal.raises() def child(): isnan() """ tree = astroid.parse(dedent(text)) print(tree.repr_tree()) func_tree = tree.body[-1].body returns = tuple(r.value for r in get_exceptions_stubs(body=func_tree, stubs=stubs)) assert returns == (ZeroDivisionError, )
def test_markers_from_stubs(): text = """ import ast nothing = None def do_nothing(): pass @deal.has() def inner(text): ast.walk(None) not_resolvable() do_nothing() nothing() """ text = dedent(text) tree = astroid.parse(text) print(tree.repr_tree()) stubs = StubsManager() tokens = list(get_markers(body=tree.body[-1].body, stubs=stubs)) markers = tuple(t.marker for t in tokens) assert markers == ('import', )
def test_marshmallow_get_stubs(): stubs = StubsManager() stub = stubs.get('marshmallow.utils') assert stub is not None
def test_stubs_manager(tmp_path: Path): stubs = StubsManager() root = tmp_path / 'project' root.mkdir() path = root / 'example.py' # test create stubs.create(path) assert set(stubs._modules) == {'example'} assert stubs._modules['example']._content == {} # test get assert stubs.get('example') is stubs._modules['example'] expected = {'raises': ['AssertionError', 'TypeError']} assert stubs.get('typing')._content['get_type_hints'] == expected # test do not re-create already cached stub old_stub = stubs.get('example') old_stub.dump() new_stub = stubs.create(path) assert new_stub is old_stub assert stubs.get('example') is old_stub # the same but path leads to stub, not code new_stub = stubs.create(path.with_suffix('.json')) assert new_stub is old_stub assert stubs.get('example') is old_stub # read already dumped stub instead of creating old_stub.add(func='fname', contract=Category.RAISES, value='TypeError') old_stub.dump() stubs = StubsManager() new_stub = stubs.create(path) assert new_stub is not old_stub assert new_stub._content == {'fname': {'raises': ['TypeError']}} # test read with non-stub extensions stub = stubs.read(path=path) assert stub.path.name == 'example.json' with pytest.raises(ValueError, match='invalid stub file extension.*'): stubs.read(path=path.with_suffix('.cpp'))
def test_get_module_name_for_real_modules(tmp_path: Path, given, expected): module = import_module(given) path = Path(module.__file__) assert StubsManager._get_module_name(path=path) == expected