Thanks to visit codestin.com
Credit goes to docs.skylos.dev

Skip to main content

Case Studies

Skylos was benchmarked against Vulture on 9 of the most popular Python repositories on GitHub — 350k+ combined stars. Every finding was manually verified against the source code.

Results Summary

RepositoryStarsDead ItemsSkylos TPSkylos FPVulture TPVulture FP
requests53k6635658
click17k77866
starlette10k11412
rich51k131314108
httpx14k006059
flask69k77126260
pydantic23k11119310112
fastapi82k66304102
tqdm30k1018137
Total525122044644
MetricSkylosVulture
Recall98.1% (51/52)84.6% (44/52)
False Positives220644

Skylos finds 7 more dead items with 3x fewer false positives.

Why These Repos?

Each repository stress-tests dead code detection differently:

RepositoryWhat It Tests
requests__init__.py re-exports, Sphinx conf, pytest classes
clickIO protocol methods (io.RawIOBase subclasses), nonlocal closures
starletteASGI interface params, polymorphic dispatch, public API methods
rich__rich_console__ protocol, sentinel vars via f_locals, metaclasses
httpxTransport/auth protocol methods, zero dead code (pure FP test)
flaskJinja2 template globals, Werkzeug protocol methods, extension hooks
pydanticMypy plugin hooks, hypothesis @resolves, __getattr__ config
fastapi100+ OpenAPI spec model fields, Starlette base class overrides
tqdmKeras/Dask callbacks, Rich column rendering, pandas monkey-patching

No repo was excluded for having unfavorable results.

Deep Dives

Flask (69k stars)

Ground truth: 1 unused function, 2 unused variables, 4 unused classes

Vulture produces 260 false positives on Flask because it flags every Jinja2 template global, Werkzeug protocol method, and Flask extension hook. Skylos recognizes Flask/Werkzeug patterns and reduces this to 12 FP.

Key challenges:

  • Decorator-based route registration (@app.route)
  • Public API extensions via __init__.py
  • Pytest fixture injection
  • Test config variables loaded via app.config.from_object

FastAPI (82k stars)

Ground truth: 4 unused variables, 2 unused imports

Vulture flags 102 false positives — mainly OpenAPI spec model fields (Pydantic BaseModel attributes like maxLength, exclusiveMinimum). Skylos understands these as schema definitions.

Key challenges:

  • Starlette interface requirements (req, receive, send parameters)
  • Pydantic model fields used by OpenAPI spec generation
  • Re-exports and compatibility layers

Pydantic (23k stars)

Ground truth: 2 unused functions, 7 unused variables, 2 unused classes

Key challenges:

  • mypy plugin hooks
  • __getattr__ dynamic dispatch for config access
  • TYPE_CHECKING imports
  • Deprecated exports and version-specific code
  • Hypothesis plugin registration

httpx (14k stars)

Ground truth: 0 dead items — a clean codebase with zero dead code.

This is a pure false positive test. Vulture reports 59 FP, Skylos reports 6 FP. Every flagged item is actually used through transport/auth protocol methods, IntEnum members, or conditional imports.

Rich (51k stars)

Ground truth: 1 unused function, 9 unused variables, 2 unused classes

Key challenges:

  • __rich_console__ protocol methods
  • Sentinel variables accessed via locals() introspection
  • Jupyter protocol methods (_repr_html_, _repr_mimebundle_)
  • Logging handler protocol (emit)

Requests (53k stars)

Ground truth: 5 unused functions, 1 unused variable

Key challenges:

  • Public API re-exports through __init__.py
  • Sphinx conf.py variables (consumed by execfile)
  • Test fixtures and pytest classes
  • __init__.py re-export chains

tqdm (30k stars)

Ground truth: 1 unused function (deprecated, scheduled for removal in v5.0)

Key challenges:

  • Framework callbacks (logging.Handler.emit, Dask/Keras/Rich)
  • IPython/Jupyter protocol methods
  • Thread protocol methods (daemon, run)
  • Backward-compatibility re-exports

Skylos misses the 1 dead function because it suppresses __init__.py definitions as potential re-exports — a deliberate conservative tradeoff.

Where Skylos Loses (Honestly)

  • click (8 vs 6 FP): IO protocol methods on io.RawIOBase subclasses
  • starlette (4 vs 2 FP): Instance method calls across files not fully resolved
  • tqdm (0 vs 1 TP): Skylos misses 1 dead function in __init__.py

We include repos where Vulture beats Skylos.

Reproduce

cd real_life_examples/{repo}
python3 ../benchmark_{repo}.py

Full methodology and per-repo breakdowns in the skylos-demo repository.