1
1
"""Checker of PEP-8 Naming Conventions."""
2
2
import ast
3
+ import enum
3
4
from ast import iter_child_nodes
4
5
from collections import deque
5
- from collections .abc import Iterable , Sequence
6
+ from collections .abc import Iterable , Iterator , Sequence
6
7
from fnmatch import fnmatchcase
7
8
from functools import partial
8
9
from itertools import chain
@@ -69,7 +70,8 @@ def __contains__(self, item: object, /) -> bool:
69
70
return super ().__contains__ (item )
70
71
71
72
72
- class _FunctionType :
73
+ @enum .unique
74
+ class FunctionType (enum .Enum ):
73
75
CLASSMETHOD = 'classmethod'
74
76
STATICMETHOD = 'staticmethod'
75
77
FUNCTION = 'function'
@@ -94,11 +96,11 @@ class _FunctionType:
94
96
95
97
96
98
def _build_decorator_to_type (classmethod_decorators , staticmethod_decorators ):
97
- decorator_to_type = {}
99
+ decorator_to_type : dict [ str , FunctionType ] = {}
98
100
for decorator in classmethod_decorators :
99
- decorator_to_type [decorator ] = _FunctionType .CLASSMETHOD
101
+ decorator_to_type [decorator ] = FunctionType .CLASSMETHOD
100
102
for decorator in staticmethod_decorators :
101
- decorator_to_type [decorator ] = _FunctionType .STATICMETHOD
103
+ decorator_to_type [decorator ] = FunctionType .STATICMETHOD
102
104
return decorator_to_type
103
105
104
106
@@ -188,7 +190,7 @@ def tag_class_functions(self, cls_node):
188
190
"""Tag functions if they are methods, classmethods, staticmethods"""
189
191
# tries to find all 'old style decorators' like
190
192
# m = staticmethod(m)
191
- late_decoration = {}
193
+ late_decoration : dict [ str , FunctionType ] = {}
192
194
for node in iter_child_nodes (cls_node ):
193
195
if not (isinstance (node , ast .Assign ) and
194
196
isinstance (node .value , ast .Call ) and
@@ -213,24 +215,31 @@ def tag_class_functions(self, cls_node):
213
215
self .set_function_nodes_types (
214
216
iter_child_nodes (cls_node ), ismetaclass , late_decoration )
215
217
216
- def set_function_nodes_types (self , nodes , ismetaclass , late_decoration ):
218
+ def set_function_nodes_types (
219
+ self ,
220
+ nodes : Iterator [ast .AST ],
221
+ ismetaclass : bool ,
222
+ late_decoration : dict [str , FunctionType ],
223
+ ):
217
224
# iterate over all functions and tag them
218
225
for node in nodes :
219
226
if type (node ) in METHOD_CONTAINER_NODES :
220
227
self .set_function_nodes_types (
221
228
iter_child_nodes (node ), ismetaclass , late_decoration )
222
229
if not isinstance (node , FUNC_NODES ):
223
230
continue
224
- node . function_type = _FunctionType .METHOD
231
+ setattr ( node , ' function_type' , FunctionType .METHOD )
225
232
if node .name in CLASS_METHODS or ismetaclass :
226
- node . function_type = _FunctionType .CLASSMETHOD
233
+ setattr ( node , ' function_type' , FunctionType .CLASSMETHOD )
227
234
if node .name in late_decoration :
228
- node . function_type = late_decoration [node .name ]
235
+ setattr ( node , ' function_type' , late_decoration [node .name ])
229
236
elif node .decorator_list :
230
237
for d in node .decorator_list :
231
238
name = self .find_decorator_name (d )
232
- if name in self .decorator_to_type :
233
- node .function_type = self .decorator_to_type [name ]
239
+ if name is None :
240
+ continue
241
+ if function_type := self .decorator_to_type .get (name ):
242
+ setattr (node , 'function_type' , function_type )
234
243
break
235
244
236
245
@classmethod
@@ -320,18 +329,18 @@ def has_override_decorator(node):
320
329
return False
321
330
322
331
def visit_functiondef (self , node , parents : Sequence , ignored : NameSet ):
323
- function_type = getattr (node , 'function_type' , _FunctionType .FUNCTION )
332
+ function_type = getattr (node , 'function_type' , FunctionType .FUNCTION )
324
333
name = node .name
325
334
if name in ignored :
326
335
return
327
336
if name in ('__dir__' , '__getattr__' ):
328
337
return
329
- if (function_type != _FunctionType .FUNCTION
338
+ if (function_type != FunctionType .FUNCTION
330
339
and self .has_override_decorator (node )):
331
340
return
332
341
if name .lower () != name :
333
342
yield self .err (node , 'N802' , name = name )
334
- if (function_type == _FunctionType .FUNCTION
343
+ if (function_type == FunctionType .FUNCTION
335
344
and name [:2 ] == '__' and name [- 2 :] == '__' ):
336
345
yield self .err (node , 'N807' , name = name )
337
346
@@ -363,9 +372,9 @@ def visit_functiondef(self, node, parents: Sequence, ignored: NameSet):
363
372
# for backwards compatibility.
364
373
if args and (name := args [0 ].arg ) and name not in ignored :
365
374
function_type = getattr (node , 'function_type' , None )
366
- if function_type == _FunctionType .METHOD and name != 'self' :
375
+ if function_type == FunctionType .METHOD and name != 'self' :
367
376
yield self .err (args [0 ], 'N805' )
368
- elif function_type == _FunctionType .CLASSMETHOD and name != 'cls' :
377
+ elif function_type == FunctionType .CLASSMETHOD and name != 'cls' :
369
378
yield self .err (args [0 ], 'N804' )
370
379
371
380
# Also add the special *arg and **kwarg arguments for the rest of the
0 commit comments