astral-sh/ruff
An extremely fast Python linter and code formatter, written in Rust.
The score is jscpd's own --health model: markup, data and text left out, tests kept. The numbers below are the trending scan's.
Most complex files
- crates/ruff_python_ast/src/generated.rs3411 cx
- crates/ty_python_semantic/src/types.rs1914 cx
- crates/ty_python_semantic/src/types/infer/builder.rs1793 cx
- crates/ruff_linter/src/rules/ruff/rules/confusables.rs1586 cx
- crates/ty_python_semantic/src/types/call/bind.rs1469 cx
- crates/ruff_linter/src/codes.rs1027 cx
- crates/ty_python_semantic/src/types/display.rs900 cx
- crates/ty_python_semantic/src/types/signatures.rs888 cx
- crates/ty_ide/src/completion.rs878 cx
- crates/ty_python_semantic/src/types/narrow.rs815 cx
Dead code 6.18% unused · 601 findings
- crates/ruff_benchmark/resources/large/dataset.pyunused-file
- crates/ruff_benchmark/resources/pydantic/types.pyunused-file
- crates/ruff_benchmark/resources/numpy/ctypeslib.pyunused-file
- crates/ty_vendored/ty_extensions/_internal.pyiunused-file
- crates/ruff_python_parser/resources/valid/statement/match.pyunused-file
- crates/ruff_benchmark/resources/typeis_narrowing.pyunused-file
- crates/ty_vendored/ty_extensions/__init__.pyiunused-file
- crates/ruff_python_parser/resources/valid/statement/function.pyunused-file
- scripts/generate_known_standard_library.pyunused-file
- crates/ruff_python_parser/resources/valid/statement/ambiguous_lpar_with_items.pyunused-file
The code number leaves out tests, fixtures, docs, examples, data files, styles, translations and vendored code, and 3 generated files: crates/ruff_linter/src/rules/ruff/rules/confusables.rs, crates/ruff_python_stdlib/src/sys/builtin_modules.rs, crates/ruff_python_stdlib/src/sys/known_stdlib.rs.
Largest clones in the code
- 6 lines in 26 placesrust54 tokenscrates/ruff_workspace/src/options.rs:1203–1208crates/ruff_workspace/src/options.rs:1313–1318crates/ruff_workspace/src/options.rs:1342–1347crates/ruff_workspace/src/options.rs:1374–1379crates/ruff_workspace/src/options.rs:1479–1484and 21 more
1203#[derive( 1204 Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, 1205)] 1206#[serde(deny_unknown_fields, rename_all = "kebab-case")] 1207#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] 1208pub struct Flake8BanditOptions {1313#[derive( 1314 Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, OptionsMetadata, CombineOptions, 1315)] 1316#[serde(deny_unknown_fields, rename_all = "kebab-case")] 1317#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] 1318pub struct Flake8BooleanTrapOptions { - 19 lines in 7 placesrust190 tokenscrates/ty_ide/src/hover.rs:2755–2773crates/ty_ide/src/hover.rs:3037–3055crates/ty_ide/src/hover.rs:3071–3089crates/ty_ide/src/hover.rs:3105–3123crates/ty_ide/src/hover.rs:3139–3157and 2 more
2755class MyClass: 2756 """some docs""" 2757"#, 2758); 2759 2760assert_snapshot!(test.hover(), @r#" 2761MyClass 2762--------------------------------------------- 2763some docs 2764First 10 of 19 lines.
- 219 lines in 2 placesrust1,069 tokenscrates/ruff_python_ast/src/visitor.rs:136–354crates/ruff_python_ast/src/visitor/transformer.rs:123–341
136match stmt { 137 Stmt::FunctionDef(ast::StmtFunctionDef { 138 parameters, 139 body, 140 decorator_list, 141 returns, 142 type_params, 143 .. 144 }) => { 145 for decorator in decorator_list {First 10 of 219 lines.
7 more
- 7 lines in 15 placesrust71 tokens
- 22 lines in 11 placesrust95 tokenscrates/ty_server/src/server/api/requests/doc_highlights.rs:31–52crates/ty_server/src/server/api/requests/goto_declaration.rs:30–51crates/ty_server/src/server/api/requests/goto_definition.rs:31–52crates/ty_server/src/server/api/requests/goto_implementation.rs:30–51crates/ty_server/src/server/api/requests/goto_type_definition.rs:31–52and 6 more
- 301 lines in 2 placesrust922 tokens
- 7 lines in 19 placesrust50 tokenscrates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_abspath.rs:1–7crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_basename.rs:1–7crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_dirname.rs:1–7crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_exists.rs:1–7crates/ruff_linter/src/rules/flake8_use_pathlib/rules/os_path_expanduser.rs:1–7and 14 more
- 12 lines in 13 placesrust63 tokens
- 14 lines in 11 placesrust73 tokens
- 153 lines in 2 placesrust717 tokens
Largest clones over all files, tests and data included
- 21 lines in 3 placesrusttests3,458 tokenscrates/ruff_annotate_snippets/tests/rustc_tests.rs:2283–2303crates/ruff_annotate_snippets/tests/rustc_tests.rs:2325–2345crates/ruff_annotate_snippets/tests/rustc_tests.rs:2369–2389
2283fn long_span_shortest() { 2284 // tests/ui/diagnostic-width/long-span.rs 2285 let source = r#" 2286const C: u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … 2287 2288fn main() {} 2289"#; 2290 let input = &[Level::ERROR 2291 .primary_title("mismatched types") 2292 .id("E0038")First 10 of 21 lines.
- 177 lines in 86 placestomldocs and examples57 tokenscrates/ty_python_semantic/resources/mdtest/annotations/intersection_types.md:113–289crates/ty_python_semantic/resources/mdtest/call/constructor.md:289–1260crates/ty_python_semantic/resources/mdtest/call/constructor.md:591–1298crates/ty_python_semantic/resources/mdtest/call/constructor.md:994–1613crates/ty_python_semantic/resources/mdtest/call/constructor.md:1083–1634and 81 more
113python-version = "3.12" 114``` 115 116```py 117class A: ... 118class B: ... 119class Box[T]: ... 120 121type AAndB = A & B 122type NotA = ~A289python-version = "3.12" 290``` 291 292### A decorator returning the enclosing class 293 294A decorator can replace `__new__` with the type of its implicit `cls` parameter, making the 295constructor refer back to itself. Regression test for <https://github.com/astral-sh/ty/issues/4347>. 296 297```py 298from collections.abc import CallableFirst 10 of 177 lines, the second copy on the right.
- 24 lines in 2 placesrusttests3,483 tokenscrates/ruff_annotate_snippets/tests/rustc_tests.rs:2283–2306crates/ruff_annotate_snippets/tests/rustc_tests.rs:2413–2436
2283fn long_span_shortest() { 2284 // tests/ui/diagnostic-width/long-span.rs 2285 let source = r#" 2286const C: u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, … 2287 2288fn main() {} 2289"#; 2290 let input = &[Level::ERROR 2291 .primary_title("mismatched types") 2292 .id("E0038")First 10 of 24 lines.
- 22 lines in 17 placesmarkuptests172 tokenscrates/ruff_annotate_snippets/tests/color/ann_eof.ascii.term.svg:1–22crates/ruff_annotate_snippets/tests/color/ensure_emoji_highlight_width.ascii.term.svg:1–22crates/ruff_annotate_snippets/tests/color/fold_bad_origin_line.ascii.term.svg:1–22crates/ruff_annotate_snippets/tests/color/fold_bad_origin_line.unicode.term.svg:1–22crates/ruff_annotate_snippets/tests/color/fold_leading.ascii.term.svg:1–22and 12 more
- 6 lines in 37 placesmarkdowndocs and examples51 tokens
By format, code only
| Format | Files | Lines | Clones | Duplicated lines | Duplication |
|---|---|---|---|---|---|
| rust | 1,857 | 788,822 | 3,678 | 46,792 | 5.93% |
| python | 203 | 22,169 | 37 | 347 | 1.57% |
| tsx | 29 | 6,533 | 9 | 213 | 3.26% |
| typescript | 13 | 734 | 1 | 27 | 3.68% |
| bash | 8 | 401 | 0 | 0 | 0% |
By format, all files
| Format | Files | Lines | Clones | Duplicated lines | Duplication |
|---|---|---|---|---|---|
| rust | 1,999 | 856,678 | 4,802 | 62,227 | 7.26% |
| python | 1,865 | 259,880 | 1,074 | 15,505 | 5.97% |
| text | 165 | 13,358 | 395 | 2,391 | 17.9% |
| markdown | 655 | 316,671 | 352 | 17,025 | 5.38% |
| toml | 147 | 8,448 | 260 | 3,200 | 37.88% |
| markup | 83 | 4,258 | 170 | 2,461 | 57.8% |
| yaml | 43 | 6,997 | 93 | 1,055 | 15.08% |
| txt | 22 | 19,373 | 69 | 546 | 2.82% |
| tsx | 29 | 6,533 | 9 | 213 | 3.26% |
| css | 4 | 583 | 2 | 132 | 22.64% |
Trending appearances
| Day | Rank | Stars | Files | Lines | Clones | All files | Code | Health | Commit |
|---|---|---|---|---|---|---|---|---|---|
| Nov 7, 2026 | #11 | 50,738 (+169) | 5,098 | 1,504,268 | 7,228 | 6.97% | 5.79% | D 47.7 | 6f86f83 |
Want this for your own project? Install jscpd and run jscpd ., or measure it the way the baselines were measured.