diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a944eb..eef612b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# next (unreleased) + +* Add typehints for `get_unused_code` and the fields of the `Item` class (John Doknjas, #361). + # 2.13 (2024-10-02) * Add support for Python 3.13 (Jendrik Seipp, #369). diff --git a/README.md b/README.md index 45bb3c4..9746153 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,16 @@ Vulture will automatically look for a `pyproject.toml` in the current working di To use a `pyproject.toml` in another directory, you can use the `--config path/to/pyproject.toml` flag. +It's also possible to use vulture programatically. For example: + +``` python +import vulture + +v = vulture.Vulture() +v.scavenge(['.']) +unused_code = v.get_unused_code() # returns a list of `Item` objects +``` + ## Integrations You can use a [pre-commit](https://pre-commit.com/#install) hook to run diff --git a/tests/test_pytype.py b/tests/test_pytype.py new file mode 100644 index 0000000..8ee01c0 --- /dev/null +++ b/tests/test_pytype.py @@ -0,0 +1,11 @@ +import subprocess +import sys + +import pytest + + +@pytest.mark.skipif( + sys.version_info >= (3, 13), reason="needs Python < 3.13 for pytype" +) +def test_pytype(): + assert subprocess.run(["pytype", "vulture/core.py"]).returncode == 0 diff --git a/tox.ini b/tox.ini index 3d36356..357c410 100644 --- a/tox.ini +++ b/tox.ini @@ -15,6 +15,7 @@ deps = pint # Use latest version to catch API changes. pytest pytest-cov + pytype ; python_version < '3.13' commands = pytest {posargs} # Install package as wheel in all envs (https://hynek.me/articles/turbo-charge-tox/). diff --git a/vulture/core.py b/vulture/core.py index b3c845c..2cadabb 100644 --- a/vulture/core.py +++ b/vulture/core.py @@ -5,6 +5,7 @@ import re import string import sys +from typing import List from vulture import lines from vulture import noqa @@ -139,13 +140,13 @@ def __init__( message="", confidence=DEFAULT_CONFIDENCE, ): - self.name = name - self.typ = typ - self.filename = filename - self.first_lineno = first_lineno - self.last_lineno = last_lineno - self.message = message or f"unused {typ} '{name}'" - self.confidence = confidence + self.name: str = name + self.typ: str = typ + self.filename: Path = filename + self.first_lineno: int = first_lineno + self.last_lineno: int = last_lineno + self.message: str = message or f"unused {typ} '{name}'" + self.confidence: int = confidence @property def size(self): @@ -219,6 +220,7 @@ def get_list(typ): self.filename = Path() self.code = [] self.exit_code = ExitCode.NoDeadCode + self.noqa_lines = {} def scan(self, code, filename=""): filename = Path(filename) @@ -300,10 +302,13 @@ def exclude_path(path): except OSError: # Most imported modules don't have a whitelist. continue + assert module_data is not None module_string = module_data.decode("utf-8") self.scan(module_string, filename=path) - def get_unused_code(self, min_confidence=0, sort_by_size=False): + def get_unused_code( + self, min_confidence=0, sort_by_size=False + ) -> List[Item]: """ Return ordered list of unused Item objects. """