Skip to main content

tingle

Spider-sense for refactoring: you know that tingle — the itch that says the codebase isn't right yet. This tool puts a number on it, so you can watch it drop.

Code metrics for the era of constant refactoring.

tingle measures things you want to shrink (or watch) while refactoring a codebase: ignored lint rules, inline # noqa / # type: ignore comments, uses of a legacy class during a strangler-fig migration, lines of code in a package that should disappear.

It runs once, prints the numbers, and stores nothing. To watch a number over months, the metrics-history action records a point per commit that lands and publishes a chart of them.

📖 Documentation: https://tingle.fancysnake.dev/

Install

pip install tingle

Quick start

tingle init                                    # starter tingle.toml
tingle library                                 # ready-made metrics for known tools
tingle add --base tingle.builtins.ruff.noqa_comment
tingle add regex_count '#\s*noqa'              # or state one yourself
tingle add toml_list_length tool.ruff.lint.ignore --name ruff-ignores
tingle                                         # interactive mode (on a terminal)
tingle stat                                    # summary table
tingle stat --json                             # machine-readable output
tingle stat --diff                             # impact of the current branch
tingle report                                  # every occurrence, file:line
tingle report --diff                           # what the branch added/removed
tingle report --group linting                  # one group, or --metric NAME

Metrics are declared in tingle.toml (or a [tool.tingle] section in pyproject.toml):

[ranges.python]
include = ["src/**/*.py", "tests/**/*.py"]
default = true

[[metrics]]
name = "noqa-comments"
type = "regex_count"
pattern = '#\s*noqa'

You can count regex matches, uses of a Python symbol, entries in a TOML or INI list (this is how you count ignored lint rules), files, and lines. See the metric types.

For the tools everyone already runs there are ready-made definitions, so a metric can name one and override only what differs:

[[metrics]]
base = "tingle.builtins.ruff.noqa_comment"
extra_ignore_lines = ['# @generated']

They live in an ordinary Python package, so your team can publish its own. See the template library.

What it does

Three things, in rising order of opinion:

  • Measure. tingle stat counts what you told it to count and prints the numbers. Metric values never affect the exit code — tingle measures, it does not judge.
  • Attribute. tingle stat --diff measures only what the current branch changed, against the merge-base with a base branch, so commits that landed on the base after you branched don't pollute your numbers.
  • Judge. tingle check is the CI gate: the same branch measurement, but it exits 1 if the branch made things worse, so a pull request that takes on debt fails the build.
$ tingle check
noqa-comment (regex_count): +2
  + src/api/views.py:23
  + src/api/views.py:41

$ echo $?
1

Documentation

Development

Python 3.11–3.14 are supported (CI runs the full matrix). The project uses mise + Poetry.

mise install
poetry install
mise run test:py      # tests
mise run lint:py      # ruff, mypy, pylint, import-linter
mise run docs:serve   # preview the docs site

See contributing for the GLIMPSE source layout and the layer contracts.

License

MIT.

Metadata

Release files for tingle 0.8.0

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

Source distribution (sdist)

Source distribution for tingle 0.8.0
File Size Uploaded Provenance Actions
tingle-0.8.0.tar.gz 92.4 kB With provenance Details for tingle-0.8.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for tingle 0.8.0
File Interpreter ABI Platform Actions
tingle-0.8.0-py3-none-any.whl Python 3 none any Details for tingle-0.8.0-py3-none-any.whl

Total release size: 211.5 kB

Release files / tingle-0.8.0.tar.gz

Download URL tingle-0.8.0.tar.gz
Size 92.4 kB
Tags Source
SHA-256 checksum
How to use checksums
bd3ba8b321f66a93b196b3c1673527434f37061b83b50e7cc310d501db5898f2
BLAKE2b-256 checksum
How to use checksums
cea39a8ec94a31a46d8b7aa13b731fbc6618b1121f8459c4a8695144bcc411da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 28, 2026.

Transparency log

Release files / tingle-0.8.0-py3-none-any.whl

Download URL tingle-0.8.0-py3-none-any.whl
Size 119.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7e1cd664988772ba35bea6aa90abc68e6332f6dea70107baa569dc64d4553196
BLAKE2b-256 checksum
How to use checksums
8a85b1e3938479b50ed097db53e158c040a821aea66497da7a885ef92404cfd6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 28, 2026.

Transparency log

Security for tingle 0.8.0

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.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for tingle-0.8.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 28, 2026.

Transparency log

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.

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