|
1 | 1 | import ast |
2 | | -import sys |
| 2 | +from logging import getLogger |
3 | 3 | from typing import List, Tuple, Any |
4 | 4 |
|
| 5 | +logger = getLogger(__name__) |
5 | 6 |
|
6 | | -def get_annotation_complexity(annotation_node, default_complexity: int = 1) -> int: |
| 7 | + |
| 8 | +def get_annotation_complexity(annotation_node) -> int: |
| 9 | + """ |
| 10 | + Recursively counts complexity of annotation nodes. |
| 11 | +
|
| 12 | + When annotations are written as strings, |
| 13 | + we additionally parse them to ``ast`` nodes. |
| 14 | + """ |
7 | 15 | if isinstance(annotation_node, ast.Str): |
| 16 | + # try to parse string-wrapped annotations |
8 | 17 | try: |
9 | 18 | annotation_node = ast.parse(annotation_node.s).body[0].value # type: ignore |
10 | | - except (SyntaxError, IndexError): |
11 | | - return default_complexity |
12 | | - complexity = default_complexity |
| 19 | + except Exception as exc: |
| 20 | + logger.debug(f'Cannot parse string-wrapped annotation: {exc!r}') |
| 21 | + return 1 |
| 22 | + |
13 | 23 | if isinstance(annotation_node, ast.Subscript): |
14 | | - if sys.version_info >= (3, 9): |
15 | | - complexity = 1 + get_annotation_complexity(annotation_node.slice) |
16 | | - else: |
17 | | - complexity = 1 + get_annotation_complexity(annotation_node.slice.value) # type: ignore |
18 | | - if isinstance(annotation_node, ast.Tuple): |
19 | | - complexity = max((get_annotation_complexity(n) for n in annotation_node.elts), default=1) |
20 | | - return complexity |
| 24 | + return 1 + get_annotation_complexity(annotation_node.slice) |
| 25 | + |
| 26 | + if isinstance(annotation_node, (ast.Tuple, ast.List)): |
| 27 | + return max((get_annotation_complexity(n) for n in annotation_node.elts), default=1) |
| 28 | + |
| 29 | + return 1 |
21 | 30 |
|
22 | 31 |
|
23 | 32 | def get_annotation_len(annotation_node) -> int: |
24 | | - annotation_len = 0 |
| 33 | + """ |
| 34 | + Recursively counts length of annotation nodes. |
| 35 | +
|
| 36 | + When annotations are written as strings, |
| 37 | + we additionally parse them to ``ast`` nodes. |
| 38 | + """ |
25 | 39 | if isinstance(annotation_node, ast.Str): |
| 40 | + # try to parse string-wrapped annotations |
26 | 41 | try: |
27 | 42 | annotation_node = ast.parse(annotation_node.s).body[0].value # type: ignore |
28 | | - except (SyntaxError, IndexError): |
29 | | - return annotation_len |
| 43 | + except Exception as exc: |
| 44 | + logger.debug(f'Cannot parse string-wrapped annotation: {exc!r}') |
| 45 | + return 0 |
| 46 | + |
30 | 47 | if isinstance(annotation_node, ast.Subscript): |
31 | 48 | try: |
32 | | - if sys.version_info >= (3, 9): |
33 | | - annotation_len = len(annotation_node.slice.elts) # type: ignore |
34 | | - else: |
35 | | - annotation_len = len(annotation_node.slice.value.elts) # type: ignore |
| 49 | + return len(annotation_node.slice.elts) # type: ignore |
36 | 50 | except AttributeError: |
37 | | - annotation_len = 0 |
38 | | - return annotation_len |
| 51 | + logger.debug('Attribute error on annotation length counting') |
| 52 | + return 0 |
| 53 | + |
| 54 | + return 0 |
39 | 55 |
|
40 | 56 |
|
41 | 57 | def validate_annotations_in_ast_node( |
|
0 commit comments