This repository has been archived by the owner on Jan 12, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
_line.py
95 lines (83 loc) · 2.38 KB
/
_line.py
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import ast
from pathlib import Path
from typing import Optional
import attr
from ._constants import DOCSTRING
@attr.s(frozen=True)
class Line:
target = attr.ib(type=str)
value = attr.ib()
content = attr.ib(type=str)
row = attr.ib(type=int)
path = attr.ib(type=Path)
# https://stackoverflow.com/a/1523456/8704691
_vars = {
'__author__',
'__authors__',
'__contact__',
'__copyright__',
'__credits__',
'__email__',
'__homepage__',
'__license__',
'__maintainer__',
'__version__',
}
@classmethod
def parse(cls, content: str, row: int, path: Path) -> Optional['Line']:
if '=' not in content:
return None
try:
tree = ast.parse(content)
except SyntaxError:
return None
if type(tree) is not ast.Module:
return None
# check is assigment
if type(tree.body[0]) is not ast.Assign: # type: ignore
return None
# check is correct target
target = tree.body[0].targets[0] # type: ignore
if type(target) is not ast.Name:
return None
if target.id not in cls._vars:
return None
value = tree.body[0].value # type: ignore
# get string
if type(value) is ast.Str:
return cls(
target=target.id,
value=value.s,
content=content,
row=row,
path=path,
)
# get list
if type(value) is ast.List or type(value) is ast.Tuple:
for element in value.elts:
if type(element) is not ast.Str:
return None
return cls(
target=target.id,
value=[element.s for element in value.elts],
content=content,
row=row,
path=path,
)
return None
@classmethod
def parse_docstring(cls, content: str, path: Path) -> Optional['Line']:
try:
tree = ast.parse(content)
except SyntaxError:
return None
docstring = ast.get_docstring(tree)
if docstring is None:
return None
return cls(
target=DOCSTRING,
value=docstring,
content='',
row=0,
path=path,
)