|
14 | 14 | import traceback |
15 | 15 | import warnings |
16 | 16 | from collections import defaultdict |
17 | | -from collections.abc import Callable, Iterable, Iterator, Sequence |
| 17 | +from collections.abc import Callable, Collection, Iterable, Iterator, Sequence |
18 | 18 | from io import TextIOWrapper |
19 | 19 | from pathlib import Path |
20 | 20 | from re import Pattern |
@@ -323,6 +323,16 @@ def __init__( |
323 | 323 | """Dictionary of registered and initialized checkers.""" |
324 | 324 | self._dynamic_plugins: dict[str, ModuleType | ModuleNotFoundError | bool] = {} |
325 | 325 | """Set of loaded plugin names.""" |
| 326 | + self._registered_checkers: set[tuple[str, checkers.BaseChecker, int]] = set() |
| 327 | + """Set of tuples with loaded checker name, reference to checker |
| 328 | + and checker object id. |
| 329 | + """ |
| 330 | + self._registered_dynamic_plugin_checkers: set[ |
| 331 | + tuple[str, checkers.BaseChecker, int] |
| 332 | + ] = set() |
| 333 | + """Set of tuples with loaded dynamic plugin checker name, reference to |
| 334 | + checker and checker object id. |
| 335 | + """ |
326 | 336 |
|
327 | 337 | # Attributes related to stats |
328 | 338 | self.stats = LinterStats() |
@@ -356,6 +366,7 @@ def __init__( |
356 | 366 | self.msgs_store = MessageDefinitionStore(self.config.py_version) |
357 | 367 | self.msg_status = 0 |
358 | 368 | self._by_id_managed_msgs: list[ManagedMessage] = [] |
| 369 | + self._freeze_register_msgs = False |
359 | 370 |
|
360 | 371 | # Attributes related to visiting files |
361 | 372 | self.file_state = FileState("", self.msgs_store, is_base_filestate=True) |
@@ -495,17 +506,30 @@ def report_order(self) -> list[BaseChecker]: |
495 | 506 | def register_checker(self, checker: checkers.BaseChecker) -> None: |
496 | 507 | """This method auto registers the checker.""" |
497 | 508 | self._checkers[checker.name].append(checker) |
| 509 | + self._registered_checkers.add((checker.name, checker, id(checker))) |
498 | 510 | for r_id, r_title, r_cb in checker.reports: |
499 | 511 | self.register_report(r_id, r_title, r_cb, checker) |
500 | | - if hasattr(checker, "msgs"): |
| 512 | + if not self._freeze_register_msgs and hasattr(checker, "msgs"): |
501 | 513 | self.msgs_store.register_messages_from_checker(checker) |
502 | 514 | for message in checker.messages: |
503 | 515 | if not message.default_enabled: |
504 | 516 | self.disable(message.msgid) |
505 | 517 | # Register the checker, but disable all of its messages. |
506 | | - if not getattr(checker, "enabled", True): |
| 518 | + if not (self._freeze_register_msgs or getattr(checker, "enabled", True)): |
507 | 519 | self.disable(checker.name) |
508 | 520 |
|
| 521 | + def _deregister_checkers( |
| 522 | + self, checker_collection: Collection[tuple[str, checkers.BaseChecker, int]] |
| 523 | + ) -> None: |
| 524 | + """De-registered a collection of checkers with its reports. |
| 525 | +
|
| 526 | + Leave messages in place as re-registering them is a no-op. |
| 527 | + """ |
| 528 | + for checker_name, checker, _ in checker_collection: |
| 529 | + self._checkers[checker_name].remove(checker) |
| 530 | + if checker.reports: |
| 531 | + self.deregister_reports(checker) |
| 532 | + |
509 | 533 | def enable_fail_on_messages(self) -> None: |
510 | 534 | """Enable 'fail on' msgs. |
511 | 535 |
|
|
0 commit comments