Skip to main content

Your code says what it should do. Quell proves it.

Project description

quelltest

Your code says what it should do. Quell proves it.

PyPI Python License: MIT

Quell reads your production code directly — every if/raise, null check, and guard clause is a requirement written in Python. It finds the ones with no test, generates a failing test that proves the gap exists, then optionally suggests a fix and verifies the fix works. No docstrings needed. No Pydantic needed. Just code.

Why Quell is different

Tool Finds logic gaps Generates failing test Suggests fix Verifies fix works
Snyk security only
Semgrep security only
CodeRabbit PR review
Corgea logic + auth auto-PR
Quell guard clauses ✅ verified ✅ LLM ✅ two-phase

The exact gap Quell fills: Nobody generates a failing test that proves a logic gap exists, then suggests a fix, then verifies the test passes after the fix.

How it works

STEP 1 — FIND (no LLM, no network)
  Read production code via AST
  Detect: if/raise, null checks, auth guards, bare excepts, silent failures
  Every guard clause is a requirement

STEP 2 — PROVE (no LLM for rule-based gaps)
  Generate a failing test that proves the gap exists
  Test MUST fail on current code (proves vulnerability is real)

STEP 3 — FIX (LLM, only on request with --suggest)
  LLM suggests a code change
  Shows diff — never auto-applies
  Test MUST pass after applying the fix
  If test still fails: fix is rejected

Installation

pip install quelltest

Requires Python 3.11+. The CLI command is quell.

Commands — which use the LLM and which don't

quell scan — primary command (v0.6.0+)

Reads if/raise patterns directly. Works on any Python file.

# Find all untested guard clauses — NO LLM, no network
quell scan src/

# Generate failing tests for each gap — NO LLM for rule-based gaps
quell scan src/ --fix

# Also suggest code fixes via LLM — USES LLM (requires API key or quell auth login)
quell scan src/ --fix --suggest

# Force rule-based only, zero network calls
quell scan src/ --no-llm

When does quell scan use the LLM?

  • --fix alone: no LLM — rule engine handles boundary, null, enum, type, auth checks
  • --fix --suggest: LLM used for generating fix suggestions only
  • --no-llm: never — skips any LLM step

quell check — for docstring/type annotation users

For codebases that have structured docstrings or Pydantic models.

# Find requirement gaps from docstrings + types — NO LLM
quell check src/

# Generate verified tests — NO LLM (rule engine handles standard constraints)
quell check src/ --fix

# Force rule-based only
quell check src/ --no-llm

# For code without docstrings/types, use scan instead:
quell scan src/

Other commands

# Reproduce a bug from a plain English description — USES LLM
quell reproduce "payment accepts zero amount"

# Show coverage score for a file — NO LLM
quell prove src/payments.py

# Project-wide Quell Score with SVG badge — NO LLM
quell score --badge

# CI mode: fail if score below threshold — NO LLM
quell ci src/ --threshold 0.8

# Analyze a GitHub PR — NO LLM
quell pr 42
quell pr 42 --comment   # post result as PR comment

# Auth (only needed for LLM features)
quell auth login
quell auth status

Quick start — production code (no docstrings needed)

Given any Python file with guard clauses:

def process_payment(amount, currency, user):
    if amount <= 0:
        raise ValueError("Amount must be positive")
    if user is None:
        raise ValueError("User required")
    if currency not in ["USD", "EUR", "GBP"]:
        raise ValueError("Invalid currency")
    return charge(amount)
# Find untested guards — no API key needed
quell scan payments.py

Output:

Quell Scan — reading guard clauses in 1 file(s)
No docstrings needed. Reading your if/raise patterns.

Logic Gaps Found (3 untested / 3 total)
┌────────────┬─────────────────┬──────────────────────────┬──────────┬──────────────────────┐
│ File       │ Function        │ Guard Clause             │ Type     │ Method               │
├────────────┼─────────────────┼──────────────────────────┼──────────┼──────────────────────┤
│ pay.py     │ process_payment │ if amount <= 0:          │ boundary │ [rule-based, no net] │
│ pay.py     │ process_payment │ if user is None:         │ not_null │ [rule-based, no net] │
│ pay.py     │ process_payment │ if currency not in [...] │ enum     │ [rule-based, no net] │
└────────────┴─────────────────┴──────────────────────────┴──────────┘

Run: quell scan payments.py --fix   → generate failing tests
# Generate + verify failing tests — still no API key needed
quell scan payments.py --fix

Quick start — docstrings and Pydantic (legacy check command)

class PaymentRequest(BaseModel):
    amount: float = Field(gt=0)
    currency: Literal["USD", "EUR", "GBP"]
quell check src/payments.py        # find gaps
quell check src/payments.py --fix  # generate verified tests

Configuration

quell init   # adds [tool.quell] to pyproject.toml
[tool.quell]
llm_provider = "anthropic"          # "anthropic" | "openai" | "ollama" | "none"
llm_model    = "claude-sonnet-4-5"
enable_docstring = true
enable_types     = true
enable_mutations = false
auto_write       = false

LLM API key — only needed for --suggest and quell reproduce:

export ANTHROPIC_API_KEY=sk-ant-...
# or
export OPENAI_API_KEY=sk-...
# or login via browser (stores token locally)
quell auth login

For fully offline use, use Ollama or --no-llm:

# pyproject.toml: llm_provider = "ollama"
# ollama pull codellama
quell scan src/ --no-llm   # zero network, always works

What each constraint type means

Type Detected from Example
boundary if x <= 0: raise / assert x > 0 amount must be positive
not_null if x is None: raise user must not be None
enum_valid if x not in [...]: raise currency must be USD/EUR/GBP
type_check if not isinstance(x, T): raise amount must be numeric
auth_check if not user.is_authenticated: raise login required
bare_except except: catches all errors silently
silent_fail if not x: return None fails silently instead of raising
magic_value if status == "admin": hardcoded string in condition

Python SDK

from quell import Quell

q = Quell()

# Find requirement gaps (no LLM)
result = q.check("src/")
print(f"Score: {result.score:.0%} | Gaps: {len(result.uncovered)}")

# Reproduce a bug (uses LLM)
q.reproduce("payment accepts zero amount silently")

# Project score (no LLM)
score = q.score()
print(f"Project: {score.percentage}%")

Project structure

quell/
├── cli.py              # Typer CLI: scan, check, reproduce, prove, score, ci, pr, auth
├── sdk.py              # Python API: Quell class
├── spec/
│   ├── code_guard_reader.py   # PRIMARY: reads if/raise patterns (v0.6.0+)
│   ├── docstring_reader.py    # reads docstring Raises:/Returns: blocks
│   ├── type_reader.py         # reads Pydantic Field constraints
│   └── bug_reader.py          # reads natural language bug descriptions
├── fix/
│   └── suggester.py    # LLM fix suggester (only after test proves gap)
├── core/
│   ├── models.py       # Requirement, ConstraintKind, VerificationResult
│   ├── verifier.py     # THE MOAT — proves every test catches violations
│   └── writer.py       # libcst injection, backup/restore
├── coverage/           # AST-based coverage checker
├── synthesis/          # rule_engine.py + llm_engine.py
├── score/              # Quell Score calculator + SVG badge
└── llm/                # Anthropic / OpenAI / Ollama providers

Development

git clone https://github.com/shashank7109/quelltest_lib.git
cd quelltest_lib
uv sync --dev

uv run pytest tests/ -v
uv run ruff check . --fix
uv run mypy quell/

# Test quell scan on itself (no LLM)
uv run quell scan quell/ --no-llm

Related

License

MIT — see LICENSE

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quelltest-0.6.2.tar.gz (272.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

quelltest-0.6.2-py3-none-any.whl (94.6 kB view details)

Uploaded Python 3

File details

Details for the file quelltest-0.6.2.tar.gz.

File metadata

  • Download URL: quelltest-0.6.2.tar.gz
  • Upload date:
  • Size: 272.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for quelltest-0.6.2.tar.gz
Algorithm Hash digest
SHA256 57592fed9bbab9c0673e7ff54b9f790fd7e5b719418c3c11fb2473cefd5711d1
MD5 7c7678512cd3e25f0c29c5df12ad7214
BLAKE2b-256 b885ec83ea9eac7e65cb810d6011492d07cca606bc86dead040e658da4b58907

See more details on using hashes here.

File details

Details for the file quelltest-0.6.2-py3-none-any.whl.

File metadata

  • Download URL: quelltest-0.6.2-py3-none-any.whl
  • Upload date:
  • Size: 94.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for quelltest-0.6.2-py3-none-any.whl
Algorithm Hash digest
SHA256 9bc9f3446126f70c91b85af5b6b02731bc575077a598b63d9bafe74ecd03b18e
MD5 4965363df4e91f1543019759b1d477b1
BLAKE2b-256 6c959eab52a4c474888cfa0fb488a6a7db6a2285c2799aed09e633dad090da65

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page