commit:     0626ecb53745f08dd4163b44b50d1d4419b013ea
Author:     Brian Harring <ferringb <AT> gmail <DOT> com>
AuthorDate: Tue Oct 28 10:04:58 2025 +0000
Commit:     Brian Harring <ferringb <AT> gmail <DOT> com>
CommitDate: Tue Oct 28 10:21:24 2025 +0000
URL:        
https://gitweb.gentoo.org/proj/pkgcore/snakeoil.git/commit/?id=0626ecb5

chore: make tooling like slot_shadow able to report all issues

Change this implementation so it collects all issues, instead of
failing out for the first issue found.

Signed-off-by: Brian Harring <ferringb <AT> gmail.com>

 src/snakeoil/test/mixins.py         | 32 ++++++++++++++++++++++++++++----
 src/snakeoil/test/slot_shadowing.py | 10 ----------
 2 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/src/snakeoil/test/mixins.py b/src/snakeoil/test/mixins.py
index eb8dae1..7ee53a6 100644
--- a/src/snakeoil/test/mixins.py
+++ b/src/snakeoil/test/mixins.py
@@ -1,8 +1,12 @@
+import abc
 import errno
 import inspect
 import os
 import stat
 import sys
+import warnings
+
+import pytest
 
 from ..compatibility import IGNORED_EXCEPTIONS
 
@@ -142,13 +146,29 @@ class TargetedNamespaceWalker(PythonNamespaceWalker):
             pass
 
 
-class _classWalker:
+class _classWalker(abc.ABC):
     cls_blacklist = frozenset()
+    collected_issues: list[str]
+
+    @pytest.fixture(scope="function")
+    @staticmethod
+    def issue_collector(request):
+        request.cls.collected_issues = []
+        yield request.cls.collected_issues
+        collected = request.cls.collected_issues
+        if not collected:
+            return
+        collected_issues = sorted(collected)
+        if getattr(request.cls, "strict"):
+            s = "\n".join(collected_issues)
+            pytest.fail(f"multiple failures detected:\n{s}")
+        for issue in collected_issues:
+            warnings.warn(issue)
 
     def is_blacklisted(self, cls):
         return cls.__name__ in self.cls_blacklist
 
-    def test_object_derivatives(self, *args, **kwds):
+    def test_object_derivatives(self, *args, issue_collector, **kwds):
         # first load all namespaces...
         self.load_namespaces()
 
@@ -164,7 +184,7 @@ class _classWalker:
                 continue
             yield obj
 
-    def test_builtin_derivatives(self, *args, **kwds):
+    def test_builtin_derivatives(self, *args, issue_collector, **kwds):
         self.load_namespaces()
         for obj in self.iter_builtin_targets():
             for cls in self.walk_derivatives(obj, *args, **kwds):
@@ -174,9 +194,13 @@ class _classWalker:
     def walk_derivatives(self, obj):
         raise NotImplementedError(self.__class__, "walk_derivatives")
 
-    def run_check(self, cls):
+    @abc.abstractmethod
+    def run_check(self, cls: type) -> None:
         raise NotImplementedError
 
+    def report_issue(self, message):
+        self.collected_issues.append(message)
+
 
 class SubclassWalker(_classWalker):
     def walk_derivatives(self, cls, seen=None):

diff --git a/src/snakeoil/test/slot_shadowing.py 
b/src/snakeoil/test/slot_shadowing.py
index fa3b683..fb7d398 100644
--- a/src/snakeoil/test/slot_shadowing.py
+++ b/src/snakeoil/test/slot_shadowing.py
@@ -1,7 +1,3 @@
-import warnings
-
-import pytest
-
 from . import mixins
 
 
@@ -86,9 +82,3 @@ class SlotShadowing(mixins.TargetedNamespaceWalker, 
mixins.SubclassWalker):
                 self.report_issue(
                     f"cls {kls!r}; slot {slot!r} was already defined at 
{slotting[slot]!r}"
                 )
-
-    def report_issue(self, message):
-        if self.strict:
-            pytest.fail(message)
-        else:
-            warnings.warn(f"slot_shadowing detected: {message}")

Reply via email to