A Pylint-style scoring system for Ruff linter output
Project description
Ruff Score 🎯
A Pylint‑style scoring system for Ruff linter output. Get a numerical quality score (0‑10) for your Python code based on Ruff's analysis, with fine‑grained rule mapping and customizable severity weights.
Features
- 🎯 Pylint‑inspired scoring: A familiar 0‑10 quality score, but improved to be more sensitive to real issues.
- 🔧 Ruff integration: Built on the fast Ruff linter – just point it at a file or directory.
- 🗂️ Full rule coverage: Every Ruff prefix (E, F, PLE/PLC/PLR/PLW, ASYNC, S, TRY, RUF, and 40+ more) is mapped to a Pylint‑style category and severity weight.
- ⚖️ Two‑level weighting: Issues are bucketed into
error/warning/convention/refactor, and within a category individual rules can carry different weights (e.g. a security finding counts more than a strayprint). - 📊 Per‑file averaging: Directory scores are the average of each file’s score – so a few problem files can’t hide behind a pile of clean code.
- 📁 File & directory support: Analyze single files or whole projects.
- ⚙️ Configurable: Use your existing Ruff configuration file, and override weights/categories in Python.
Installation
pip install ruff-score
Quick Start
from ruff_score import RuffScorer
scorer = RuffScorer()
# Score a single file
result = scorer.score_file("myfile.py")
print(f"Score: {result['score']:.2f}/10.00")
# Score a directory (averages per‑file scores)
result = scorer.score_directory("src/")
scorer.print_report(result)
# Score against a specific Ruff config
result = scorer.score_directory("src/", config_file="pyproject.toml")
How It Works
Ruff Score uses the Pylint‑style formula, but with a more sensitive penalty:
Score = 10.0 - ((error_multiplier * errors + warnings + refactor + convention) / denominator * 10)
Where:
denominator is the number of non‑blank, non‑comment lines of code (by default). This makes each issue affect the score more than counting AST statements. You can switch back to statement counting by passing use_lines=False to the constructor.
error_multiplier is configurable and defaults to 10 (was 5 in the original Pylint formula). This amplifies the impact of real bugs.
Score Interpretation:
9.0‑10.0: Excellent code quality (10.0 means no issues at all
7.0‑8.9: Good code quality
5.0‑6.9: Needs improvement
0.0‑4.9: Poor code quality
Example Output
==================================================
RUFF QUALITY SCORE REPORT
==================================================
Target: src/
Score: 7.85/10.00
Total lines analyzed: 1,247
Files analyzed: 23
Total issues: 12
Issues by category:
Error: 0
Warning: 3
Convention: 8
Refactor: 1
Good code quality
Advanced Usage
Custom Weights and Categories
from ruff_score import RuffScorer
# Change the fallback used for any rule prefix not in the tables
scorer = RuffScorer(default_weight=2, default_category="warning")
# Override the weight or category for a specific prefix
scorer.RULE_WEIGHTS["D"] = 1 # docstring issues
scorer.RULE_CATEGORIES["D"] = "convention"
# Adjust the error multiplier (default is 10)
scorer.error_multiplier = 15
# Switch to statement‑based denominator (AST nodes)
scorer.use_lines = False
# Inspect how a given rule code resolves
scorer.get_rule_weight("S608") # -> 4
scorer.get_rule_category("S608") # -> "warning"
Integration with CI/CD
# check_quality.py
import sys
from ruff_score import RuffScorer
scorer = RuffScorer()
result = scorer.score_directory("src/")
scorer.print_report(result)
THRESHOLD = 7.0
sys.exit(0 if result["score"] >= THRESHOLD else 1)
bash
python check_quality.py && echo "Quality check passed!" || echo "Quality check failed!"
Configuration
Ruff Score respects your existing Ruff configuration by passing it straight through to ruff check --config. Place your settings in:
- pyproject.toml
- ruff.toml
- .ruff.toml
Example configuration:
[tool.ruff]
line-length = 88
target-version = "py38"
[tool.ruff.lint]
select = ["E", "F", "W", "C", "N", "D", "S", "B"]
ignore = ["E501", "D100"]
Requirements
- Python 3.8+
- Ruff installed and available on your PATH
License
MIT License – see LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Related Projects
Ruff – The fast Python linter Pylint – The original Python code quality tool
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ruff_score-0.2.1.tar.gz.
File metadata
- Download URL: ruff_score-0.2.1.tar.gz
- Upload date:
- Size: 43.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"CachyOS Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03606fced6db0526e5afdc434eb3c5d68175afbc49e4efb31299ad0882cf3c87
|
|
| MD5 |
0a90d6ef5adcf9fa7dabe695c707d7fb
|
|
| BLAKE2b-256 |
8efc9a20d3531fd3297efc884ff3ce6e6ae16fbc21021c1a5b17cd09b64fd69a
|
File details
Details for the file ruff_score-0.2.1-py3-none-any.whl.
File metadata
- Download URL: ruff_score-0.2.1-py3-none-any.whl
- Upload date:
- Size: 10.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"CachyOS Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31c62a949e0f602e9777622a3a16350ea2a00eed29c13f9eff6d9cfd86056507
|
|
| MD5 |
77ada1f164d4ff51eb5024f3afe57eda
|
|
| BLAKE2b-256 |
4cfe59a75184bb648737ab8338875a0e48d92a76c13f268624ef6f14f8388a58
|