Repository: pylint-dev/pylint

Issue:
# ``duplicate-code`` takes over an hour for a large project even when disabled, if ``reports=yes``

<!--
  Hi there! Thank you for discovering and submitting an issue.

  Before you submit this, make sure that the issue doesn't already exist
  or if it is not closed.

  Is your issue fixed on the preview release?: pip install pylint astroid --pre -U

-->

In a directory with 500000 LOC of python files, we noticed pylint would hang for the entire directory. After investigating, it actually was just taking **forever** (60+ minutes) to compute similarities. We have similarities disabled for our project, and it was doing this regardless.
After removing pylint/checkers/similarities.py, it took about 3 minutes to do all of the checks we wanted.

### Steps to reproduce
1. Find some project with 500000 lines
2. Run pylint
3. Wait an hour

### Current behavior
It takes an hour to run similarities on a project, despite similarities being disabled.

### Expected behavior
Similarities are not checked and do not consume so much time. Or they take a non-noticeable amount of time.

### pylint --version output
```
$ pylint --version
Starting at 18:07:52
pylint3 2.3.1
astroid 2.2.5
Python 3.7.3 (default, Aug  8 2019, 00:00:00) 
[GCC 7.3.1 20180303 (Red Hat 7.3.1-5)]
(datarobot-6.0) Completed at 18:07:53
```


Implementation patch:
diff --git a/pylint/lint/pylinter.py b/pylint/lint/pylinter.py
index 90fb0a3360..088e9c15c0 100644
--- a/pylint/lint/pylinter.py
+++ b/pylint/lint/pylinter.py
@@ -617,7 +617,10 @@ def prepare_checkers(self) -> list[BaseChecker]:
         needed_checkers: list[BaseChecker] = [self]
         for checker in self.get_checkers()[1:]:
             messages = {msg for msg in checker.msgs if self.is_message_enabled(msg)}
-            if messages or any(self.report_is_enabled(r[0]) for r in checker.reports):
+            if messages or (
+                not checker.msgs
+                and any(self.report_is_enabled(r[0]) for r in checker.reports)
+            ):
                 needed_checkers.append(checker)
         return needed_checkers
 


Test patch:
diff --git a/tests/lint/unittest_lint.py b/tests/lint/unittest_lint.py
index 49d02f7e77..c037c3636c 100644
--- a/tests/lint/unittest_lint.py
+++ b/tests/lint/unittest_lint.py
@@ -445,6 +445,20 @@ def test_disable_similar(initialized_linter: PyLinter) -> None:
     assert "similarities" not in [c.name for c in linter.prepare_checkers()]
 
 
+def test_disable_similar_with_reports(initialized_linter: PyLinter) -> None:
+    """Disabling R0801 should exclude the similarities checker even with reports enabled.
+
+    Regression test for https://github.com/pylint-dev/pylint/issues/3443
+    """
+    linter = initialized_linter
+    linter.set_option("reports", True)
+    linter.set_option("disable", "R0801")
+    checker_names = [c.name for c in linter.prepare_checkers()]
+    assert "similarities" not in checker_names
+    # Report-only checkers (no messages) should still be included
+    assert "metrics" in checker_names
+
+
 def test_disable_alot(linter: PyLinter) -> None:
     """Check that we disabled a lot of checkers."""
     linter.set_option("reports", False)