Просмотр исходного кода

Annotating pattern, utils

master
Rocketsoup 4 лет назад
Родитель
Сommit
a0a2e5834f
2 измененных файлов: 63 добавлений и 61 удалений
  1. 36
    36
      rocketbot/pattern.py
  2. 27
    25
      rocketbot/utils.py

+ 36
- 36
rocketbot/pattern.py Просмотреть файл

43
 		pass
43
 		pass
44
 
44
 
45
 	@abstractmethod
45
 	@abstractmethod
46
-	def matches(self, message: Message, other_fields: dict[str: Any]) -> bool:
46
+	def matches(self, message: Message, other_fields: dict[str, Any]) -> bool:
47
 		"""
47
 		"""
48
 		Whether a message matches this expression. other_fields are additional
48
 		Whether a message matches this expression. other_fields are additional
49
 		fields that can be queried not contained in the message itself.
49
 		fields that can be queried not contained in the message itself.
57
 	"""
57
 	"""
58
 	def __init__(self, field: str, operator: str, value: Any):
58
 	def __init__(self, field: str, operator: str, value: Any):
59
 		super().__init__()
59
 		super().__init__()
60
-		self.field = field
61
-		self.operator = operator
62
-		self.value = value
60
+		self.field: str = field
61
+		self.operator: str = operator
62
+		self.value: Any = value
63
 
63
 
64
 	def __field_value(self, message: Message, other_fields: dict[str: Any]) -> Any:
64
 	def __field_value(self, message: Message, other_fields: dict[str: Any]) -> Any:
65
 		if self.field in ('content.markdown', 'content'):
65
 		if self.field in ('content.markdown', 'content'):
149
 	the given actions should be performed.
149
 	the given actions should be performed.
150
 	"""
150
 	"""
151
 
151
 
152
-	DEFAULT_PRIORITY = 100
152
+	DEFAULT_PRIORITY: int = 100
153
 
153
 
154
 	def __init__(self,
154
 	def __init__(self,
155
 			name: str,
155
 			name: str,
157
 			expression: PatternExpression,
157
 			expression: PatternExpression,
158
 			original: str,
158
 			original: str,
159
 			priority: int = DEFAULT_PRIORITY):
159
 			priority: int = DEFAULT_PRIORITY):
160
-		self.name = name
161
-		self.actions = list(actions)  # PatternAction[]
162
-		self.expression = expression
163
-		self.original = original
164
-		self.priority = priority
160
+		self.name: str = name
161
+		self.actions: list[PatternAction] = list(actions)  # PatternAction[]
162
+		self.expression: PatternExpression = expression
163
+		self.original: str = original
164
+		self.priority: int = priority
165
 
165
 
166
 	def check_deprecations(self) -> None:
166
 	def check_deprecations(self) -> None:
167
 		"""
167
 		"""
181
 			for oper in c.operands:
181
 			for oper in c.operands:
182
 				cls.__check_deprecations(oper)
182
 				cls.__check_deprecations(oper)
183
 
183
 
184
-	def to_json(self) -> dict:
184
+	def to_json(self) -> dict[str, Any]:
185
 		"""
185
 		"""
186
 		Returns a JSON representation of this statement.
186
 		Returns a JSON representation of this statement.
187
 		"""
187
 		"""
192
 		}
192
 		}
193
 
193
 
194
 	@classmethod
194
 	@classmethod
195
-	def from_json(cls, json: dict):
195
+	def from_json(cls, json: dict[str, Any]):
196
 		"""
196
 		"""
197
 		Gets a PatternStatement from its JSON representation.
197
 		Gets a PatternStatement from its JSON representation.
198
 		"""
198
 		"""
204
 	"""
204
 	"""
205
 	Parses a user-provided message filter statement into a PatternStatement.
205
 	Parses a user-provided message filter statement into a PatternStatement.
206
 	"""
206
 	"""
207
-	TYPE_FLOAT = 'float'
208
-	TYPE_ID = 'id'
209
-	TYPE_INT = 'int'
210
-	TYPE_MEMBER = 'Member'
211
-	TYPE_REGEX = 'regex'
212
-	TYPE_TEXT = 'text'
213
-	TYPE_TIMESPAN = 'timespan'
207
+	TYPE_FLOAT: str = 'float'
208
+	TYPE_ID: str = 'id'
209
+	TYPE_INT: str = 'int'
210
+	TYPE_MEMBER: str = 'Member'
211
+	TYPE_REGEX: str = 'regex'
212
+	TYPE_TEXT: str = 'text'
213
+	TYPE_TIMESPAN: str = 'timespan'
214
 
214
 
215
 	FIELD_TO_TYPE: dict[str, str] = {
215
 	FIELD_TO_TYPE: dict[str, str] = {
216
 		'author': TYPE_MEMBER,
216
 		'author': TYPE_MEMBER,
235
 
235
 
236
 	OPERATORS_IDENTITY: set[str] = set([ '==', '!=' ])
236
 	OPERATORS_IDENTITY: set[str] = set([ '==', '!=' ])
237
 	OPERATORS_COMPARISON: set[str] = set([ '<', '>', '<=', '>=' ])
237
 	OPERATORS_COMPARISON: set[str] = set([ '<', '>', '<=', '>=' ])
238
-	OPERATORS_NUMERIC = OPERATORS_IDENTITY | OPERATORS_COMPARISON
239
-	OPERATORS_TEXT = OPERATORS_IDENTITY | set([
238
+	OPERATORS_NUMERIC: set[str] = OPERATORS_IDENTITY | OPERATORS_COMPARISON
239
+	OPERATORS_TEXT: set[str] = OPERATORS_IDENTITY | set([
240
 		'contains', '!contains',
240
 		'contains', '!contains',
241
 		'containsword', '!containsword',
241
 		'containsword', '!containsword',
242
 		'matches', '!matches',
242
 		'matches', '!matches',
243
 	])
243
 	])
244
-	OPERATORS_ALL = OPERATORS_IDENTITY | OPERATORS_COMPARISON | OPERATORS_TEXT
244
+	OPERATORS_ALL: set[str] = OPERATORS_IDENTITY | OPERATORS_COMPARISON | OPERATORS_TEXT
245
 
245
 
246
 	TYPE_TO_OPERATORS: dict[str, set[str]] = {
246
 	TYPE_TO_OPERATORS: dict[str, set[str]] = {
247
 		TYPE_ID: OPERATORS_IDENTITY,
247
 		TYPE_ID: OPERATORS_IDENTITY,
252
 		TYPE_TIMESPAN: OPERATORS_NUMERIC,
252
 		TYPE_TIMESPAN: OPERATORS_NUMERIC,
253
 	}
253
 	}
254
 
254
 
255
-	WHITESPACE_CHARS = ' \t\n\r'
256
-	STRING_QUOTE_CHARS = '\'"'
257
-	SYMBOL_CHARS = 'abcdefghijklmnopqrstuvwxyz.'
258
-	VALUE_CHARS = '0123456789dhms<@!>'
259
-	OP_CHARS = '<=>!(),'
255
+	WHITESPACE_CHARS: str = ' \t\n\r'
256
+	STRING_QUOTE_CHARS: str = '\'"'
257
+	SYMBOL_CHARS: str = 'abcdefghijklmnopqrstuvwxyz.'
258
+	VALUE_CHARS: str = '0123456789dhms<@!>'
259
+	OP_CHARS: str = '<=>!(),'
260
 
260
 
261
-	MAX_EXPRESSION_NESTING = 8
261
+	MAX_EXPRESSION_NESTING: int = 8
262
 
262
 
263
 	@classmethod
263
 	@classmethod
264
 	def expression_str_from_context(cls, context: Context, name: str) -> str:
264
 	def expression_str_from_context(cls, context: Context, name: str) -> str:
265
 		"""
265
 		"""
266
 		Extracts the statement string from an "add" command context.
266
 		Extracts the statement string from an "add" command context.
267
 		"""
267
 		"""
268
-		pattern_str = context.message.content
268
+		pattern_str: str = context.message.content
269
 		command_chain = [ name ]
269
 		command_chain = [ name ]
270
 		cmd = context.command
270
 		cmd = context.command
271
 		while cmd:
271
 		while cmd:
285
 		Parses a user-provided message filter statement into a PatternStatement.
285
 		Parses a user-provided message filter statement into a PatternStatement.
286
 		Raises PatternError on failure.
286
 		Raises PatternError on failure.
287
 		"""
287
 		"""
288
-		tokens = cls.__tokenize(statement)
289
-		token_index = 0
288
+		tokens: list[str] = cls.__tokenize(statement)
289
+		token_index: int = 0
290
 		actions, token_index = cls.__read_actions(tokens, token_index)
290
 		actions, token_index = cls.__read_actions(tokens, token_index)
291
 		expression, token_index = cls.__read_expression(tokens, token_index)
291
 		expression, token_index = cls.__read_expression(tokens, token_index)
292
 		return PatternStatement(name, actions, expression, statement)
292
 		return PatternStatement(name, actions, expression, statement)
297
 		Converts a message filter statement into a list of tokens.
297
 		Converts a message filter statement into a list of tokens.
298
 		"""
298
 		"""
299
 		tokens: list[str] = []
299
 		tokens: list[str] = []
300
-		in_quote = False
301
-		in_escape = False
302
-		all_token_types = set([ 'sym', 'op', 'val' ])
303
-		possible_token_types = set(all_token_types)
304
-		current_token = ''
300
+		in_quote: bool = False
301
+		in_escape: bool = False
302
+		all_token_types: set[str] = set([ 'sym', 'op', 'val' ])
303
+		possible_token_types: set[str] = set(all_token_types)
304
+		current_token: str = ''
305
 		for ch in statement:
305
 		for ch in statement:
306
 			if in_quote:
306
 			if in_quote:
307
 				if in_escape:
307
 				if in_escape:

+ 27
- 25
rocketbot/utils.py Просмотреть файл

3
 """
3
 """
4
 import re
4
 import re
5
 from datetime import datetime, timedelta
5
 from datetime import datetime, timedelta
6
+from typing import Any, Union
7
+
6
 from discord import Guild
8
 from discord import Guild
7
 from discord.ext.commands import Cog, Group
9
 from discord.ext.commands import Cog, Group
8
 
10
 
15
 	"1h30m"
17
 	"1h30m"
16
 	"73d18h22m52s"
18
 	"73d18h22m52s"
17
 	"""
19
 	"""
18
-	p = re.compile('^(?:[0-9]+[dhms])+$')
20
+	p: re.Pattern = re.compile('^(?:[0-9]+[dhms])+$')
19
 	if p.match(s) is None:
21
 	if p.match(s) is None:
20
 		raise ValueError("Illegal timespan value '{s}'.")
22
 		raise ValueError("Illegal timespan value '{s}'.")
21
 	p = re.compile('([0-9]+)([dhms])')
23
 	p = re.compile('([0-9]+)([dhms])')
22
-	days = 0
23
-	hours = 0
24
-	minutes = 0
25
-	seconds = 0
24
+	days: int = 0
25
+	hours: int = 0
26
+	minutes: int = 0
27
+	seconds: int = 0
26
 	for m in p.finditer(s):
28
 	for m in p.finditer(s):
27
 		scalar = int(m.group(1))
29
 		scalar = int(m.group(1))
28
 		unit = m.group(2)
30
 		unit = m.group(2)
40
 	"""
42
 	"""
41
 	Encodes a timedelta as a str. E.g. "3d2h"
43
 	Encodes a timedelta as a str. E.g. "3d2h"
42
 	"""
44
 	"""
43
-	d = td.days
44
-	h = td.seconds // 3600
45
-	m = (td.seconds // 60) % 60
46
-	s = td.seconds % 60
47
-	components = []
45
+	d: int = td.days
46
+	h: int = td.seconds // 3600
47
+	m: int = (td.seconds // 60) % 60
48
+	s: int = td.seconds % 60
49
+	components: list[str] = []
48
 	if d != 0:
50
 	if d != 0:
49
 		components.append(f'{d}d')
51
 		components.append(f'{d}d')
50
 	if h != 0:
52
 	if h != 0:
59
 	"""
61
 	"""
60
 	Formats a human-readable description of a time span. E.g. "3 days 2 hours".
62
 	Formats a human-readable description of a time span. E.g. "3 days 2 hours".
61
 	"""
63
 	"""
62
-	d = td.days
63
-	h = td.seconds // 3600
64
-	m = (td.seconds // 60) % 60
65
-	s = td.seconds % 60
66
-	components = []
64
+	d: int = td.days
65
+	h: int = td.seconds // 3600
66
+	m: int = (td.seconds // 60) % 60
67
+	s: int = td.seconds % 60
68
+	components: list[str] = []
67
 	if d != 0:
69
 	if d != 0:
68
 		components.append('1 day' if d == 1 else f'{d} days')
70
 		components.append('1 day' if d == 1 else f'{d} days')
69
 	if h != 0:
71
 	if h != 0:
84
 			return member
86
 			return member
85
 	return None
87
 	return None
86
 
88
 
87
-def bot_log(guild: Guild, cog_class, message: str) -> None:
89
+def bot_log(guild: Guild, cog_class, message: Any) -> None:
88
 	'Logs a message to stdout with time, cog, and guild info.'
90
 	'Logs a message to stdout with time, cog, and guild info.'
89
-	now = datetime.now() # local
91
+	now: datetime = datetime.now() # local
90
 	s = f'[{now.strftime("%Y-%m-%dT%H:%M:%S")}|'
92
 	s = f'[{now.strftime("%Y-%m-%dT%H:%M:%S")}|'
91
 	s += f'{cog_class.__name__}|' if cog_class else '-|'
93
 	s += f'{cog_class.__name__}|' if cog_class else '-|'
92
 	s += f'{guild.name}] ' if guild else '-] '
94
 	s += f'{guild.name}] ' if guild else '-] '
93
-	s += message
95
+	s += str(message)
94
 	print(s)
96
 	print(s)
95
 
97
 
96
-__QUOTE_CHARS = '\'"'
97
-__ID_REGEX = re.compile('^[0-9]{17,20}$')
98
-__MENTION_REGEX = re.compile('^<@[!&]([0-9]{17,20})>$')
99
-__USER_MENTION_REGEX = re.compile('^<@!([0-9]{17,20})>$')
100
-__ROLE_MENTION_REGEX = re.compile('^<@&([0-9]{17,20})>$')
98
+__QUOTE_CHARS: str = '\'"'
99
+__ID_REGEX: re.Pattern = re.compile('^[0-9]{17,20}$')
100
+__MENTION_REGEX: re.Pattern = re.compile('^<@[!&]([0-9]{17,20})>$')
101
+__USER_MENTION_REGEX: re.Pattern = re.compile('^<@!([0-9]{17,20})>$')
102
+__ROLE_MENTION_REGEX: re.Pattern = re.compile('^<@&([0-9]{17,20})>$')
101
 
103
 
102
 def is_user_id(val: str) -> bool:
104
 def is_user_id(val: str) -> bool:
103
 	'Tests if a string is in user/role ID format.'
105
 	'Tests if a string is in user/role ID format.'
122
 		return m.group(1)
124
 		return m.group(1)
123
 	raise ValueError(f'"{mention}" is not an @ user mention')
125
 	raise ValueError(f'"{mention}" is not an @ user mention')
124
 
126
 
125
-def mention_from_user_id(user_id: str) -> str:
127
+def mention_from_user_id(user_id: Union[str, int]) -> str:
126
 	'Returns a markdown user mention from a user id.'
128
 	'Returns a markdown user mention from a user id.'
127
 	return f'<@!{user_id}>'
129
 	return f'<@!{user_id}>'
128
 
130
 
129
-def mention_from_role_id(role_id: str) -> str:
131
+def mention_from_role_id(role_id: Union[str, int]) -> str:
130
 	'Returns a markdown role mention from a role id.'
132
 	'Returns a markdown role mention from a role id.'
131
 	return f'<@&{role_id}>'
133
 	return f'<@&{role_id}>'
132
 
134
 

Загрузка…
Отмена
Сохранить