diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 938737c..4ced560 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -90,3 +90,7 @@ jobs: - name: Check tests/ with mypy run: | python -m mypy tests/ + + - name: Check tests/ with basedpyright + run: | + basedpyright tests/ diff --git a/pyproject.toml b/pyproject.toml index 7963789..8823940 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "docstub" authors = [ {name = "Lars GrĂ¼ter"}, ] -description = "Generate Python stub files (PYI) from docstrings" +description = "Generate Python stub files from docstrings" readme = "README.md" license.file = "LICENSE" requires-python = ">=3.12" @@ -46,6 +46,7 @@ test = [ "pytest >=5.0.0", "pytest-cov >= 5.0.0", "mypy", + "basedpyright", ] [project.urls] @@ -129,3 +130,8 @@ disable_error_code = ["var-annotated", "union-attr"] [[tool.mypy.overrides]] module = ["numpydoc.*"] ignore_missing_imports = true + + +[tool.basedpyright] +stubPath = "stubs/" +typeCheckingMode = "standard" diff --git a/tests/test_analysis.py b/tests/test_analysis.py index 3f0cb5c..9307392 100644 --- a/tests/test_analysis.py +++ b/tests/test_analysis.py @@ -148,6 +148,8 @@ def test_query_types(self, search_name, expected_name, expected_origin): assert expected_name is type_name assert expected_origin is type_origin else: + assert type_name is not None + assert type_origin is not None assert str(type_origin) == expected_origin assert type_name.startswith(type_origin.target) assert type_name == expected_name @@ -174,6 +176,8 @@ def test_query_prefix(self, search_name, expected_name, expected_origin): assert expected_name is type_name assert expected_origin is type_origin else: + assert type_name is not None + assert type_origin is not None assert str(type_origin) == expected_origin assert type_name.startswith(type_origin.target) assert type_name == expected_name diff --git a/tests/test_docstrings.py b/tests/test_docstrings.py index fd4f619..b075e6e 100644 --- a/tests/test_docstrings.py +++ b/tests/test_docstrings.py @@ -207,7 +207,7 @@ def test_natlang_array_invalid_shape(self, shape): doctype = f"array of shape {shape}" transformer = DoctypeTransformer() with pytest.raises(lark.exceptions.UnexpectedInput): - transformer.doctype_to_annotation(doctype) + _ = transformer.doctype_to_annotation(doctype) def test_unknown_name(self): # Simple unknown name is aliased to typing.Any @@ -302,6 +302,7 @@ def test_returns(self, doctypes, expected): ).format(*doctypes) transformer = DoctypeTransformer() annotations = DocstringAnnotations(docstring, transformer=transformer) + assert annotations.returns is not None assert annotations.returns.value == expected def test_yields(self, caplog): @@ -315,6 +316,7 @@ def test_yields(self, caplog): ) transformer = DoctypeTransformer() annotations = DocstringAnnotations(docstring, transformer=transformer) + assert annotations.returns is not None assert annotations.returns.value == "Generator[tuple[int, str]]" assert annotations.returns.imports == { KnownImport(import_path="collections.abc", import_name="Generator") @@ -336,6 +338,7 @@ def test_receives(self, caplog): ) transformer = DoctypeTransformer() annotations = DocstringAnnotations(docstring, transformer=transformer) + assert annotations.returns is not None assert ( annotations.returns.value == "Generator[tuple[int, str], tuple[float, bytes]]" @@ -364,6 +367,7 @@ def test_full_generator(self, caplog): ) transformer = DoctypeTransformer() annotations = DocstringAnnotations(docstring, transformer=transformer) + assert annotations.returns is not None assert annotations.returns.value == ( "Generator[tuple[int, str], tuple[float, bytes], bool]" ) @@ -386,6 +390,7 @@ def test_yields_and_returns(self, caplog): ) transformer = DoctypeTransformer() annotations = DocstringAnnotations(docstring, transformer=transformer) + assert annotations.returns is not None assert annotations.returns.value == ("Generator[tuple[int, str], None, bool]") assert annotations.returns.imports == { KnownImport(import_path="collections.abc", import_name="Generator") @@ -416,6 +421,8 @@ def test_duplicate_returns(self, caplog): ) transformer = DoctypeTransformer() annotations = DocstringAnnotations(docstring, transformer=transformer) + assert annotations.returns is not None + assert annotations.returns is not None assert annotations.returns.value == "int" def test_args_kwargs(self): diff --git a/tests/test_stubs.py b/tests/test_stubs.py index 3bc8dda..ff96328 100644 --- a/tests/test_stubs.py +++ b/tests/test_stubs.py @@ -52,6 +52,7 @@ def foo(a, b=None): assert isinstance(func_def, cst.FunctionDef) docstring_node = _get_docstring_node(func_def) + assert isinstance(docstring_node, cst.SimpleString) assert docstring_node.value == docstring def test_func_without_docstring(self): @@ -196,7 +197,8 @@ def test_attributes_no_doctype(self, assign, expected, scope): src = MODULE_ATTRIBUTE_TEMPLATE.format(assign=assign, doctype="") elif scope == "class": src = CLASS_ATTRIBUTE_TEMPLATE.format(assign=assign, doctype="") - elif scope == "nested class": + else: + assert scope == "nested class" src = NESTED_CLASS_ATTRIBUTE_TEMPLATE.format(assign=assign, doctype="") transformer = Py2StubTransformer() @@ -234,7 +236,8 @@ def test_attributes_with_doctype(self, assign, doctype, expected, scope): src = MODULE_ATTRIBUTE_TEMPLATE.format(assign=assign, doctype=doctype) elif scope == "class": src = CLASS_ATTRIBUTE_TEMPLATE.format(assign=assign, doctype=doctype) - elif scope == "nested class": + else: + assert scope == "nested class" src = NESTED_CLASS_ATTRIBUTE_TEMPLATE.format(assign=assign, doctype=doctype) transformer = Py2StubTransformer()