diff --git a/.github/workflows/check-deadcode-on-python38.yml b/.github/workflows/check-deadcode-on-python310.yml similarity index 84% rename from .github/workflows/check-deadcode-on-python38.yml rename to .github/workflows/check-deadcode-on-python310.yml index 953e827..f889b0f 100644 --- a/.github/workflows/check-deadcode-on-python38.yml +++ b/.github/workflows/check-deadcode-on-python310.yml @@ -1,7 +1,7 @@ # This workflow will install Python dependencies, run tests and lint with a single version of Python # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python -name: Checks deadcode package with Python3.8 +name: Checks deadcode package with Python3.10 on: push: @@ -19,10 +19,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v3 with: - python-version: "3.8" + python-version: "3.10" - name: Install dependencies run: | make .venv diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml new file mode 100644 index 0000000..6ca4b4e --- /dev/null +++ b/.pre-commit-hooks.yaml @@ -0,0 +1,9 @@ +# Config options described at: https://pre-commit.com/#creating-new-hooks +- id: deadcode + name: deadcode + description: "Deadcode: find and fix unused Python code" + entry: deadcode + language: python + minimum_pre_commit_version: 2.9.2 + require_serial: true + types: [python] diff --git a/Makefile b/Makefile index 2c37dd7..13930da 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ fix: format fixlint .venv: pip install uv - uv venv -p 3.8 .venv + uv venv -p 3.10 .venv uv pip sync requirements-dev.txt uv pip install -e .[test] @@ -22,7 +22,7 @@ lint: .venv .venv/bin/ruff check deadcode tests fix: .venv - .venv/bin/ruff deadcode tests --fix + .venv/bin/ruff check deadcode tests --fix mypy: .venv .venv/bin/mypy deadcode @@ -38,7 +38,7 @@ format: .venv .venv/bin/ruff format deadcode tests audit: .venv - .venv/bin/pip-audit + .venv/bin/pip-audit --skip-editable sync: .venv uv pip sync requirements-dev.txt diff --git a/README.md b/README.md index ac5f402..1aa1723 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,10 @@

Find and Fix Unused Python Code

-License: AGPLv3 +pre-commit PyPI Downloads +License: AGPLv3

@@ -71,9 +72,9 @@ ignore-names-in-files = ["migrations"] ##### Glossory -name - variable, function or class name. -body - code block which follows after `:` in function or class definition. -definition - whole class or function definition expression including its name and body. +- `name` - variable, function or class name. +- `body` - code block which follows after `:` in function or class definition. +- `definition` - whole class or function definition expression including its name and body. ## Rules @@ -173,6 +174,9 @@ code base is implemented in. - [ ] Check if file is still valid/parsable after automatic fixing, if not: halt the change and report error. ## Release notes +- v2.3.2: + - Add `pre-commit` hook support. + - Drop support for Python 3.8 and 3.9 versions, since their ast implementation is lacking features. - v2.3.1: - Started analysing files in bytes instead of trying to convert them into UTF-8 encoded strings. - Improved automatic removal of unused imports. diff --git a/deadcode/actions/fix_or_show_unused_code.py b/deadcode/actions/fix_or_show_unused_code.py index 03f1bd6..3066d0c 100644 --- a/deadcode/actions/fix_or_show_unused_code.py +++ b/deadcode/actions/fix_or_show_unused_code.py @@ -41,8 +41,13 @@ def fix_or_show_unused_code(unused_items: Iterable[CodeItem], args: Args) -> str if args.dry and ('__all_files__' in args.dry or _match(filename, args.dry)): with open(filename, 'rb') as f: filename_bytes = filename.encode() - diff = diff_bytes(unified_diff, f.readlines(), updated_file_content_lines, - fromfile=filename_bytes, tofile=filename_bytes) + diff = diff_bytes( + unified_diff, + f.readlines(), + updated_file_content_lines, + fromfile=filename_bytes, + tofile=filename_bytes, + ) # TODO: consider printing result instantly to save memory result_chunk = b''.join(diff) if args.no_color: diff --git a/deadcode/utils/fix_indent.py b/deadcode/utils/fix_indent.py index 36d3bbb..35a2e76 100644 --- a/deadcode/utils/fix_indent.py +++ b/deadcode/utils/fix_indent.py @@ -3,6 +3,7 @@ T = TypeVar('T') + def fix_indent(doc: T) -> Optional[T]: """Finds indentation of a first line and removes it from all following lines. diff --git a/pyproject.toml b/pyproject.toml index f702c38..c458a93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,20 +1,18 @@ [project] name = "deadcode" -version = "2.3.1" +version = "2.3.2" authors = [ {name = "Albertas Gimbutas", email = "albertasgim@gmail.com"}, ] description = "Find and remove dead code." readme = "README.md" -requires-python = ">= 3.8" +requires-python = ">= 3.10" classifiers = [ "Development Status :: 3 - Alpha", "License :: OSI Approved :: GNU Affero General Public License v3", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -156,10 +154,9 @@ ignore = [ ] "tests/fix/test_unused_imports.py" = ["F401", "W291"] - [tool.mypy] exclude = ["build", "dist", ".venv"] -python_version = "3.8" +python_version = "3.10" strict = true pretty = true color_output = true @@ -167,12 +164,6 @@ show_error_codes = true warn_return_any = true warn_unused_configs = true - -[tool.isort] -profile = "black" -multi_line_output = 3 -known_third_party = ["deadcode"] - [tool.deadcode] ignore_names = [ "ERROR_CODES", @@ -195,14 +186,7 @@ ignore_names = [ ignore_names_in_files = [ "deadcode/utils/base_test_case.py" ] - exclude = ["tests"] -[tool.black] -max_line_length = 120 -line_length = 120 -target_version = ["py38"] - - [tool.pytest.ini_options] addopts = "--cov=. --no-cov-on-fail --cov-fail-under=88.0" diff --git a/requirements-dev.txt b/requirements-dev.txt index 95d7fc7..8882e09 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -8,7 +8,7 @@ boolean-py==4.0 # via license-expression cachecontrol==0.14.0 # via pip-audit -certifi==2024.6.2 +certifi==2024.7.4 # via # httpcore # httpx @@ -25,12 +25,16 @@ coverage==7.5.4 # via pytest-cov cryptography==42.0.8 # via secretstorage -cyclonedx-python-lib==7.4.1 +cyclonedx-python-lib==7.5.1 # via pip-audit defusedxml==0.7.1 # via py-serializable distlib==0.3.8 # via virtualenv +exceptiongroup==1.2.1 + # via + # anyio + # pytest filelock==3.15.4 # via # cachecontrol @@ -85,7 +89,7 @@ msgpack==1.0.8 mypy==1.10.1 mypy-extensions==1.0.0 # via mypy -packageurl-python==0.15.1 +packageurl-python==0.15.3 # via cyclonedx-python-lib packaging==24.1 # via @@ -98,9 +102,9 @@ pathspec==0.12.1 # via hatchling pexpect==4.9.0 # via hatch -pip==24.1.1 +pip==24.1.2 # via pip-api -pip-api==0.0.33 +pip-api==0.0.34 # via pip-audit pip-audit==2.7.3 pip-requirements-parser==32.0.1 @@ -115,7 +119,7 @@ pluggy==1.5.0 # pytest ptyprocess==0.7.0 # via pexpect -py-serializable==1.0.3 +py-serializable==1.1.0 # via cyclonedx-python-lib pycparser==2.22 # via cffi @@ -134,7 +138,7 @@ rich==13.7.1 # via # hatch # pip-audit -ruff==0.5.0 +ruff==0.5.1 secretstorage==3.3.3 # via keyring shellingham==1.5.4 @@ -150,19 +154,26 @@ sortedcontainers==2.4.0 toml==0.10.2 # via pip-audit tomli==2.0.1 + # via + # coverage + # hatchling + # mypy + # pytest tomli-w==1.0.0 # via hatch -tomlkit==0.12.5 +tomlkit==0.13.0 # via hatch trove-classifiers==2024.7.2 # via hatchling typing-extensions==4.12.2 - # via mypy + # via + # anyio + # mypy urllib3==2.2.2 # via requests userpath==1.9.2 # via hatch -uv==0.2.21 +uv==0.2.24 # via hatch virtualenv==20.26.3 # via hatch diff --git a/tests/fix/test_unused_imports.py b/tests/fix/test_unused_imports.py index 9e2c10b..f4c9af5 100644 --- a/tests/fix/test_unused_imports.py +++ b/tests/fix/test_unused_imports.py @@ -38,7 +38,7 @@ def fn(): file2.py:4:4: DC07 Import `xyz` is never used file2.py:7:18: DC07 Import `foo` is never used - Removed 4 unused code items!""") + Removed 4 unused code items!"""), ) # TODO: empty imports statements should be removed as well.