forked from sagemath/sage
-
Notifications
You must be signed in to change notification settings - Fork 0
/
recipe_item.py
112 lines (94 loc) · 3.75 KB
/
recipe_item.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import re
import weakref
from typing import Any, Optional, Union
from ruamel.yaml import CommentToken
from ruamel.yaml.comments import CommentedSeq
class RecipeItem:
def __init__(self, position: int, yaml: CommentedSeq, item: Any = None):
self.__yaml = weakref.ref(yaml)
self.__pos = position
if position >= len(yaml):
yaml.append(None)
self.value = item
def __repr__(self) -> str:
return (
f"RecipeItem(position={self.__pos},"
f" value={self.value}, selector={self.selector})"
)
def __str__(self) -> str:
val = f"{self.__yaml()[self.__pos]}"
comment = self._get_comment_token()
if comment:
val += f" {comment.value}"
return val
def __lt__(self, other: "RecipeItem") -> bool:
return self.value < other.value
def __eq__(self, other: Union[str, int, "RecipeItem"]) -> bool:
if isinstance(other, RecipeItem):
return self.value == other.value and self.selector == other.selector
return str(self) == str(other) or str(self.value) == str(other)
@staticmethod
def _extract_selector(item: str) -> str:
"""Extract the selectors from the string received.
:param item: String to be parsed
:return: It will return just the content of the selector
"""
selector = re.search(r"\#\s+\[(.*)\]\s*$", item, re.DOTALL)
if selector:
return selector.groups()[0].strip()
return ""
@staticmethod
def _remove_selector(item: str) -> str:
"""Remove the special characters which identifies the selector, if they
are not present it will just return the same string as received.
:param item: String to be removed the selector
:return: New string without the selectors representation
"""
return re.sub(r"\#\s+\[(.*)\]\s*$", "", item).strip()
def _get_comment_token(self) -> Optional[CommentToken]:
all_comment = self.__yaml().ca.items.get(self.__pos, None)
return all_comment[0] if all_comment else None
@property
def value(self) -> Union[str, int, None]:
return self.__yaml()[self.__pos]
@value.setter
def value(self, value: Union[str, int]):
column = 7
if isinstance(value, int):
column += len(str(value))
self.__yaml()[self.__pos] = value
elif value:
self.__yaml()[self.__pos] = self._remove_selector(value)
column += len(str(self.__yaml()[self.__pos]))
else:
column += len(str(value))
self.__yaml()[self.__pos] = value
selector = self._extract_selector(str(value))
if selector:
sel = f"[{selector}]"
self.__yaml().yaml_add_eol_comment(sel, self.__pos, column + len(sel))
@property
def selector(self) -> Optional[str]:
"""Return just the content of the selector, without the special characters
such as # and [ ]
:return: Return the selector
"""
comment = self._get_comment_token()
if comment:
return self._extract_selector(self._get_comment_token().value)
return ""
@selector.setter
def selector(self, value: str):
"""Set the selector for this specific item. It is not necessary to
add the # and [ or ]. Please add just the values.
:param value: string values which represent the content of the selector
"""
comment = self._get_comment_token()
sel = self._extract_selector(value)
if not sel:
sel = self._remove_selector(value)
sel = f"[{sel}]"
if comment:
comment.value = f" # {sel}"
else:
self.__yaml().yaml_add_eol_comment(sel, self.__pos)