|
26 | 26 | from collections import defaultdict |
27 | 27 |
|
28 | 28 | import astroid |
| 29 | +from astroid import nodes |
29 | 30 |
|
30 | 31 | from pylint import utils |
31 | 32 | from pylint.checkers import BaseChecker |
|
97 | 98 | TYPING_NAMEDTUPLE = "typing.NamedTuple" |
98 | 99 | TYPING_TYPEDDICT = "typing.TypedDict" |
99 | 100 |
|
| 101 | +# Set of stdlib classes to ignore when calculating number of ancestors |
| 102 | +STDLIB_CLASSES_IGNORE_ANCESTOR = frozenset( |
| 103 | + ( |
| 104 | + "builtins.object", |
| 105 | + "builtins.tuple", |
| 106 | + "builtins.dict", |
| 107 | + "builtins.list", |
| 108 | + "builtins.set", |
| 109 | + "bulitins.frozenset", |
| 110 | + "collections.ChainMap", |
| 111 | + "collections.Counter", |
| 112 | + "collections.OrderedDict", |
| 113 | + "collections.UserDict", |
| 114 | + "collections.UserList", |
| 115 | + "collections.UserString", |
| 116 | + "collections.defaultdict", |
| 117 | + "collections.deque", |
| 118 | + "collections.namedtuple", |
| 119 | + "_collections_abc.Awaitable", |
| 120 | + "_collections_abc.Coroutine", |
| 121 | + "_collections_abc.AsyncIterable", |
| 122 | + "_collections_abc.AsyncIterator", |
| 123 | + "_collections_abc.AsyncGenerator", |
| 124 | + "_collections_abc.Hashable", |
| 125 | + "_collections_abc.Iterable", |
| 126 | + "_collections_abc.Iterator", |
| 127 | + "_collections_abc.Generator", |
| 128 | + "_collections_abc.Reversible", |
| 129 | + "_collections_abc.Sized", |
| 130 | + "_collections_abc.Container", |
| 131 | + "_collections_abc.Collection", |
| 132 | + "_collections_abc.Set", |
| 133 | + "_collections_abc.MutableSet", |
| 134 | + "_collections_abc.Mapping", |
| 135 | + "_collections_abc.MutableMapping", |
| 136 | + "_collections_abc.MappingView", |
| 137 | + "_collections_abc.KeysView", |
| 138 | + "_collections_abc.ItemsView", |
| 139 | + "_collections_abc.ValuesView", |
| 140 | + "_collections_abc.Sequence", |
| 141 | + "_collections_abc.MutableSequence", |
| 142 | + "_collections_abc.ByteString", |
| 143 | + "typing.Tuple", |
| 144 | + "typing.List", |
| 145 | + "typing.Dict", |
| 146 | + "typing.Set", |
| 147 | + "typing.FrozenSet", |
| 148 | + "typing.Deque", |
| 149 | + "typing.DefaultDict", |
| 150 | + "typing.OrderedDict", |
| 151 | + "typing.Counter", |
| 152 | + "typing.ChainMap", |
| 153 | + "typing.Awaitable", |
| 154 | + "typing.Coroutine", |
| 155 | + "typing.AsyncIterable", |
| 156 | + "typing.AsyncIterator", |
| 157 | + "typing.AsyncGenerator", |
| 158 | + "typing.Iterable", |
| 159 | + "typing.Iterator", |
| 160 | + "typing.Generator", |
| 161 | + "typing.Reversible", |
| 162 | + "typing.Container", |
| 163 | + "typing.Collection", |
| 164 | + "typing.AbstractSet", |
| 165 | + "typing.MutableSet", |
| 166 | + "typing.Mapping", |
| 167 | + "typing.MutableMapping", |
| 168 | + "typing.Sequence", |
| 169 | + "typing.MutableSequence", |
| 170 | + "typing.ByteString", |
| 171 | + "typing.MappingView", |
| 172 | + "typing.KeysView", |
| 173 | + "typing.ItemsView", |
| 174 | + "typing.ValuesView", |
| 175 | + "typing.ContextManager", |
| 176 | + "typing.AsyncContextManger", |
| 177 | + "typing.Hashable", |
| 178 | + "typing.Sized", |
| 179 | + ) |
| 180 | +) |
| 181 | + |
100 | 182 |
|
101 | 183 | def _is_exempt_from_public_methods(node: astroid.ClassDef) -> bool: |
102 | 184 | """Check if a class is exempt from too-few-public-methods""" |
@@ -294,9 +376,13 @@ def _ignored_argument_names(self): |
294 | 376 | "too-few-public-methods", |
295 | 377 | "too-many-public-methods", |
296 | 378 | ) |
297 | | - def visit_classdef(self, node): |
| 379 | + def visit_classdef(self, node: nodes.ClassDef): |
298 | 380 | """check size of inheritance hierarchy and number of instance attributes""" |
299 | | - nb_parents = len(list(node.ancestors())) |
| 381 | + nb_parents = sum( |
| 382 | + 1 |
| 383 | + for ancestor in node.ancestors() |
| 384 | + if ancestor.qname() not in STDLIB_CLASSES_IGNORE_ANCESTOR |
| 385 | + ) |
300 | 386 | if nb_parents > self.config.max_parents: |
301 | 387 | self.add_message( |
302 | 388 | "too-many-ancestors", |
|
0 commit comments