This guide compares five useful options for Python analysis in 2026: Semgrep, Bandit, CodeQL, Vulture, and Skylos. They solve different slices of security, dead-code, quality, and AI-assisted-code review; Vulture is a dead-code tool rather than SAST.

The comparison focuses on published detection scope, likely triage work, CI/CD integration, dead-code support, and AI-oriented workflows. It does not claim a universal false-positive ranking; that requires a labeled corpus representative of your code.

If you want the shortest possible answer:

  • choose Semgrep for multi-language security and custom rules
  • choose Bandit for a simple, familiar Python security linter
  • choose CodeQL for deeper GitHub-native analysis
  • choose Vulture for dead code only
  • choose Skylos if you want Python security, dead code, quality checks, and AI-code review in one workflow

Quick comparison table

SemgrepBanditCodeQLVultureSkylos
FocusMulti-language securityPython securityMulti-language securityDead codeSecurity + dead code + quality
Languages30+ in CE; depth varies by enginePython onlyC/C++, C#, Go, Java/Kotlin, JavaScript/TypeScript, Python, Ruby, Rust, Swift, and ActionsPython onlyPython (deepest), TypeScript/JavaScript and Java: dead code, security and quality. PHP, Rust, Dart: dead code and security. Go: dead code and security need the separate skylos-go engine (in the Docker image and GitHub Action, not the PyPI package). C# partial. Kotlin: dead code only. C++: unused file-local functions only. Shell: security only.
Security rulesLarge community and Pro rule setsPython AST plugin checksQuery suites with semantic and data-flow analysisNoneBuilt-in pattern and flow rules; depth varies by language/category
Dead codeNot a dedicated analyzerNoPython quality queries for unused imports, unused variables and unreachable code; no whole-program unused-function analysisYesYes; deepest in Python
Code qualitySecurity-firstSecurity-firstCode scanning is security-focused; GitHub Code Quality is a separate productNoYes; metrics are primarily Python-focused
Taint analysisCE: taint within a single function; hosted Pro engine: cross-function and cross-fileNo general interstatement taint engineYesN/ALocal propagation for supported source/sink patterns; conservative parameter handling
Custom rulesYes (multi-language DSL)Python plugin systemYes (QL language)Whitelists and ignore controlsFocused Python AST rules; much narrower than Semgrep or QL
Framework awareRule-dependentIndividual plugin-dependentQuery-dependentImplicit uses may require ignores/whitelistsExplicit Python entry-point models for common frameworks
AI-oriented checksSemgrep Guardian (launched June 2026): MCP server, hooks and skills that rescan agent-written code; plus custom rulesNo dedicated suiteGitHub also offers separate Code Quality AI analysisNo dedicated suiteAI-defect checks, selected removed-control diffs, and LLM/agent static plugins
CI/CDStandalone CE and hosted workflowsPre-commit, GitHub Action, or manual CIGitHub-native default or advanced setupGitHub Action, pre-commit, or manual CIAuto-generated GitHub Actions workflow
Free availabilityOpen-source CE and hosted Free planOpen sourcePublic repositories; private repository access depends on GitHub Code Security licensingOpen sourceCLI free (Apache-2.0), including the LLM verifier with your own model key. Skylos Cloud: Free plan (1 project) and Workspace plan ($990 per workspace for 12 months, paid once, or 12 months with any credit pack from $9); no seats, line meter or subscriptions.

1. Semgrep

Best for: Multi-language teams, custom rule authoring, enterprise security programs

Semgrep is the broadest general-purpose SAST option on this list. Community Edition supports 30+ languages and 3,000+ customizable community rules; the hosted platform adds a Pro engine and AppSec workflows. Analysis depth varies by language and product.

Strengths

  • Custom rule DSL. You can encode team-specific structural and taint policies in YAML across supported languages.
  • Large ecosystem. Semgrep documents more than 3,000 customizable community rules for Community Edition. The engine is LGPL-2.1; since December 2024 the rules are under the Semgrep Rules License, which is not an OSI open-source license (the Opengrep fork exists for that reason).
  • Multi-language. If you have Python + Java + Go + JS, Semgrep scans all of them.
  • Hosted workflows. Findings triage and pull-request integrations are available, RBAC and SAML/OIDC SSO start at the Teams plan, while Jira and Slack integrations are on every tier (pricing).
  • Taint analysis. Semgrep CE tracks taint only within a single function (with constant propagation across functions in one file); the Pro engine adds cross-function and cross-file analysis, and the hosted Free plan (up to 10 contributors and 10 private repositories) includes it.

Weaknesses

  • No dedicated dead-code analyzer. You need a separate usage/reachability tool for that job.
  • Security-first scope. Complexity, coupling, and cohesion are not Semgrep's core product focus.
  • Engine differences matter. CE taint stays within a single function; Pro analysis adds cross-function and cross-file context, so a generic "Semgrep" result is not one fixed capability.
  • Framework behavior depends on rules. Confirm that the selected rule set and engine model the framework APIs and flows you rely on.

Quick start

pipx install semgrep
semgrep scan --config auto src/

When to choose Semgrep

Choose Semgrep if you need its broader language catalog, mature cross-language rule DSL, registry, or hosted AppSec workflows.

For a detailed Semgrep vs Skylos comparison, see Semgrep vs Skylos for Python.


2. Bandit

Best for: Quick Python-only security scanning with zero configuration

Bandit is a long-running Python security analyzer maintained under PyCQA. It reports AST-based checks with severity, confidence, and CWE metadata and supports profiles, baselines, plugins, pre-commit, and CI use.

Strengths

  • Zero setup. Install and run. No config file needed.
  • Stable interface. Existing teams can keep familiar rule IDs, severity/confidence fields, baselines, and suppressions.
  • Maintained under PyCQA. It is part of the PyCQA project family.
  • Plugin system. You can write custom Bandit plugins.
  • Broad security coverage. Catches shell injection, SQL injection, weak crypto, pickle, YAML, eval, exec, and more.

Weaknesses

  • No general taint engine. Bandit can report dangerous call patterns without proving an interstatement source-to-sink flow.
  • No dead code detection. Security only.
  • No general framework entry-point model. Its individual security plugins recognize APIs rather than modeling dead-code reachability.
  • No interstatement data flow. B602 distinguishes literal from computed commands, but Bandit does not trace where a computed value came from.
  • Triage is repository-specific. Pattern findings can be valuable, but teams should measure how many require # nosec, configuration, or baseline handling in their own code.

Example severity distinction

# B602 reports this simple static command at LOW severity
subprocess.call("ls -la", shell=True)

Quick start

pip install bandit
bandit -r src/

When to choose Bandit

Choose Bandit if you want a focused Python security scanner, value its plugin and baseline formats, and already have separate tools for dead code and quality.

For a detailed comparison, see Bandit vs Skylos.


3. CodeQL

Best for: Deep semantic analysis on GitHub-hosted projects

CodeQL is GitHub's static analysis engine. It treats code as data — you write queries in CodeQL's query language (QL) to find patterns.

Strengths

  • Semantic analysis. CodeQL builds a database of your code and supports semantic, interprocedural, and data-flow queries over it.
  • GitHub-native. Results appear in GitHub code scanning; default setup can configure supported repositories without a hand-written workflow.
  • Taint analysis. Built-in data flow tracking across functions and files.
  • Standard and custom queries. GitHub maintains query suites, and users can add QL queries.

Weaknesses

  • Database build cost. CodeQL creates a source database, so measure its latency on your codebase before placing it in a fast local loop.
  • Specialized query language. Custom analysis requires learning QL and CodeQL's library model.
  • Limited dead-code coverage. CodeQL's Python quality queries flag unused imports, unused local/global variables and unreachable code, but not unused functions or classes across the whole program.
  • Code scanning is security-focused. GitHub now offers a separate Code Quality product with deterministic CodeQL quality rules and AI analysis, so "GitHub has no code-quality analysis" is no longer accurate. Code Quality became generally available on 20 July 2026 at $10 per active committer per month plus metered AI usage, on GitHub Team and Enterprise Cloud (not GHES); it costs nothing per committer on public repositories.
  • Private-repository licensing. CodeQL code scanning is available for public repositories; organization-owned private repositories require GitHub Code Security. GitHub Code Security costs $30 per active committer per month.

Quick start

Eligible repositories can enable CodeQL with GitHub's default setup. Advanced setup uses a workflow such as:

# .github/workflows/codeql.yml
name: CodeQL
on: [push, pull_request]

permissions:
  contents: read

jobs:
  analyze:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    permissions:
      contents: read
      actions: read
      security-events: write
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
        with:
          persist-credentials: false
      - uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
        with:
          languages: python
      - uses: github/codeql-action/analyze@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3

When to choose CodeQL

Choose CodeQL if you're on GitHub and want its semantic query model and supported cross-file data-flow analysis. Measure database-build time and confirm the licensing that applies to your repositories.


4. Vulture

Best for: Dedicated dead code detection in Python

Vulture is purpose-built for finding unused Python code. Its documented core records defined and used names from Python ASTs and reports candidates with confidence scores.

Strengths

  • Purpose-built. Focused entirely on dead code — unused functions, classes, imports, variables.
  • Focused. It has a small command surface for unused-code analysis.
  • Confidence scoring. Reports 60-100% confidence for each finding.
  • Integrations. The project documents a GitHub Action, pre-commit use, and a VS Code extension.

Weaknesses

  • Implicit uses require help. Vulture documents false positives for code that is used implicitly and provides whitelists, ignore decorators, and other controls.
  • No security scanning. Dead code only.
  • Iterative cleanup. Vulture's own documentation recommends running it again after deletion because more dead code may become visible. Skylos models call reachability in one analysis, though dynamic uses can challenge both tools.
  • Whitelist maintenance. Framework-heavy projects may need project-specific ignores or generated whitelists.

Example false positive

@app.route("/api/users")  # implicit registration can require an ignore/whitelist
def get_users():
    return jsonify(users)

@pytest.fixture  # implicit fixture use can require framework-aware handling
def db_connection():
    return create_connection()

Quick start

pip install vulture
vulture src/ --min-confidence 80

When to choose Vulture

Choose Vulture if you only need dead-code candidates, want confidence scoring, and are comfortable configuring implicit framework uses when they arise.

For reviewable upstream outcomes, see what happened when we sent dead-code cleanup PRs to mature Python projects.


5. Skylos

Best for: Python-focused teams wanting security + dead code + quality in one tool

Skylos combines dead-code, security, secrets, dependency, quality, and AI-defect checks. It is newer than the other tools and goes deepest on Python-specific reachability, frameworks, metrics, and flows; its other language analyzers have narrower, category-dependent coverage.

Strengths

  • Combined categories. Security, secrets, dead code, quality, AI defects, and supported dependency manifests can run in one scan.
  • Framework-aware Python reachability. Built-in models for Django, Flask, FastAPI, Pydantic, pytest, Celery, and Click reduce false positives for recognized entry points.
  • Taint analysis. Traces user input to dangerous sinks; the injection rules (for example SKY-D211, SKY-D212) fire only on traced input, while shell=True itself is always reported as SKY-D209.
  • Transitive dead code propagation. If A is dead and only A calls B, B is also flagged as dead.
  • AI-oriented checks. Dedicated rules cover registry-backed nonexistent dependencies, undeclared third-party imports, selected phantom security helpers, and missing members on statically resolvable local modules. Secrets and disabled-control patterns come from separate scanners, while selected removed controls are checked in Git diffs.
  • Generated CI/CD. skylos cicd init writes a GitHub Actions pull-request gate with PR comments that needs no Skylos account or API key. By default it also adds a "Skylos Cloud upload" job for pushes to your default branch, which fails until the Skylos GitHub App is installed; without Cloud, run skylos cicd init --no-upload.
  • Quality metrics. Cyclomatic complexity, coupling, cohesion, god classes, architecture metrics.

Weaknesses

  • Narrow custom-rule model. Python AST custom rules cover functions, classes, and calls locally and through Cloud. This is much less expressive and less multi-language than Semgrep or QL.
  • Newer ecosystem. Smaller community than Semgrep or Bandit.
  • Uneven language depth. Python has the deepest coverage; TypeScript/JavaScript and Java also get dead-code, security and quality checks, while PHP, Rust and Dart get dead-code and security checks. Go dead-code and security checks need the separately built skylos-go engine, which the Docker image and GitHub Action include but the PyPI package does not. C# is partial, Kotlin is dead code only, C++ is limited to unused file-local functions, and Shell is security only. Ruby and C are not supported. See language support.
  • Fewer security rules than Semgrep's full registry.
  • Bounded dependency coverage. SCA uses OSV for PyPI, npm, Go and NuGet. It reads uv.lock, poetry.lock, Pipfile.lock, package-lock.json/npm-shrinkwrap.json, pnpm-lock.yaml and yarn.lock, plus exact pins in requirements.txt, pyproject.toml, package.json and go.mod; it does not resolve version ranges and has no Maven, Gradle, Cargo or Composer support.

Quick start

pip install skylos
skylos . --danger --quality

When to choose Skylos

Choose Skylos if your codebase is primarily Python, its supported checks match your repository, and you want several analysis categories plus a generated GitHub Actions workflow. Validate its narrower language and dependency coverage before replacing specialized tools.

For more on what Skylos catches, see How to detect dead code in Python and AI-generated code security.


Tool combinations that work

Minimal setup (Python-only team)

pip install skylos
skylos . --danger --quality

One invocation enables security, dead-code, and quality checks for the supported files in the repository.

Maximum coverage (multi-language team)

# Semgrep for multi-language custom rules
- run: semgrep scan --config auto src/

# CodeQL for deep semantic analysis (needs init + analyze, as in the workflow above)
- uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
  with:
    languages: python
- uses: github/codeql-action/analyze@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3

# Skylos for its supported dead-code, AI-defect, and quality checks
- run: skylos . --danger --quality --ai-defects --github

Budget-friendly stack

# Bandit for security (free, established)
bandit -r src/

# Vulture for dead code (free, established)
vulture src/ --min-confidence 80

Two focused open-source tools. The trade-off is separate result streams and project-specific handling of implicit framework uses and security-pattern noise.


The 2026 context: AI-generated code

The biggest shift in Python static analysis in 2026 is AI-generated code. Teams using Copilot, Claude, and Cursor are generating more code faster — but with new failure modes:

  • Dependency mistakes — registry-backed nonexistent packages and undeclared third-party imports
  • Verified missing references — selected security helpers and missing members on statically resolvable local modules
  • Hardcoded credentials — AI tools inline secrets for "working examples"
  • Disabled security — verify=False, debug=True
  • Dead code accumulation — abandoned AI-generated drafts

These patterns cross several scanner categories. Bandit, Semgrep, and CodeQL can catch many underlying security patterns; Semgrep and CodeQL can be extended with custom rules or queries. Skylos adds registry-backed dependency checks, missing-member checks for resolvable local module surfaces, selected security-helper checks, heuristic Git provenance, and a selected removed-control diff rule. Hardcoded credentials and unsafe options are ordinary secrets/security findings rather than proof of AI authorship.

If your team uses AI coding tools heavily, factor this into your tool choice. See How to catch hallucinated imports in AI-generated Python code for more detail.


Summary

NeedBest tool
Multi-language securitySemgrep
Simplest Python security scanBandit
Deep semantic analysis (GitHub)CodeQL
Dedicated dead code finderVulture
Python security + dead code + quality + AI codeSkylos
Broad custom rule authoringSemgrep or CodeQL
Focused Python AST conventionsSkylos custom rules
Framework-aware dead code (fewer manual whitelists for recognized frameworks)Skylos
Generated GitHub Actions workflow with PR commentsSkylos
Enterprise security programSemgrep AppSec Platform

Pick the tool that matches your primary need. Start with the highest-risk gap, then expand coverage based on measured misses and triage cost.

If your team is deciding between two specific options, these follow-up pages are better than staying on a broad list:

If you want to stop researching and test the workflow directly:

pip install skylos
skylos . -a


Try Skylos

If you want one tool that covers security, dead code, and quality for Python:

pip install skylos
skylos . --danger --quality

No signup is required for a local CLI scan; runtime depends on repository size and enabled checks. View on PyPI | Read the docs


All tools mentioned are open source or have free tiers. Semgrep | Bandit | CodeQL | Vulture | Skylos | Skylos Docs