Repository Analysis

Delgan/loguru

Python logging made (stupidly) simple

21.7 Moderate AI signal View on GitHub

Analysis Overview

This report presents the forensic synthetic code analysis of Delgan/loguru, a Python project with 24,013 GitHub stars. SynthScan v2.0 examined 26,581 lines of code across 286 source files, recording 533 pattern matches distributed across 10 syntactic categories. The overall adjusted score of 21.7 places this repository in the Moderate AI signal band.

The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).

21.7
Adjusted Score
21.7
Raw Score
100%
Time Factor
2026-07-01
Last Push
24.0K
Stars
Python
Language
26.6K
Lines of Code
286
Files
533
Pattern Hits
2026-07-14
Scan Date
0.00
HC Hit Rate

What These Metrics Mean

Adjusted Score
Primary synthetic code indicator. Raw score normalised per 1,000 lines of code and multiplied by the temporal discount factor. This is the definitive comparative metric — use it to rank repositories by AI authorship density.
Raw Score
The unmodified sum of all severity-weighted, context-multiplied pattern match scores before temporal discounting. Reflects the absolute signal strength independent of when the repository was last active.
Time Factor
The temporal discount multiplier (0–100%) applied to the raw score. Repositories last updated before ChatGPT's launch (Nov 2022) receive a 5% factor. Full signal is only assigned to repositories active in the post-adoption era (Jan 2024+).
Pattern Hits
Total count of individual pattern matches across all files and categories. A high hit count with a low score may indicate a very large codebase with isolated AI snippets; a low count with a high score indicates dense, concentrated AI signatures.
HC Hit Rate
High+Critical pattern hits per file, averaged across the repository. This orthogonal signal catches repositories where a few files are densely packed with high-severity AI tells — a strong indicator even when the normalised score appears moderate due to codebase size.
Lines of Code / Files
Total lines and files analysed. The scanner examines 94 file extensions. These denominators are used to normalise the score, enabling fair comparison between repositories of vastly different sizes.

Score History

This chart maps the temporal evolution of the adjusted synthetic code score across successive scan runs. An upward trajectory indicates ongoing incorporation of AI-generated code or expanding LLM-assisted scaffolding; a stable or declining trajectory may reflect active human refactoring, code removal, or the adoption of stricter authorship policies. The dashed secondary line (right axis) independently tracks total raw pattern hit count, which can diverge from the normalised score when codebase size changes significantly between scans.

Severity Breakdown

Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.

CRITICAL 0HIGH 0MEDIUM 11LOW 522

Directory Score Breakdown

This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.

Pattern Findings

The scanner identified 533 distinct pattern matches across 10 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.

Reading the findings table: The Severity column indicates the diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.

Hyper-Verbose Identifiers429 hits · 454 pts
SeverityFileLineSnippetContext
LOWtests/test_colorama.py44def test_stream_wrapped_on_windows_if_no_vt_support(patched, monkeypatch, patch_colorama):CODE
LOWtests/test_colorama.py56def test_stream_not_wrapped_on_windows_if_vt_support(patched, monkeypatch, patch_colorama):CODE
LOWtests/test_colorama.py110def test_github_actions_fixed(monkeypatch, patched, expected):CODE
LOWtests/test_colorama.py130def test_mintty_fixed_windows(monkeypatch, patched, expected):CODE
LOWtests/test_colorama.py148def test_dumb_term_not_colored(monkeypatch, patched, expected):CODE
LOWtests/test_colorama.py173def test_honor_no_color_standard(monkeypatch, patched, no_color, expected):CODE
LOWtests/test_colorama.py198def test_honor_force_color_standard(monkeypatch, patched, force_color, expected):CODE
LOWtests/test_colorama.py206def test_no_color_takes_precedence_over_force_color(monkeypatch):CODE
LOWtests/test_colorama.py232def test_mintty_not_fixed_linux(monkeypatch, patched, expected):CODE
LOWtests/test_colorama.py295def test_dont_wrap_if_not_original_stdout_or_stderr(monkeypatch, patched, patch_colorama):CODE
LOWtests/test_colorama.py305def test_dont_wrap_if_terminal_has_vt_support(monkeypatch, patched, patch_colorama):CODE
LOWtests/test_colorama.py317def test_dont_wrap_if_winapi_false(monkeypatch, patched, patch_colorama):CODE
LOWtests/test_colorama.py329def test_wrap_if_winapi_true_and_no_vt_support(monkeypatch, patched, patch_colorama):CODE
LOWtests/test_colorama.py342def test_wrap_if_winapi_true_and_vt_check_fails(monkeypatch, patched, patch_colorama):CODE
LOWtests/test_colorama.py355def test_wrap_if_winapi_true_and_stream_has_no_fileno(monkeypatch, patched, patch_colorama):CODE
LOWtests/test_colorama.py367def test_wrap_if_winapi_true_and_old_colorama_version(monkeypatch, patched, patch_colorama):CODE
LOWtests/test_filesink_rotation.py1122def test_invalid_day_rotation(rotation):CODE
LOWtests/test_filesink_rotation.py1130def test_invalid_time_rotation(rotation):CODE
LOWtests/test_filesink_rotation.py1136def test_invalid_value_size_rotation(rotation):CODE
LOWtests/test_filesink_rotation.py1142def test_invalid_unit_rotation_duration(rotation):CODE
LOWtests/test_filesink_rotation.py1148def test_invalid_value_rotation_duration(rotation):CODE
LOWtests/test_filesink_rotation.py191def test_time_rotation_with_tzinfo_diff_bigger(freeze_time, tmp_path):CODE
LOWtests/test_filesink_rotation.py214def test_time_rotation_with_tzinfo_diff_lower(freeze_time, tmp_path):CODE
LOWtests/test_filesink_rotation.py237def test_time_rotation_with_tzinfo_utc(freeze_time, tmp_path):CODE
LOWtests/test_filesink_rotation.py263def test_time_rotation_multiple_days_at_midnight_utc(freeze_time, tmp_path):CODE
LOWtests/test_filesink_rotation.py295def test_daily_rotation_with_different_timezone(freeze_time, tmp_path, offset):CODE
LOWtests/test_filesink_rotation.py333def test_time_rotation_after_positive_timezone_changes_forward(freeze_time, tmp_path, rotation):CODE
LOWtests/test_filesink_rotation.py360def test_time_rotation_when_positive_timezone_changes_forward(freeze_time, tmp_path, rotation):CODE
LOWtests/test_filesink_rotation.py396def test_time_rotation_after_negative_timezone_changes_forward(freeze_time, tmp_path, rotation):CODE
LOWtests/test_filesink_rotation.py423def test_time_rotation_when_negative_timezone_changes_forward(freeze_time, tmp_path, rotation):CODE
LOWtests/test_filesink_rotation.py457def test_time_rotation_after_positive_timezone_changes_backward_aware(CODE
LOWtests/test_filesink_rotation.py486def test_time_rotation_after_positive_timezone_changes_backward_naive(CODE
LOWtests/test_filesink_rotation.py524def test_time_rotation_after_negative_timezone_changes_backward_aware(CODE
LOWtests/test_filesink_rotation.py553def test_time_rotation_after_negative_timezone_changes_backward_naive(CODE
LOWtests/test_filesink_rotation.py583def test_time_rotation_when_timezone_changes_backward_rename_file(freeze_time, tmp_path):CODE
LOWtests/test_filesink_rotation.py619def test_dont_rotate_earlier_when_utc_is_one_day_before(freeze_time, tmp_path, rotation):CODE
LOWtests/test_filesink_rotation.py654def test_dont_rotate_later_when_utc_is_one_day_after(freeze_time, tmp_path, rotation):CODE
LOWtests/test_filesink_rotation.py680def test_rotation_at_midnight_with_date_in_filename(freeze_time, tmp_path, timezone):CODE
LOWtests/test_filesink_rotation.py702def test_time_rotation_reopening_native(tmp_path_local, delay):CODE
LOWtests/test_filesink_rotation.py758def test_time_rotation_reopening_xattr_attributeerror(tmp_path_local, monkeypatch, delay):CODE
LOWtests/test_filesink_rotation.py794def test_time_rotation_reopening_xattr_oserror(tmp_path_local, monkeypatch, delay):CODE
LOWtests/test_filesink_rotation.py823def test_time_rotation_windows_no_setctime(tmp_path, monkeypatch):CODE
LOWtests/test_filesink_rotation.py847def test_time_rotation_windows_setctime_exception(tmp_path, monkeypatch, exception):CODE
LOWtests/test_filesink_rotation.py915def test_no_rotation_at_remove(tmp_path, mode):CODE
LOWtests/test_filesink_rotation.py923def test_rename_existing_with_creation_time(freeze_time, tmp_path):CODE
LOWtests/test_filesink_rotation.py939def test_renaming_rotation_dest_exists(freeze_time, tmp_path):CODE
LOWtests/test_filesink_rotation.py957def test_renaming_rotation_dest_exists_with_time(freeze_time, tmp_path):CODE
LOWtests/test_filesink_rotation.py977def test_exception_during_rotation(tmp_path, capsys):CODE
LOWtests/test_filesink_rotation.py996def test_exception_during_rotation_not_caught(tmp_path, capsys):CODE
LOWtests/test_filesink_rotation.py1015def test_recipe_rotation_both_size_and_time(freeze_time, tmp_path):CODE
LOWtests/test_filesink_rotation.py1062def test_multiple_rotation_conditions(freeze_time, tmp_path):CODE
LOWtests/test_filesink_rotation.py1087def test_empty_rotation_condition_list():CODE
LOWtests/test_filesink_rotation.py1095def test_invalid_rotation_type(rotation):CODE
LOWtests/test_add_option_serialize.py29def test_serialize_non_ascii_characters():CODE
LOWtests/test_add_option_serialize.py60def test_serialize_exception_without_context():CODE
LOWtests/test_add_option_serialize.py77def test_serialize_exception_none_tuple():CODE
LOWtests/test_add_option_serialize.py94def test_serialize_exception_instance():CODE
LOWtests/test_add_option_serialize.py111def test_serialize_with_catch_decorator():CODE
LOWtests/test_add_option_serialize.py127def test_serialize_with_record_option():CODE
LOWtests/test_add_option_serialize.py137def test_serialize_not_serializable():CODE
369 more matches not shown…
Excessive Try-Catch Wrapping63 hits · 80 pts
SeverityFileLineSnippetContext
LOWtests/test_opt.py68 except Exception:CODE
LOWtests/test_opt.py82 except Exception:CODE
LOWtests/test_opt.py98 except Exception:CODE
LOWtests/test_opt.py114 except Exception:CODE
LOWtests/test_interception.py110 except Exception:CODE
LOWtests/test_add_option_diagnose.py10 except Exception:CODE
LOWtests/test_add_option_diagnose.py20 except Exception:CODE
LOWtests/test_exceptions_catch.py75 except Exception:CODE
LOWtests/test_exceptions_catch.py91 except Exception:CODE
LOWtests/test_add_option_enqueue.py263 except Exception:CODE
LOWtests/test_add_option_enqueue.py286 except Exception:CODE
LOWtests/test_propagation.py89 except Exception:CODE
LOWtests/test_add_option_backtrace.py10 except Exception:CODE
LOWtests/test_add_option_backtrace.py20 except Exception:CODE
LOWtests/test_exceptions_formatting.py287 except Exception:CODE
LOW…tions/source/backtrace/missing_lineno_frame_objects.py40except Exception as e:CODE
LOWtests/exceptions/source/backtrace/nested_wrapping.py32except Exception:CODE
LOW…exceptions/source/backtrace/nested_chained_catch_up.py23 except Exception as e:CODE
MEDIUM…exceptions/source/backtrace/nested_chained_catch_up.py20def main():CODE
LOWtests/exceptions/source/others/repeated_lines.py22except Exception:CODE
LOWtests/exceptions/source/others/one_liner_recursion.py15except Exception:CODE
LOWtests/exceptions/source/others/recursion_error.py20except Exception:CODE
LOWtests/exceptions/source/others/nested_with_reraise.py21 except Exception as e:CODE
MEDIUMtests/exceptions/source/others/nested_with_reraise.py18def bar(x, y):CODE
LOWtests/exceptions/source/diagnose/chained_both.py16 except Exception:CODE
LOWtests/exceptions/source/diagnose/chained_both.py23 except Exception as e:CODE
MEDIUMtests/exceptions/source/diagnose/chained_both.py13def cause(x, y):CODE
MEDIUMtests/exceptions/source/diagnose/chained_both.py20def context(x, y):CODE
LOWtests/exceptions/source/modern/grouped_simple.py27 except Exception as error_1:CODE
LOWtests/exceptions/source/modern/grouped_simple.py30 except Exception as error_2:CODE
LOWtests/exceptions/source/modern/grouped_simple.py33 except Exception as error_3:CODE
MEDIUMtests/exceptions/source/modern/grouped_simple.py24def main():CODE
LOW…ptions/source/modern/grouped_with_cause_and_context.py18 except Exception as err:CODE
LOW…ptions/source/modern/grouped_with_cause_and_context.py20 except Exception as err:CODE
LOW…ptions/source/modern/grouped_with_cause_and_context.py25 except Exception as err:CODE
LOW…ptions/source/modern/grouped_with_cause_and_context.py27 except Exception as err:CODE
LOW…ptions/source/modern/grouped_with_cause_and_context.py32 except Exception as err:CODE
LOW…ptions/source/modern/grouped_with_cause_and_context.py35 except Exception:CODE
MEDIUM…ptions/source/modern/grouped_with_cause_and_context.py14def main():CODE
LOWtests/exceptions/source/modern/grouped_nested.py18 except Exception as err:CODE
LOWtests/exceptions/source/modern/grouped_nested.py23 except Exception as err:CODE
LOWtests/exceptions/source/modern/grouped_nested.py30 except Exception as err:CODE
MEDIUMtests/exceptions/source/modern/grouped_nested.py14def main():CODE
LOW…ceptions/source/modern/grouped_as_cause_and_context.py21 except Exception as err:CODE
LOW…ceptions/source/modern/grouped_as_cause_and_context.py26 except Exception as err:CODE
LOW…ceptions/source/modern/grouped_as_cause_and_context.py32 except Exception as err:CODE
LOW…ceptions/source/modern/grouped_as_cause_and_context.py34 except Exception as err:CODE
MEDIUM…ceptions/source/modern/grouped_as_cause_and_context.py18def main():CODE
LOWloguru/_better_exceptions.py353 except Exception:CODE
MEDIUMloguru/_better_exceptions.py193def _get_char(self, char, default):CODE
LOWloguru/_handler.py207 except Exception:CODE
LOWloguru/_handler.py318 except Exception:CODE
LOWloguru/_handler.py333 except Exception:CODE
MEDIUMloguru/_handler.py127def emit(self, record, level_id, from_decorator, is_raw, colored_message):CODE
LOWloguru/_colorama.py32 except Exception:CODE
LOWloguru/_colorama.py53 except Exception:CODE
LOWloguru/_colorama.py76 except Exception:CODE
LOWloguru/_simple_sinks.py194 except Exception:CODE
LOWloguru/_error_interceptor.py26 except Exception:CODE
LOWloguru/_get_frame.py8 except Exception:CODE
3 more matches not shown…
Deep Nesting15 hits · 15 pts
SeverityFileLineSnippetContext
LOWloguru/_better_exceptions.py72CODE
LOWloguru/_better_exceptions.py210CODE
LOWloguru/_better_exceptions.py275CODE
LOWloguru/_better_exceptions.py361CODE
LOWloguru/_better_exceptions.py401CODE
LOWloguru/_colorizer.py222CODE
LOWloguru/_colorizer.py416CODE
LOWloguru/_colorizer.py477CODE
LOWloguru/_handler.py127CODE
LOWloguru/_file_sink.py377CODE
LOWloguru/_logger.py273CODE
LOWloguru/_logger.py1182CODE
LOWloguru/_logger.py1886CODE
LOWloguru/_logger.py2053CODE
LOWloguru/_logger.py1319CODE
Unused Imports12 hits · 12 pts
SeverityFileLineSnippetContext
LOWtests/exceptions/source/ownership/callback.py3CODE
LOW…ts/exceptions/source/ownership/assertion_from_local.py3CODE
LOW…ts/exceptions/source/ownership/assertion_from_local.py4CODE
LOWtests/exceptions/source/ownership/assertion_from_lib.py3CODE
LOWtests/exceptions/source/ownership/syntaxerror.py3CODE
LOWtests/exceptions/source/ownership/decorated_callback.py3CODE
LOWtests/exceptions/source/ownership/decorated_callback.py4CODE
LOWtests/exceptions/source/ownership/catch_decorator.py3CODE
LOWtests/exceptions/source/ownership/indirect.py3CODE
LOW…xceptions/source/ownership/catch_decorator_from_lib.py3CODE
LOWtests/exceptions/source/ownership/string_lib.py3CODE
LOWtests/exceptions/source/ownership/direct.py3CODE
Overly Generic Function Names3 hits · 4 pts
SeverityFileLineSnippetContext
LOWtests/test_multiprocessing.py26def do_something(i):CODE
LOWtests/test_repr.py84def test_function():CODE
LOWtests/test_repr.py85 def my_function(message):CODE
AI Structural Patterns4 hits · 4 pts
SeverityFileLineSnippetContext
LOWloguru/_better_exceptions.py151CODE
LOWloguru/_file_sink.py165CODE
LOWloguru/_logger.py273CODE
LOWloguru/_logger.py1384CODE
Over-Commented Block3 hits · 3 pts
SeverityFileLineSnippetContext
LOWdocs/conf.py81# The theme to use for HTML and HTML Help pages. See the documentation forCOMMENT
LOWdocs/conf.py101# defined by theme itself. Builtin themes are using these templates byCOMMENT
LOWdocs/conf.py121 #COMMENT
Slop Phrases2 hits · 2 pts
SeverityFileLineSnippetContext
LOWloguru/_logger.py782 Windows, don't forget to restart your terminal for the change to be taken into account.CODE
LOWloguru/_logger.py1737 >>> logger.info("While publishing a library, don't forget to disable logging")CODE
AI Slop Vocabulary1 hit · 2 pts
SeverityFileLineSnippetContext
LOWtests/test_template_strings.py18 # We can't just use t"2**8 = {2**8}", because its a syntax error before python-3.14.COMMENT
Modern Structural Boilerplate1 hit · 1 pts
SeverityFileLineSnippetContext
LOWloguru/__init__.py16__all__ = ["logger"]CODE