anb-python-components 1.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. anb_python_components/__init__.py +1 -0
  2. anb_python_components/classes/__init__.py +1 -0
  3. anb_python_components/classes/action_state.py +211 -0
  4. anb_python_components/classes/directory.py +115 -0
  5. anb_python_components/classes/file.py +226 -0
  6. anb_python_components/classes/shortcode_parser.py +195 -0
  7. anb_python_components/custom_types/__init__.py +3 -0
  8. anb_python_components/custom_types/guid.py +169 -0
  9. anb_python_components/custom_types/object_array.py +625 -0
  10. anb_python_components/custom_types/shortcode_attributes.py +128 -0
  11. anb_python_components/custom_types/two_dim_size.py +413 -0
  12. anb_python_components/custom_types/version_info.py +461 -0
  13. anb_python_components/enums/__init__.py +1 -0
  14. anb_python_components/enums/message_type.py +44 -0
  15. anb_python_components/enums/not_bool_action.py +24 -0
  16. anb_python_components/enums/type_copy_strategy.py +47 -0
  17. anb_python_components/exceptions/__init__.py +1 -0
  18. anb_python_components/exceptions/wrong_type_exception.py +20 -0
  19. anb_python_components/extensions/__init__.py +1 -0
  20. anb_python_components/extensions/array_extension.py +34 -0
  21. anb_python_components/extensions/bool_extension.py +87 -0
  22. anb_python_components/extensions/string_extension.py +259 -0
  23. anb_python_components/extensions/string_extension_constant.py +80 -0
  24. anb_python_components/extensions/type_extension.py +112 -0
  25. anb_python_components/models/__init__.py +1 -0
  26. anb_python_components/models/action_state_message.py +27 -0
  27. anb_python_components/models/shortcode_model.py +31 -0
  28. anb_python_components-1.2.1.dist-info/METADATA +12 -0
  29. anb_python_components-1.2.1.dist-info/RECORD +48 -0
  30. anb_python_components-1.2.1.dist-info/WHEEL +5 -0
  31. anb_python_components-1.2.1.dist-info/licenses/LICENSE +235 -0
  32. anb_python_components-1.2.1.dist-info/top_level.txt +2 -0
  33. tests/__init__.py +1 -0
  34. tests/classes/__init__.py +1 -0
  35. tests/classes/action_state_test.py +138 -0
  36. tests/classes/directory_test.py +19 -0
  37. tests/classes/file_test.py +79 -0
  38. tests/classes/shortcode_parser_test.py +105 -0
  39. tests/custom_types/__init__.py +1 -0
  40. tests/custom_types/guid_test.py +14 -0
  41. tests/custom_types/object_array_test.py +160 -0
  42. tests/custom_types/two_dim_size_test.py +37 -0
  43. tests/custom_types/version_info_test.py +51 -0
  44. tests/extensions/__init__.py +1 -0
  45. tests/extensions/array_extension_test.py +21 -0
  46. tests/extensions/bool_extension_test.py +19 -0
  47. tests/extensions/string_extension_test.py +55 -0
  48. tests/extensions/type_extension_test.py +38 -0
@@ -0,0 +1,128 @@
1
+ # anb_python_components/custom_types/shortcode_attributes.py
2
+
3
+ class ShortCodeAttributes:
4
+ """
5
+ Атрибуты шорткода.
6
+ """
7
+
8
+ # Словарь атрибутов шорткода (ключ - имя атрибута, значение - значение атрибута)
9
+ __attributes: dict[str, str] = {}
10
+
11
+ def __init__ (self, attributes: dict[str, str] | str | None = None):
12
+ """
13
+ Конструктор.
14
+ :param attributes: Атрибуты шорткода в виде словаря, строки или None. В случае None - атрибуты будут заданы пустым словарем.
15
+ По умолчанию None.
16
+ """
17
+ # Инициализируем словарь
18
+ self.__attributes = {}
19
+
20
+ # Если атрибуты не заданы
21
+ if attributes is None:
22
+ # - то выходим из функции
23
+ return
24
+
25
+ # Если атрибуты заданы как строка
26
+ if isinstance(attributes, str):
27
+ # - разделяем параметры по пробелам
28
+ pairs = attributes.split()
29
+
30
+ # - для каждого параметра
31
+ for pair in pairs:
32
+ # -- разбиваем его на ключ и значение
33
+ key_value = pair.split('=', 1)
34
+
35
+ # -- если количество элементов не равно 2
36
+ if len(key_value) != 2:
37
+ # --- то пропускаем
38
+ continue
39
+
40
+ # -- задаем ключ и знач
41
+ key, value = key_value
42
+
43
+ # -- записываем ключ и значение в словарь, предварительно убирая кавычки и пробелы с обеих сторон
44
+ self.__attributes[key.lstrip().rstrip()] = value.lstrip(' "').rstrip('" ')
45
+
46
+ # Если атрибуты заданы как словарь
47
+ if isinstance(attributes, dict):
48
+ # - для каждого ключа и значения
49
+ for key, value in attributes.items():
50
+ # -- записываем ключ и значение в словарь
51
+ self.__attributes[key] = value
52
+
53
+ @staticmethod
54
+ def parse (param_string: str) -> 'ShortCodeAttributes':
55
+ """
56
+ Преобразует строку параметров в словарь.
57
+
58
+ :param param_string: Строка параметров
59
+ :return: Словарь параметров
60
+ """
61
+ # Возвращаем словарь параметров
62
+ return ShortCodeAttributes(param_string)
63
+
64
+ def __str__ (self) -> str:
65
+ """
66
+ Преобразует атрибуты в строку.
67
+ :return: Строка атрибутов.
68
+ """
69
+ # Если атрибуты не заданы
70
+ if not self.__attributes:
71
+ # - то возвращаем пустую строку
72
+ return ''
73
+
74
+ # Возвращаем строку
75
+ return ' '.join([f'{key}="{value}"' for key, value in self.__attributes.items()])
76
+
77
+ def __iter__ (self):
78
+ """
79
+ Итератор.
80
+ :return: Итератор.
81
+ """
82
+ return iter(self.__attributes.items())
83
+
84
+ def __getitem__ (self, key: str) -> str | None:
85
+ """
86
+ Доступ к атрибутам по ключу.
87
+ :param key: Ключ атрибута.
88
+ :return: Значение атрибута или None, если атрибут не найден.
89
+ """
90
+ return self.__attributes[key] if key in self.__attributes else None
91
+
92
+ def __setitem__ (self, key: str, value: str):
93
+ """
94
+ Установить значение атрибута.
95
+ :param key: Ключ атрибута.
96
+ :param value: Значение атрибута.
97
+ :return: None
98
+ """
99
+ self.__attributes[key] = value
100
+
101
+ def __contains__ (self, key: str) -> bool:
102
+ """
103
+ Проверяет наличие атрибута.
104
+ :param key: Ключ атрибута.
105
+ :return: True, если атрибут найден, иначе False.
106
+ """
107
+ return True if key in self.__attributes else False
108
+
109
+ def __len__ (self) -> int:
110
+ """
111
+ Количество атрибутов.
112
+ :return: Количество атрибутов.
113
+ """
114
+ return len(self.__attributes)
115
+
116
+ def keys (self) -> list[str]:
117
+ """
118
+ Возвращает список ключей атрибутов.
119
+ :return: Список ключей атрибутов.
120
+ """
121
+ return list(self.__attributes.keys())
122
+
123
+ def values (self) -> list[str]:
124
+ """
125
+ Возвращает список значений атрибутов.
126
+ :return: Список значений атрибутов.
127
+ """
128
+ return list(self.__attributes.values())
@@ -0,0 +1,413 @@
1
+ # anb_python_components/custom_types/two_dim_size.py
2
+
3
+ class TwoDimSize:
4
+ """
5
+ Класс TwoDimSize для представления размеров двухмерного объекта.
6
+ """
7
+
8
+ # Разделитель частей по умолчанию.
9
+ DEFAULT_DELIMITER: str = ':'
10
+
11
+ @staticmethod
12
+ def _get_valid_num (num: int, min_num: int | None = 0, max_num: int | None = None) -> int:
13
+ """
14
+ Получает корректное значение представленного числа.
15
+ :param num: Проверяемое значение.
16
+ :param min_num: Минимальное значение (по умолчанию 0). Если None, то считается, что минимальное значение не ограничено.
17
+ :param max_num: Максимальное значение (по умолчанию None). Если None, то считается, что максимальное значение не ограничено.
18
+ :return: Корректное значение.
19
+ """
20
+ # Флаг, разрешающий или запрещающий отрицательные значения
21
+ is_negative_allowed = min_num < 0 or min_num is None
22
+
23
+ # Безлимитные значения
24
+ # - для минимального значения
25
+ is_unlimited_min = min_num is None
26
+ # - для максимального значения
27
+ is_unlimited_max = max_num is None
28
+
29
+ # Если значение отрицательное, а отрицательные значения запрещены
30
+ if num < 0 and not is_negative_allowed:
31
+ # - то возвращаю 0
32
+ return 0
33
+
34
+ # Если значение вышло за ограничения минимальное значения
35
+ if not is_unlimited_min and num < min_num:
36
+ # - то возвращаю минимальное значение
37
+ return min_num
38
+
39
+ # Если значение вышло за ограничения максимальное значения
40
+ if not is_unlimited_max and num > max_num:
41
+ # - то возвращаю максимальное значение
42
+ return max_num
43
+
44
+ # Если значение корректно, то возвращаю его
45
+ return num
46
+
47
+ def __init__ (
48
+ self, width: int = 0, height: int = 0, min_width: int | None = 0, max_width: int | None = None,
49
+ min_height: int | None = 0, max_height: int | None = None
50
+ ):
51
+ """
52
+ Инициализирует объект TwoDimSize.
53
+ :param width: Ширина (по умолчанию 0).
54
+ :param height: Высота (по умолчанию 0).
55
+ :param min_width: Минимальная ширина (по умолчанию 0). Если None, то считается, что минимальная ширина не ограничена.
56
+ :param max_width: Максимальная ширина (по умолчанию None). Если None, то считается, что максимальная ширина не ограничена.
57
+ :param min_height: Минимальная высота (по умолчанию 0). Если None, то считается, что минимальная высота не ограничена.
58
+ :param max_height: Максимальная высота (по умолчанию None). Если None, то считается, что максимальная высота не ограничена.
59
+ """
60
+
61
+ # Если некорректно заданы минимальные и максимальные значения ширины
62
+ if min_width is not None and max_width is not None and min_width > max_width:
63
+ # - то выбрасываю исключение
64
+ raise ValueError("Минимальная ширина не может быть больше максимальной.")
65
+
66
+ # Если некорректно заданы минимальные и максимальные значения высоты
67
+ elif min_height is not None and max_height is not None and min_height > max_height:
68
+ # - то выбрасываю исключение
69
+ raise ValueError("Минимальная высота не может быть больше максимальной.")
70
+
71
+ # Задаю минимальные и максимальные
72
+ # - для ширины
73
+ # -- минимальное
74
+ self._min_width: int | None = min_width
75
+ # -- максимальное
76
+ self._max_width: int | None = max_width
77
+ # - для высоты
78
+ # -- минимальное
79
+ self._min_height: int | None = min_height
80
+ # -- максимальное
81
+ self._max_height: int | None = max_height
82
+
83
+ # Устанавливаю ширину
84
+ self._width: int = self._get_valid_num(width, min_width, max_width)
85
+
86
+ # Устанавливаю высоту
87
+ self._height: int = self._get_valid_num(height, min_height, max_height)
88
+
89
+ @property
90
+ def min_width (self) -> int:
91
+ """
92
+ Минимальная ширина.
93
+ :return: Значение минимальной ширины.
94
+ """
95
+ return self._min_width
96
+
97
+ @min_width.setter
98
+ def min_width (self, value: int):
99
+ """
100
+ Устанавливает минимальную ширину и пересчитывает ширину, если она выходит за новые ограничения.
101
+ :param value: Новое значение минимальной ширины.
102
+ :return: None
103
+ """
104
+ # Если максимальная ширина ограничена и значение минимальной ширины больше максимальной ширины,
105
+ # то устанавливаю минимальную ширину равной максимальной ширине, иначе возвращаю значение
106
+ self._min_width = self._max_width if self._max_width is not None and value > self._max_width else value
107
+
108
+ # При изменении минимальной ширины пересчитываю ширину
109
+ self.width = self._width
110
+
111
+ @min_width.deleter
112
+ def min_width (self):
113
+ """
114
+ Удаляет минимальную ширину и устанавливает минимальную ширину в 0.
115
+ :return: None
116
+ """
117
+ self._min_width = 0
118
+
119
+ @property
120
+ def max_width (self) -> int:
121
+ """
122
+ Максимальная ширина.
123
+ :return: Значение максимальной ширины.
124
+ """
125
+ return self._max_width
126
+
127
+ @max_width.setter
128
+ def max_width (self, value: int):
129
+ """
130
+ Устанавливает максимальную ширину и пересчитывает ширину, если она выходит за новые ограничения.
131
+ :param value: Новое значение максимальной ширины.
132
+ :return: None
133
+ """
134
+ # Если минимальная ширина ограничена и значение максимальной ширины меньше минимальной ширины,
135
+ # то устанавливаю максимальную ширину равной минимальной ширине, иначе возвращаю значение
136
+ self._max_width = self._min_width if self._min_width is not None and value < self._min_width else value
137
+
138
+ # При изменении максимальной ширины пересчитываю ширину
139
+ self.width = self._width
140
+
141
+ @max_width.deleter
142
+ def max_width (self):
143
+ """
144
+ Удаляет максимальную ширину.
145
+ :return: None
146
+ """
147
+ self._max_width = None
148
+
149
+ @property
150
+ def min_height (self) -> int:
151
+ """
152
+ Минимальная высота.
153
+ :return: Значение минимальной высоты.
154
+ """
155
+ return self._min_height
156
+
157
+ @min_height.setter
158
+ def min_height (self, value: int):
159
+ """
160
+ Устанавливает минимальную высоту и пересчитывает высоту, если она выходит за новые ограничения.
161
+ :param value: Новое значение минимальной высоты.
162
+ :return: None
163
+ """
164
+ # Если максимальная высота ограничена и значение минимальной высоты больше максимальной высоты,
165
+ # то устанавливаю минимальную высоту равной максимальной высоте, иначе возвращаю значение
166
+ self._min_height = self._max_height if self._max_height is not None and value > self._max_height else value
167
+
168
+ # При изменении минимальной высоты пересчитываю высоту
169
+ self.height = self._height
170
+
171
+ @min_height.deleter
172
+ def min_height (self):
173
+ """
174
+ Удаляет минимальную высоту и устанавливает минимальную высоту в 0.
175
+ :return: None
176
+ """
177
+ self._min_height = 0
178
+
179
+ @property
180
+ def max_height (self) -> int:
181
+ """
182
+ Максимальная высота.
183
+ :return: Значение максимальной высоты.
184
+ """
185
+ return self._max_height
186
+
187
+ @max_height.setter
188
+ def max_height (self, value: int):
189
+ """
190
+ Устанавливает максимальную высоту и пересчитывает высоту, если она выходит за новые ограничения.
191
+ :param value: Новое значение максимальной высоты.
192
+ :return: None
193
+ """
194
+ # Если минимальная высота ограничена и значение максимальной высоты меньше минимальной высоты,
195
+ # то устанавливаю максимальную высоту равной минимальной высоте, иначе возвращаю значение
196
+ self._max_height = self._min_height if self._min_height is not None and value < self._min_height else value
197
+
198
+ # При изменении максимальной высоты пересчитываю высоту
199
+ self.height = self._height
200
+
201
+ @max_height.deleter
202
+ def max_height (self):
203
+ """
204
+ Удаляет максимальную высоту.
205
+ :return: None
206
+ """
207
+ self._max_height = None
208
+
209
+ @property
210
+ def width (self) -> int:
211
+ """
212
+ Ширина.
213
+ :return: Установленная ширина.
214
+ """
215
+ return self._width
216
+
217
+ @width.setter
218
+ def width (self, value: int):
219
+ """
220
+ Устанавливает ширину.
221
+ :param value: Новое значение ширины.
222
+ :return: None
223
+ """
224
+ self._width = self._get_valid_num(value, self.min_width, self.max_width)
225
+
226
+ @width.deleter
227
+ def width (self):
228
+ """
229
+ Удаляет ширину.
230
+ :return: None
231
+ """
232
+ self._width = 0 if self._min_width is None else self._min_width
233
+
234
+ @property
235
+ def height (self) -> int:
236
+ """
237
+ Высота.
238
+ :return: Установленная высота.
239
+ """
240
+ return self._height
241
+
242
+ @height.setter
243
+ def height (self, value: int):
244
+ """
245
+ Устанавливает высоту.
246
+ :param value: Новое значение высоты.
247
+ :return: None
248
+ """
249
+ self._height = self._get_valid_num(value, self.min_height, self.max_height)
250
+
251
+ @height.deleter
252
+ def height (self):
253
+ """
254
+ Удаляет высоту.
255
+ :return: None
256
+ """
257
+ self._height = 0 if self._min_height is None else self._min_height
258
+
259
+ def as_str (self, delimiter: str = DEFAULT_DELIMITER) -> str:
260
+ """
261
+ Возвращает строковое представление объекта TwoDimSize в формате "ширина:высота".
262
+ :param delimiter: Разделитель частей ширины и высоты (по умолчанию ":").
263
+ :return: Строковое представление объекта TwoDimSize.
264
+ """
265
+ return f"{self.width}{delimiter}{self.height}"
266
+
267
+ def __str__ (self) -> str:
268
+ """
269
+ Строковое представление объекта TwoDimSize.
270
+ :return: Строковое представление объекта TwoDimSize.
271
+ """
272
+ return self.as_str(TwoDimSize.DEFAULT_DELIMITER)
273
+
274
+ def as_tuple (self) -> tuple[int, int]:
275
+ """
276
+ Возвращает кортеж (ширина, высота).
277
+ :return: Кортеж (ширина, высота).
278
+ """
279
+ return self.width, self.height
280
+
281
+ def __eq__ (self, other: object) -> bool:
282
+ """
283
+ Сравнивает объект TwoDimSize с другим объектом.
284
+ :param other: Объект для сравнения.
285
+ :return: True, если объекты равны, иначе False.
286
+ """
287
+ # Если сравниваем с объектом TwoDimSize
288
+ if isinstance(other, TwoDimSize):
289
+ # - то сравниваю ширину и высоту
290
+ return self.width == other.width and self.height == other.height
291
+ else:
292
+ # - иначе возвращаю False
293
+ return False
294
+
295
+ def __repr__ (self) -> str:
296
+ """
297
+ Строковое представление объекта TwoDimSize для отладки.
298
+ :return: Строковое представление объекта TwoDimSize для отладки.
299
+ """
300
+ return f"TwoDimSize({self.width}, {self.height}, min_width={self.min_width}, max_width={self.max_width}, min_height={self.min_height}, max_height={self.max_height})"
301
+
302
+ def __hash__ (self) -> int:
303
+ """
304
+ Хэш объекта TwoDimSize.
305
+ :return: Хэш объекта TwoDimSize.
306
+ """
307
+ return hash((self.width, self.height))
308
+
309
+ def __copy__ (self) -> 'TwoDimSize':
310
+ """
311
+ Копирует объект TwoDimSize.
312
+ :return: Копия объекта TwoDimSize.
313
+ """
314
+ return TwoDimSize(self.width, self.height, self.min_width, self.max_width, self.min_height, self.max_height)
315
+
316
+ def __deepcopy__ (self, memo: dict) -> 'TwoDimSize':
317
+ """
318
+ Глубокое копирование объекта TwoDimSize.
319
+ :param memo: Словарь для хранения копий объектов.
320
+ :return: Глубокая копия объекта TwoDimSize.
321
+ """
322
+ # Если объект уже был скопирован
323
+ if id(self) in memo:
324
+ # - то возвращаю его копию
325
+ return memo[id(self)]
326
+ else:
327
+ # - иначе создаю копию объекта
328
+ memo[id(self)] = copy = TwoDimSize(
329
+ self.width, self.height, self.min_width, self.max_width, self.min_height, self.max_height
330
+ )
331
+ # - и возвращаю её
332
+ return copy
333
+
334
+ def __add__ (self, other: 'TwoDimSize') -> 'TwoDimSize':
335
+ """
336
+ Складывает объект TwoDimSize с другим объектом TwoDimSize.
337
+ :param other: Объект TwoDimSize для сложения.
338
+ :return: Объект TwoDimSize, полученный после сложения.
339
+ """
340
+ # Если другой объект является объектом TwoDimSize
341
+ if isinstance(other, TwoDimSize):
342
+ # - то складываю ширину и высоту с объектом TwoDimSize и возвращаю результат в виде объекта TwoDimSize
343
+ return TwoDimSize(
344
+ self.width + other.width, self.height + other.height, self.min_width, self.max_width,
345
+ self.min_height, self.max_height
346
+ )
347
+ else:
348
+ # - иначе выбрасываю исключение
349
+ raise TypeError("Невозможно сложить два объекта разных типов.")
350
+
351
+ def __mul__ (self, other: int) -> 'TwoDimSize':
352
+ """
353
+ Умножает объект TwoDimSize на целое число.
354
+ :param other: Целое число для умножения.
355
+ :return: Объект TwoDimSize, полученный после умножения.
356
+ """
357
+ # Если другой объект является целым числом
358
+ if isinstance(other, int):
359
+ # - то перемножаю ширину и высоту на целое число и возвращаю результат в виде объекта TwoDimSize
360
+ return TwoDimSize(
361
+ self.width * other, self.height * other, self.min_width, self.max_width, self.min_height,
362
+ self.max_height
363
+ )
364
+ else:
365
+ # - иначе выбрасываю исключение
366
+ raise TypeError("Невозможно перемножить объект TwoDimSize на другой объект.")
367
+
368
+ @staticmethod
369
+ def parse (
370
+ text: str, delimiter: str = DEFAULT_DELIMITER, min_width: int | None = 0, max_width: int | None = None,
371
+ min_height: int | None = 0, max_height: int | None = None
372
+ ) -> 'TwoDimSize':
373
+ """
374
+ Создает объект TwoDimSize из строки.
375
+ :param max_height: Минимальная высота (по умолчанию 0). Если None, то считается, что минимальная высота не ограничена.
376
+ :param min_height: Максимальная высота (по умолчанию None). Если None, то считается, что максимальная высота не ограничена.
377
+ :param max_width: Максимальная ширина (по умолчанию None). Если None, то считается, что максимальная ширина не ограничена.
378
+ :param min_width: Минимальная ширина (по умолчанию 0). Если None, то считается, что минимальная ширина не ограничена.
379
+ :param text: Строка для создания объекта TwoDimSize.
380
+ :param delimiter: Разделитель частей ширины и высоты (по умолчанию ":").
381
+ :return: Объект TwoDimSize.
382
+ :raises ValueError: Если строка имеет неверный формат.
383
+ :raises TypeError: При попытке преобразовать строку в объект int (ширину или высоту).
384
+ """
385
+ # Разделяю значения
386
+ split_sizes = text.split(delimiter)
387
+
388
+ # Проверяю, что массив имеет ровно два элемента
389
+ if len(split_sizes) != 2:
390
+ # - иначе выбрасываю исключение
391
+ raise ValueError("Неверный формат строки для TwoDimSize.")
392
+
393
+ # Получаю ширину и высоту
394
+ width, height = split_sizes
395
+
396
+ # Проверяю, что ширина получена
397
+ if width:
398
+ # - и перевожу ее в целое число
399
+ width = int(width)
400
+ else:
401
+ # - иначе выбрасываю исключение
402
+ raise ValueError("Неверный формат ширины в строке для TwoDimSize.")
403
+
404
+ # Проверяю, что высота получена
405
+ if height:
406
+ # - и перевожу ее в целое число
407
+ height = int(height)
408
+ else:
409
+ # - иначе выбрасываю исключение
410
+ raise ValueError("Неверный формат высоты в строке для TwoDimSize.")
411
+
412
+ # Если все проверки пройдены успешно, то создаю объект TwoDimSize с заданными шириной и высотой и возвращаю его
413
+ return TwoDimSize(width, height, min_width, max_width, min_height, max_height)