Skip to main content

Pylon

Pylon is a static analysis CLI for Python that flags real issues in your code and, on request, explains them and suggests fixes using an LLM.

Pylon mostly utilises Python's included ast module to traverse source code.

Built in collaboration with Soham200613 and GraydenDonaldson

Implemented rules

  • Unused imports: imports that are never referenced. Correctly handles Python's re-export idioms (from .app import Flask as Flask, __all__ = [...]) so it doesn't flag deliberate public re-exports as dead code.

  • Mutable default arguments: def f(x=[]) shares the same object across every call, a classic source of hard-to-trace bugs. Catches both literal syntax ([], {}) and constructor calls (list(), dict(), set()).

  • Bare except: clauses: catching all exceptions, including KeyboardInterrupt and SystemExit, silently swallows bugs. Recognizes and skips the deliberate catch-and-reraise pattern (except: ... raise), rather than flagging every bare except indiscriminately.

  • Wildcard imports: from module import * pollutes the namespace and makes it impossible to tell where a name came from.

  • Comparing with == instead of is for None/True/False — non-idiomatic and can misbehave with custom __eq__. Check ast.Compare nodes where one side is an ast.Constant with value None/True/False and the operator is Eq/NotEq.

  • Shadowed funcions/methods/class definitions: functions later shadowed without an @overload stub and other exceptions are silently shadowed by python

  • Shadowed builtins: parameters and variable bindings named list, dict, id, type, etc. hide Python's builtins. Attribute names and ordinary builtin references are not flagged.

Rules yet to be implemented

  • Excessive function arguments: functions with too many parameters are hard to maintain and often signal the function is doing too much.
  • Unused function arguments: parameters never referenced in the function body, often signaling incomplete refactoring. Same "walk and collect ast.Name usages" pattern as unused imports, applied per-function.
  • Global variable mutation inside functions: using global to mutate outer-scope state is a common source of hard-to-trace bugs. Check for ast.Global nodes within functions.
  • Deeply nested code (high cyclomatic complexity): functions with many nested if/for/while/try blocks are hard to read and test. Requires tracking nesting depth/branch count while walking, rather than matching a single node type.
  • Redefining function in same scope: functions that are later redefined in the same scope silently shadow, hinting to dead code
  • Format-string arg count mismatch: % operator and logging calls with a mismatch in the number of format requests and args supplied

LLM layer

Passing --explain sends each finding, along with its surrounding source code, to an LLM for a short, specific judgment on whether it's a genuine issue or a likely false positive. This is deliberately kept separate from the deterministic rule engine: rules encode patterns worth hard-coding that have few special deliberate cases, while the LLM layer handles judgment calls that don't generalize cleanly into a fixed rule. For example, correctly identifying that an unused from __future__ import annotations import is not actually dead code, despite never appearing as a referenced name in its respective file.

Supports multiple providers behind a shared interface — local models via ollama for fast, free iteration, or Anthropic/OpenAI for production-quality explanations:

pylon path/to/file.py --explain --provider ollama   # default
pylon path/to/file.py --explain --provider anthropic
pylon path/to/file.py --explain --provider openai
pylon path/to/file.py --explain # will use default ollama qwen2.5:7b-coder

Note that users of OpenAI/Anthropic models should configure their API keys by following the Configuration section above.

Installation, as PyPI package

Plain installation without external provider support ie. Ollama only

pip install pylon-analyzer

To install specific or all providers,

# Just Anthropic
pip install "pylon-analyzer[anthropic]"
# Just OpenAI
pip install "pylon-analyzer[openai]"
# Just Google
pip install "pylon-analyzer[google]"
# Full provider support
pip install "pylon-analyzer[llm-all]"

Installation, from source

git clone https://github.com/Anonymoose725/pylon.git
cd pylon
python3 -m venv .venv
source .venv/bin/activate # for linux/mac, or .venv\Scripts\activate on Windows
pip install -r requirements.txt

Minimal install (Ollama only, no API keys required)

pip install -e ".[ollama]"

Full install with all LLM providers

pip install -e ".[llm-all]"

Or install specific providers

# Just OpenAI
pip install -e ".[openai]"
# Just Anthropic  
pip install -e ".[anthropic]"

Configuration: Set Up Environment Variables

After installation, you'll need to configure environment variables for LLM API access:

  1. Copy the example file: Rename .env.example to .env.local first to review the template, then rename it to .env:

    cp .env.example .env.local  # Review what needs to be set
    mv .env.local .env          # Now you can edit it safely
    
  2. Edit .env: Add your API keys to the .env file:

    nano .env  # or use your preferred editor
    
  3. Load environment variables (if your shell doesn't auto-source):

    source .env  # Linux/mac, or .venv\Scripts\activate.ps1 for Windows
    

Detailed setup, for contributors

Clone the repo:

git clone https://github.com/Anonymoose725/pylon.git
cd pylon

Create and activate a virtual environment:

python3 -m venv .venv
source .venv/bin/activate

Install dependencies from requirements.txt:

pip install -r requirements.txt

Run the test suite to confirm everything works:

pytest testing/ -v

Optional: Configure LLM API keys by following the Configuration section. The tests will run with Ollama by default (no API keys needed) unless you've installed other providers and set up .env.

Milestones & metrics

Validated against 5 actively maintained production codebases to confirm the tool works at real scale and to catch genuine false-positive patterns before they'd be found by an actual user.

Repo Files Lines Findings
Flask 24 9,513 32
Requests 19 6,394 56
Click 17 12,821 19
Django 907 165,529 198
NumPy 428 260,868 764
Total 1,395 455,125 1,069
  • Reduced false-positive unused-import findings by 34% (1,479 → 976) by diagnosing and fixing two Python re-export idioms (from x import Y as Y and __all__ re-exports) that the AST-based detector initially misread as dead code
  • Correctly identified a genuine bare-except anti-pattern in Flask's core WSGI dispatch logic (app.py), then refined the rule to distinguish safe catch-and-reraise handlers from true error suppression via AST-level exception analysis
  • Processes ~365 files/sec (Django) and remains performant on dense, large codebases (~83 files/sec on NumPy's 260K-line source tree due to larger file sizes)
  • Every rule is covered by positive and negative test cases (pytest) — proving each rule catches real issues without false-flagging safe, idiomatic code
  • Uploaded to PyPI, where now users can 'pip install pylon-analyzer' on any system!

Roadmap

  1. Implement the roadmap rules listed above!
  2. Implement a --fat flag that assumes a user is testing on a large number of files/repos, compacting the large list of findings into a more digestible (and collapsible?) format, potentially outside the CLI
  3. Add a false-positive flagging mechanism to the CLI, so users can mark findings as false positives, with and without having seen an --explain explanation first. This is the basis for measuring whether the LLM layer's context genuinely reduces false-positive flags in practice

Metadata

Release files for pylon-analyzer 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pylon-analyzer 0.1.1
File Size Uploaded Provenance Actions
pylon_analyzer-0.1.1.tar.gz 18.3 kB Without provenance Details for pylon_analyzer-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pylon-analyzer 0.1.1
File Interpreter ABI Platform Actions
pylon_analyzer-0.1.1-py3-none-any.whl Python 3 none any Details for pylon_analyzer-0.1.1-py3-none-any.whl

Total release size: 38.2 kB

Release files / pylon_analyzer-0.1.1.tar.gz

Download URL pylon_analyzer-0.1.1.tar.gz
Size 18.3 kB
Tags Source
SHA-256 checksum
How to use checksums
3321527663f5b867d0391292b630c17c35405647797c91ba1e6aed5491646fbe
BLAKE2b-256 checksum
How to use checksums
35084ca165e0b23c2de45cbe22d03cf5423856aa9179b64b353b3b93a865c4b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.2

Release files / pylon_analyzer-0.1.1-py3-none-any.whl

Download URL pylon_analyzer-0.1.1-py3-none-any.whl
Size 19.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5055103056b2c4a59d911d1a0d6495417235d95bf45e2fee4d770338520963d6
BLAKE2b-256 checksum
How to use checksums
458f11aff3550e4175a150f8854b50b6e03aa2942176934c9add2c641f3cd70e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.2

Security for pylon-analyzer 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page