Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
TravisDart committed Dec 20, 2024
2 parents e56cc10 + 4ecc149 commit fcc3704
Show file tree
Hide file tree
Showing 27 changed files with 1,145 additions and 608 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']

steps:
- name: Checkout code
Expand All @@ -26,6 +26,7 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true

- name: Install dependencies
run: |
Expand Down
5 changes: 4 additions & 1 deletion .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
entry: vulture
description: Find unused Python code.
types: [python]
# Vulture needs access to all files for a complete analysis, so we
# prevent pre-commit from passing only the changed files. Instead,
# please create a `pyproject.toml` file in your repository and specify
# all files that Vulture should check under `[tool.vulture] --> paths`.
pass_filenames: false
require_serial: true

20 changes: 17 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
# next (unreleased)

* Use `ruff` for linting (Anh Trinh, #347).
* Use `ruff` for formatting (Anh Trinh, #349).
* Handle `while True` loops without `break` statements (kreathon).

# 2.14 (2024-12-08)

* Improve reachability analysis (kreathon, #270, #302).
* Add type hints 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).
* Add PyPI and conda-forge badges to README file (Trevor James Smith, #356).
* Include `tests/**/*.toml` in sdist (Colin Watson).

# 2.12 (2024-09-17)

* Use `ruff` for linting and formatting (Anh Trinh, #347, #349).
* Replace `tox` by `pre-commit` for linting and formatting (Anh Trinh, #349).
* Add `--config` flag to specify path to pyproject.toml configuration file (Glen Robertson #352).
* Add `--config` flag to specify path to pyproject.toml configuration file (Glen Robertson, #352).

# 2.11 (2024-01-06)

Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include *.md
include *.txt
include tests/*.py
include tests/**/*.toml
include tox.ini
include vulture/whitelists/*.py
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Vulture - Find dead code

[![PyPI Version](https://img.shields.io/pypi/v/vulture.svg)](https://pypi.python.org/pypi/vulture)
[![Conda Version](https://img.shields.io/conda/vn/conda-forge/vulture.svg)](https://anaconda.org/conda-forge/vulture)
![CI:Test](https://github.com/jendrikseipp/vulture/workflows/CI/badge.svg)
[![Codecov Badge](https://codecov.io/gh/jendrikseipp/vulture/branch/main/graphs/badge.svg)](https://codecov.io/gh/jendrikseipp/vulture?branch=main)

Expand Down Expand Up @@ -189,7 +191,7 @@ 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.

## Version control integration
## Integrations

You can use a [pre-commit](https://pre-commit.com/#install) hook to run
Vulture before each commit. For this, install pre-commit and add the
Expand All @@ -207,6 +209,17 @@ Then run `pre-commit install`. Finally, create a `pyproject.toml` file
in your repository and specify all files that Vulture should check under
`[tool.vulture] --> paths` (see above).

There's also a [GitHub Action for Vulture](https://github.com/gtkacz/vulture-action)
and you can 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
```

## How does it work?

Vulture uses the `ast` module to build abstract syntax trees for all
Expand Down
2 changes: 1 addition & 1 deletion dev/make-release-notes.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def check(name, text):
print("*" * 60)
print(text)
print("*" * 60)
response = input("Accept this %s (Y/n)? " % name).strip().lower()
response = input(f"Accept this {name} (Y/n)? ").strip().lower()
if response and response != "y":
sys.exit(1)

Expand Down
9 changes: 6 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,19 @@ indent-width = 4
target-version = "py38"

[tool.ruff.lint]
# ruff enables Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
# ruff enables Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
select = [
"F", # pyflakes
"E4", "E7", "E9", # pycodestyle
"B", # flake8-bugbear
"C4", # comprehensions
"E", # pycodestyle
"F", # pyflakes
"I001", # isort
"SIM", # flake8-simplify
"UP", # pyupgrade
]
ignore = [
"C408", # unnecessary dict call
"SIM115", # Use context handler for opening files
]

# Allow fix for all enabled rules (when `--fix`) is provided.
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def find_version(*parts):
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Quality Assurance",
Expand Down
13 changes: 12 additions & 1 deletion tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@

REPO = pathlib.Path(__file__).resolve().parents[1]
WHITELISTS = [
str(path) for path in (REPO / "vulture" / "whitelists").glob("*.py")
str(path)
for path in (REPO / "vulture" / "whitelists").glob("*.py")
# Pint is incompatible with Python 3.13 (https://github.com/hgrecco/pint/issues/1969).
if sys.version_info < (3, 13) or path.name != "pint_whitelist.py"
]


Expand Down Expand Up @@ -36,6 +39,14 @@ def check_unreachable(v, lineno, size, name):
assert item.name == name


def check_multiple_unreachable(v, checks):
assert len(v.unreachable_code) == len(checks)
for item, (lineno, size, name) in zip(v.unreachable_code, checks):
assert item.first_lineno == lineno
assert item.size == size
assert item.name == name


@pytest.fixture
def v():
return core.Vulture(verbose=True)
145 changes: 0 additions & 145 deletions tests/test_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from vulture import utils

from . import check_unreachable
from . import v

assert v # Silence pyflakes
Expand Down Expand Up @@ -73,147 +72,3 @@ def test_errors():
condition = ast.parse(condition, mode="eval").body
assert not utils.condition_is_always_false(condition)
assert not utils.condition_is_always_true(condition)


def test_while(v):
v.scan(
"""\
while False:
pass
"""
)
check_unreachable(v, 1, 2, "while")


def test_while_nested(v):
v.scan(
"""\
while True:
while False:
pass
"""
)
check_unreachable(v, 2, 2, "while")


def test_if_false(v):
v.scan(
"""\
if False:
pass
"""
)
check_unreachable(v, 1, 2, "if")


def test_elif_false(v):
v.scan(
"""\
if bar():
pass
elif False:
print("Unreachable")
"""
)
check_unreachable(v, 3, 2, "if")


def test_nested_if_statements_false(v):
v.scan(
"""\
if foo():
if bar():
pass
elif False:
print("Unreachable")
pass
elif something():
print("Reachable")
else:
pass
else:
pass
"""
)
check_unreachable(v, 4, 3, "if")


def test_if_false_same_line(v):
v.scan(
"""\
if False: a = 1
else: c = 3
"""
)
check_unreachable(v, 1, 1, "if")


def test_if_true(v):
v.scan(
"""\
if True:
a = 1
b = 2
else:
c = 3
d = 3
"""
)
# For simplicity, we don't report the "else" line as dead code.
check_unreachable(v, 5, 2, "else")


def test_if_true_same_line(v):
v.scan(
"""\
if True:
a = 1
b = 2
else: c = 3
d = 3
"""
)
check_unreachable(v, 4, 1, "else")


def test_nested_if_statements_true(v):
v.scan(
"""\
if foo():
if bar():
pass
elif True:
if something():
pass
else:
pass
elif something_else():
print("foo")
else:
print("bar")
else:
pass
"""
)
check_unreachable(v, 9, 4, "else")


def test_redundant_if(v):
v.scan(
"""\
if [5]:
pass
"""
)
print(v.unreachable_code[0].size)
check_unreachable(v, 1, 2, "if")


def test_if_exp_true(v):
v.scan("foo if True else bar")
check_unreachable(v, 1, 1, "ternary")


def test_if_exp_false(v):
v.scan("foo if False else bar")
check_unreachable(v, 1, 1, "ternary")
4 changes: 2 additions & 2 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
Unit tests for config file and CLI argument parsing.
"""

from io import BytesIO
import pathlib
from io import BytesIO
from textwrap import dedent

import pytest

from vulture.config import (
DEFAULTS,
InputError,
_check_input_config,
_parse_args,
_parse_toml,
make_config,
InputError,
)


Expand Down
3 changes: 2 additions & 1 deletion tests/test_encoding.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import codecs

from . import v
from vulture.utils import ExitCode

from . import v

assert v # Silence pyflakes.


Expand Down
3 changes: 2 additions & 1 deletion tests/test_errors.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import pytest

from . import v, call_vulture
from vulture.utils import ExitCode

from . import call_vulture, v

assert v # Silence pyflakes.


Expand Down
1 change: 1 addition & 0 deletions tests/test_noqa.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from vulture.core import ERROR_CODES
from vulture.noqa import NOQA_CODE_MAP, NOQA_REGEXP, _parse_error_codes

from . import check, v

assert v # Silence pyflakes.
Expand Down
11 changes: 11 additions & 0 deletions tests/test_pytype.py
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit fcc3704

Please sign in to comment.