aboutsummaryrefslogtreecommitdiff
blob: eaa42a37618f2a0074a4bacc6efab4c7d5081905 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
from . import mixins


class Test(mixins.TargetedNamespaceWalker, mixins.KlassWalker):

    target_namespace = "snakeoil"

    singleton = object()

    def setup_method(self):
        self._ignore_set = frozenset(self.iter_builtin_targets())

    def _should_ignore(self, cls):
        if cls in self._ignore_set:
            return True

        if getattr(cls, "__hash__intentionally_disabled__", False):
            return True

        namepath = f"{cls.__module__}.{cls.__name__}"
        return not namepath.startswith(self.target_namespace)

    def run_check(self, cls):
        for parent in cls.__bases__:
            if parent == object:
                # object sets __hash__/__eq__, which isn't usually
                # intended to be inherited/reused
                continue
            eq = getattr(parent, "__eq__", self.singleton)
            h = getattr(parent, "__hash__", self.singleton)
            if eq == object.__eq__ and h == object.__hash__:
                continue
            if eq and h:
                break
        else:
            return

        # pylint: disable=undefined-loop-variable
        # 'parent' is guaranteed to be defined due to the 'else' clause above
        assert getattr(cls, "__hash__") is not None, (
            f"class '{cls.__module__}.{cls.__name__}' had its __hash__ reset, "
            "while it would've inherited __hash__ from parent "
            f"'{parent.__module__}.{parent.__name__}'; this occurs in py3k when "
            "__eq__ is  defined alone.  If this is desired behaviour, set "
            "__hash__intentionally_disabled__ to True to explicitly ignore this"
            " class"
        )