{"id":13468601,"url":"https://github.com/jendrikseipp/vulture","last_synced_at":"2026-03-04T23:04:37.216Z","repository":{"id":37851256,"uuid":"84045805","full_name":"jendrikseipp/vulture","owner":"jendrikseipp","description":"Find dead Python code","archived":false,"fork":false,"pushed_at":"2025-11-25T12:24:40.000Z","size":724,"stargazers_count":4323,"open_issues_count":55,"forks_count":180,"subscribers_count":25,"default_branch":"main","last_synced_at":"2026-02-13T08:25:58.435Z","etag":null,"topics":["dead-code-removal","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jendrikseipp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-03-06T08:00:18.000Z","updated_at":"2026-02-12T17:16:40.000Z","dependencies_parsed_at":"2023-02-11T21:00:49.771Z","dependency_job_id":"ff49ae44-d505-49bf-8b78-448c5d22a17f","html_url":"https://github.com/jendrikseipp/vulture","commit_stats":{"total_commits":763,"total_committers":44,"mean_commits":17.34090909090909,"dds":0.1625163826998689,"last_synced_commit":"4ecc14923a307b265e912ea6520b139a0448c726"},"previous_names":[],"tags_count":51,"template":false,"template_full_name":null,"purl":"pkg:github/jendrikseipp/vulture","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jendrikseipp%2Fvulture","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jendrikseipp%2Fvulture/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jendrikseipp%2Fvulture/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jendrikseipp%2Fvulture/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jendrikseipp","download_url":"https://codeload.github.com/jendrikseipp/vulture/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jendrikseipp%2Fvulture/sbom","scorecard":{"id":514873,"data":{"date":"2025-08-11","repo":{"name":"github.com/jendrikseipp/vulture","commit":"3c2bef412d5c6860a1b91dc784e590565a6d5e6d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4,"checks":[{"name":"Maintained","score":3,"reason":"1 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":3,"reason":"Found 9/30 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yml:1","Warn: no topLevel permission defined: .github/workflows/pre-commit.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/jendrikseipp/vulture/main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/jendrikseipp/vulture/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/jendrikseipp/vulture/main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pre-commit.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/jendrikseipp/vulture/pre-commit.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pre-commit.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/jendrikseipp/vulture/pre-commit.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/main.yml:33","Warn: pipCommand not pinned by hash: .github/workflows/main.yml:34","Warn: pipCommand not pinned by hash: .github/workflows/main.yml:35","Warn: pipCommand not pinned by hash: .github/workflows/main.yml:42","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   4 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: MIT License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 10 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-20T01:33:47.900Z","repository_id":37851256,"created_at":"2025-08-20T01:33:47.900Z","updated_at":"2025-08-20T01:33:47.900Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30098118,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T22:49:54.894Z","status":"ssl_error","status_checked_at":"2026-03-04T22:49:48.883Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dead-code-removal","python"],"created_at":"2024-07-31T15:01:14.680Z","updated_at":"2026-03-04T23:04:37.204Z","avatar_url":"https://github.com/jendrikseipp.png","language":"Python","funding_links":[],"categories":["Python","资源列表","代码分析和 Lint 工具","Containers \u0026 Language Extentions \u0026 Linting","代码分析","Code Analysis","Code Analysis [🔝](#readme)","Programming Languages","Software Development AntiPatterns","Code Refactoring","Unused code detection"],"sub_categories":["代码分析和 Lint 工具","For Python"],"readme":"# Vulture - Find dead code\n\n[![PyPI Version](https://img.shields.io/pypi/v/vulture.svg)](https://pypi.python.org/pypi/vulture)\n[![Conda Version](https://img.shields.io/conda/vn/conda-forge/vulture.svg)](https://anaconda.org/conda-forge/vulture)\n![CI:Test](https://github.com/jendrikseipp/vulture/workflows/CI/badge.svg)\n[![Codecov Badge](https://codecov.io/gh/jendrikseipp/vulture/branch/main/graphs/badge.svg)](https://codecov.io/gh/jendrikseipp/vulture?branch=main)\n\nVulture finds unused code in Python programs. This is useful for\ncleaning up and finding errors in large code bases. If you run Vulture\non both your library and test suite you can find untested code.\n\nDue to Python's dynamic nature, static code analyzers like Vulture are\nlikely to miss some dead code. Also, code that is only called implicitly\nmay be reported as unused. Nonetheless, Vulture can be a very helpful\ntool for higher code quality.\n\n## Features\n\n* fast: uses static code analysis\n* tested: tests itself and has complete test coverage\n* complements pyflakes and has the same output syntax\n* sorts unused classes and functions by size with `--sort-by-size`\n\n## Installation\n\n    $ pip install vulture\n\n## Usage\n\n    $ vulture myscript.py  # or\n    $ python3 -m vulture myscript.py\n    $ vulture myscript.py mypackage/\n    $ vulture myscript.py --min-confidence 100  # Only report 100% dead code.\n\nThe provided arguments may be Python files or directories. For each\ndirectory Vulture analyzes all contained\n\u003cspan class=\"title-ref\"\u003e\\*.py\u003c/span\u003e files.\n\nAfter you have found and deleted dead code, run Vulture again, because\nit may discover more dead code.\n\n## Types of unused code\n\nIn addition to finding unused functions, classes, etc., Vulture can detect\nunreachable code. Each chunk of dead code is assigned a *confidence value*\nbetween 60% and 100%, where a value of 100% signals that it is certain that the\ncode won't be executed. Values below 100% are *very rough* estimates (based on\nthe type of code chunk) for how likely it is that the code is unused.\n\n| Code type                                              | Confidence value |\n|--------------------------------------------------------|------------------|\n| function/method/class argument, unreachable code       | 100%             |\n| import                                                 | 90%              |\n| attribute, class, function, method, property, variable | 60%              |\n\nYou can use the `--min-confidence` flag to set the minimum confidence\nfor code to be reported as unused. Use `--min-confidence 100` to only\nreport code that is guaranteed to be unused within the analyzed files.\n\n## Handling false positives\n\nWhen Vulture incorrectly reports chunks of code as unused, you have\nseveral options for suppressing the false positives. If fixing your false\npositives could benefit other users as well, please file an issue report.\n\n#### Whitelists\n\nThe recommended option is to add used code that is reported as unused to a\nPython module and add it to the list of scanned paths. To obtain such a\nwhitelist automatically, pass `--make-whitelist` to Vulture:\n\n    $ vulture mydir --make-whitelist \u003e whitelist.py\n    $ vulture mydir whitelist.py\n\nNote that the resulting `whitelist.py` file will contain valid Python\nsyntax, but for Python to be able to *run* it, you will usually have to\nmake some modifications.\n\nWe collect whitelists for common Python modules and packages in\n`vulture/whitelists/` (pull requests are welcome).\n\n#### Ignoring files\n\nIf you want to ignore a whole file or directory, use the `--exclude` parameter\n(e.g., `--exclude \"*settings.py,*/docs/*.py,*/test_*.py,*/.venv/*.py\"`). The\nexclude patterns are matched against absolute paths.\n\n#### Flake8 noqa comments\n\n\u003c!-- Hide noqa docs until we decide whether we want to support it.\nAnother way of ignoring errors is to annotate the line causing the false\npositive with `# noqa: \u003cERROR_CODE\u003e` in a trailing comment (e.g., `#\nnoqa: V103`). The `ERROR_CODE` specifies what kind of dead code to\nignore (see the table below for the list of error codes). In case no\nerror code is specified, Vulture ignores all results for the line.\n(Note that the line number for decorated objects is the line number of\nthe first decorator.)\n--\u003e\n\nFor compatibility with [flake8](https://flake8.pycqa.org/), Vulture\nsupports the [F401 and\nF841](https://flake8.pycqa.org/en/latest/user/error-codes.html) error\ncodes for ignoring unused imports (`# noqa: F401`) and unused local\nvariables (`# noqa: F841`). However, we recommend using whitelists instead\nof `noqa` comments, since `noqa` comments add visual noise to the code and\nmake it harder to read.\n\n#### Ignoring names\n\nYou can use `--ignore-names foo*,ba[rz]` to let Vulture ignore all names\nstarting with `foo` and the names `bar` and `baz`. Additionally, the\n`--ignore-decorators` option can be used to ignore the names of functions\ndecorated with the given decorator (but not their arguments or function body).\nThis is helpful for example in Flask\nprojects, where you can use `--ignore-decorators \"@app.route\"` to ignore all\nfunction names with the `@app.route` decorator. Note that Vulture simplifies\ndecorators it cannot parse: `@foo.bar(x, y)` becomes \"@foo.bar\" and\n`@foo.bar(x, y).baz` becomes \"@\" internally.\n\nWe recommend using whitelists instead of `--ignore-names` or\n`--ignore-decorators` whenever possible, since whitelists are\nautomatically checked for syntactic correctness when passed to Vulture\nand often you can even pass them to your Python interpreter and let it\ncheck that all whitelisted code actually still exists in your project.\n\n#### Marking unused variables\n\nThere are situations where you can't just remove unused variables, e.g.,\nin function signatures. The recommended solution is to use the `del`\nkeyword as described in the\n[PyLint manual](http://pylint-messages.wikidot.com/messages:w0613) and on\n[StackOverflow](https://stackoverflow.com/a/14836005):\n\n```python\ndef foo(x, y):\n    del y\n    return x + 3\n```\n\nVulture will also ignore all variables that start with an underscore, so\nyou can use `_x, y = get_pos()` to mark unused tuple assignments or\nfunction arguments, e.g., `def foo(x, _y)`.\n\n#### Minimum confidence\n\nRaise the minimum [confidence value](#types-of-unused-code) with the `--min-confidence` flag.\n\n#### Unreachable code\n\nIf Vulture complains about code like `if False:`, you can use a Boolean\nflag `debug = False` and write `if debug:` instead. This makes the code\nmore readable and silences Vulture.\n\n#### Forward references for type annotations\n\nSee [#216](https://github.com/jendrikseipp/vulture/issues/216). For\nexample, instead of `def foo(arg: \"Sequence\"): ...`, we recommend using\n\n``` python\nfrom __future__ import annotations\n\ndef foo(arg: Sequence):\n    ...\n```\n\n\n## Configuration\n\nYou can also store command line arguments in `pyproject.toml` under the\n`tool.vulture` section. Simply remove leading dashes and replace all\nremaining dashes with underscores.\n\nOptions given on the command line have precedence over options in\n`pyproject.toml`.\n\nExample Config:\n\n``` toml\n[tool.vulture]\nexclude = [\"*file*.py\", \"dir/\"]\nignore_decorators = [\"@app.route\", \"@require_*\"]\nignore_names = [\"visit_*\", \"do_*\"]\nmake_whitelist = true\nmin_confidence = 80\npaths = [\"myscript.py\", \"mydir\", \"whitelist.py\"]\nsort_by_size = true\nverbose = true\n```\n\nVulture will automatically look for a `pyproject.toml` in the current working directory.\n\nTo use a `pyproject.toml` in another directory, you can use the `--config path/to/pyproject.toml` flag.\n\n## Integrations\n\nYou can use a [pre-commit](https://pre-commit.com/#install) hook to run\nVulture before each commit. For this, install pre-commit and add the\nfollowing to the `.pre-commit-config.yaml` file in your repository:\n\n```yaml\nrepos:\n  - repo: https://github.com/jendrikseipp/vulture\n    rev: 'v2.3'  # or any later Vulture version\n    hooks:\n      - id: vulture\n```\n\nThen run `pre-commit install`. Finally, create a `pyproject.toml` file\nin your repository and specify all files that Vulture should check under\n`[tool.vulture] --\u003e paths` (see above).\n\nThere's also a [GitHub Action for Vulture](https://github.com/gtkacz/vulture-action),\na [VS Code extension](https://marketplace.visualstudio.com/items?itemName=sebastienfi.dead-code-finder)\nand you can use Vulture programmatically. For example:\n\n``` python\nimport vulture\n\nv = vulture.Vulture()\nv.scavenge(['.'])\nunused_code = v.get_unused_code()  # returns a list of `Item` objects\n```\n\n## How does it work?\n\nVulture uses the `ast` module to build abstract syntax trees for all\ngiven files. While traversing all syntax trees it records the names of\ndefined and used objects. Afterwards, it reports the objects which have\nbeen defined, but not used. This analysis ignores scopes and only takes\nobject names into account.\n\nVulture also detects unreachable code by looking for code after\n`return`, `break`, `continue` and `raise` statements, and by searching\nfor unsatisfiable `if`- and `while`-conditions.\n\n## Sort by size\n\nWhen using the `--sort-by-size` option, Vulture sorts unused code by its\nnumber of lines. This helps developers prioritize where to look for dead\ncode first.\n\n## Examples\n\nConsider the following Python script (`dead_code.py`):\n\n``` python\nimport os\n\nclass Greeter:\n    def greet(self):\n        print(\"Hi\")\n\ndef hello_world():\n    message = \"Hello, world!\"\n    greeter = Greeter()\n    func_name = \"greet\"\n    greet_func = getattr(greeter, func_name)\n    greet_func()\n\nif __name__ == \"__main__\":\n    hello_world()\n```\n\nCalling :\n\n    $ vulture dead_code.py\n\nresults in the following output:\n\n    dead_code.py:1: unused import 'os' (90% confidence)\n    dead_code.py:4: unused function 'greet' (60% confidence)\n    dead_code.py:8: unused variable 'message' (60% confidence)\n\nVulture correctly reports `os` and `message` as unused but it fails to\ndetect that `greet` is actually used. The recommended method to deal\nwith false positives like this is to create a whitelist Python file.\n\n**Preparing whitelists**\n\nIn a whitelist we simulate the usage of variables, attributes, etc. For\nthe program above, a whitelist could look as follows:\n\n``` python\n# whitelist_dead_code.py\nfrom dead_code import Greeter\nGreeter.greet\n```\n\nAlternatively, you can pass `--make-whitelist` to Vulture and obtain an\nautomatically generated whitelist.\n\nPassing both the original program and the whitelist to Vulture\n\n    $ vulture dead_code.py whitelist_dead_code.py\n\nmakes Vulture ignore the `greet` method:\n\n    dead_code.py:1: unused import 'os' (90% confidence)\n    dead_code.py:8: unused variable 'message' (60% confidence)\n\n\u003c!-- Hide noqa docs until we decide whether we want to support it.\n**Using \"# noqa\"**\n\n```python\nimport os  # noqa\n\nclass Greeter:  # noqa: V102\n    def greet(self):  # noqa: V103\n        print(\"Hi\")\n```\n\n## Error codes\n\nFor compatibility with [flake8](https://flake8.pycqa.org/), Vulture\nsupports the [F401 and\nF841](https://flake8.pycqa.org/en/latest/user/error-codes.html) error\ncodes.\n\n| Error codes |    Description    |\n| ----------- | ----------------- |\n| V101        | Unused attribute  |\n| V102        | Unused class      |\n| V103        | Unused function   |\n| V104, F401  | Unused import     |\n| V105        | Unused property   |\n| V106        | Unused method     |\n| V107, F841  | Unused variable   |\n| V201        | Unreachable code  |\n\n--\u003e\n\n## Exit codes\n\n| Exit code | Description                                                |\n|-----------|------------------------------------------------------------|\n| 0         | No dead code found                                         |\n| 1         | Invalid input (file missing, syntax error, wrong encoding) |\n| 2         | Invalid command line arguments                             |\n| 3         | Dead code found                                            |\n\n## Similar programs\n\n  - [pyflakes](https://pypi.org/project/pyflakes/) finds unused imports\n    and unused local variables (in addition to many other programmatic\n    errors).\n  - [coverage](https://pypi.org/project/coverage/) finds unused code\n    more reliably than Vulture, but requires all branches of the code to\n    actually be run.\n  - [uncalled](https://pypi.org/project/uncalled/) finds dead code by\n    using the abstract syntax tree (like Vulture), regular expressions,\n    or both.\n  - [dead](https://pypi.org/project/dead/) finds dead code by using the\n    abstract syntax tree (like Vulture).\n\n## Participate\n\nPlease visit \u003chttps://github.com/jendrikseipp/vulture\u003e to report any\nissues or to make pull requests.\n\n  - Contributing guide:\n    [CONTRIBUTING.md](https://github.com/jendrikseipp/vulture/blob/main/CONTRIBUTING.md)\n  - Release notes:\n    [CHANGELOG.md](https://github.com/jendrikseipp/vulture/blob/main/CHANGELOG.md)\n  - Roadmap:\n    [TODO.md](https://github.com/jendrikseipp/vulture/blob/main/TODO.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjendrikseipp%2Fvulture","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjendrikseipp%2Fvulture","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjendrikseipp%2Fvulture/lists"}