anb-python-components 1.2.1__tar.gz → 1.3.0__tar.gz
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.
- anb_python_components-1.3.0/PKG-INFO +146 -0
- anb_python_components-1.3.0/anb_python_components/__init__.py +55 -0
- anb_python_components-1.3.0/anb_python_components/classes/__init__.py +7 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/classes/action_state.py +2 -1
- anb_python_components-1.3.0/anb_python_components/classes/interface.py +192 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/classes/shortcode_parser.py +1 -1
- anb_python_components-1.3.0/anb_python_components/custom_types/__init__.py +7 -0
- anb_python_components-1.3.0/anb_python_components/decorators/__init__.py +2 -0
- anb_python_components-1.3.0/anb_python_components/decorators/interface_decorators.py +74 -0
- anb_python_components-1.3.0/anb_python_components/enums/__init__.py +5 -0
- anb_python_components-1.3.0/anb_python_components/exceptions/__init__.py +3 -0
- anb_python_components-1.3.0/anb_python_components/extensions/__init__.py +6 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/extensions/string_extension_constant.py +0 -1
- anb_python_components-1.3.0/anb_python_components/models/__init__.py +4 -0
- anb_python_components-1.3.0/anb_python_components.egg-info/PKG-INFO +146 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components.egg-info/SOURCES.txt +5 -0
- anb_python_components-1.3.0/anb_python_components.egg-info/not-zip-safe +1 -0
- anb_python_components-1.3.0/setup.py +38 -0
- anb_python_components-1.3.0/tests/classes/interface_test.py +47 -0
- anb_python_components-1.2.1/PKG-INFO +0 -12
- anb_python_components-1.2.1/anb_python_components/__init__.py +0 -1
- anb_python_components-1.2.1/anb_python_components/classes/__init__.py +0 -1
- anb_python_components-1.2.1/anb_python_components/custom_types/__init__.py +0 -3
- anb_python_components-1.2.1/anb_python_components/enums/__init__.py +0 -1
- anb_python_components-1.2.1/anb_python_components/exceptions/__init__.py +0 -1
- anb_python_components-1.2.1/anb_python_components/extensions/__init__.py +0 -1
- anb_python_components-1.2.1/anb_python_components/models/__init__.py +0 -1
- anb_python_components-1.2.1/anb_python_components.egg-info/PKG-INFO +0 -12
- anb_python_components-1.2.1/setup.py +0 -26
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/LICENSE +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/README.md +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/classes/directory.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/classes/file.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/custom_types/guid.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/custom_types/object_array.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/custom_types/shortcode_attributes.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/custom_types/two_dim_size.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/custom_types/version_info.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/enums/message_type.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/enums/not_bool_action.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/enums/type_copy_strategy.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/exceptions/wrong_type_exception.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/extensions/array_extension.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/extensions/bool_extension.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/extensions/string_extension.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/extensions/type_extension.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/models/action_state_message.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/models/shortcode_model.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components.egg-info/dependency_links.txt +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components.egg-info/top_level.txt +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/setup.cfg +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/__init__.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/classes/__init__.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/classes/action_state_test.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/classes/directory_test.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/classes/file_test.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/classes/shortcode_parser_test.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/custom_types/__init__.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/custom_types/guid_test.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/custom_types/object_array_test.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/custom_types/two_dim_size_test.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/custom_types/version_info_test.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/extensions/__init__.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/extensions/array_extension_test.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/extensions/bool_extension_test.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/extensions/string_extension_test.py +0 -0
- {anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/extensions/type_extension_test.py +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: anb_python_components
|
|
3
|
+
Version: 1.3.0
|
|
4
|
+
Summary: Набор компонентов Python, которые упрощают разработку / A set of Python components that simplify development
|
|
5
|
+
Home-page: https://gitflic.ru/project/babaev-an/anb-python-components
|
|
6
|
+
Author: Александр Бабаев
|
|
7
|
+
Author-email: contact_with_us@babaev-an.ru
|
|
8
|
+
Project-URL: Documentation, https://gitflic.ru/project/babaev-an/anb-python-components/wiki
|
|
9
|
+
Project-URL: Source, https://gitflic.ru/project/babaev-an/anb-python-components
|
|
10
|
+
Project-URL: Tracker, https://gitflic.ru/project/babaev-an/anb-python-components/issue?page=0
|
|
11
|
+
Keywords: python components development utils
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.14.0
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Dynamic: author
|
|
23
|
+
Dynamic: author-email
|
|
24
|
+
Dynamic: classifier
|
|
25
|
+
Dynamic: description
|
|
26
|
+
Dynamic: description-content-type
|
|
27
|
+
Dynamic: home-page
|
|
28
|
+
Dynamic: keywords
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
Dynamic: project-url
|
|
31
|
+
Dynamic: requires-python
|
|
32
|
+
Dynamic: summary
|
|
33
|
+
|
|
34
|
+
# 📌🇷🇺 Русская версия
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Набор компонентов Python для упрощения разработки приложений
|
|
39
|
+
|
|
40
|
+
**ANB Python Components** — это библиотека полезных классов и модулей, предназначенная для ускорения процесса разработки
|
|
41
|
+
программного обеспечения на языке программирования Python. Библиотека включает широкий спектр инструментов, облегчающих
|
|
42
|
+
выполнение повседневных задач разработчика, от обработки файлов и сетевых запросов до автоматизации тестирования и
|
|
43
|
+
интеграции с популярными фреймворками.
|
|
44
|
+
|
|
45
|
+
### ✅ Основные возможности:
|
|
46
|
+
|
|
47
|
+
- Удобные инструменты для работы с файлами и каталогами.
|
|
48
|
+
- Классы для работы с файлами и директориями.
|
|
49
|
+
- Классы для удобной передачи состояния.
|
|
50
|
+
- Новые
|
|
51
|
+
типы [GUID](https://gitflic.ru/project/babaev-an/anb-python-components/wiki/page?file=class_desc%2Ftypes%2Fguid.md),
|
|
52
|
+
[TwoDimSize](https://gitflic.ru/project/babaev-an/anb-python-components/wiki/page?file=class_desc%2Ftypes%2Ftwo_dim_size.md)
|
|
53
|
+
и [VersionInfo](https://gitflic.ru/project/babaev-an/anb-python-components/wiki/page?file=class_desc%2Ftypes%2Fversion_info.md).
|
|
54
|
+
- Расширение массивов, типа `bool`, типа `GUID`, типа `str`.
|
|
55
|
+
- Класс для перевода любого типа в строку и наоборот.
|
|
56
|
+
|
|
57
|
+
### ⚙️ Установка и использование:
|
|
58
|
+
|
|
59
|
+
Установить пакет можно через pip:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install anb-python-components --index-url https://registry.gitflic.ru/project/babaev-an/anb-python-components/package/-/pypi/simple
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Подключайте необходимые модули и начните пользоваться ими прямо сейчас:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from anb_python_components.custom_types.two_dim_size import TwoDimSize
|
|
69
|
+
|
|
70
|
+
# Пример использования
|
|
71
|
+
two_dim = TwoDimSize.parse('100x150', 'x')
|
|
72
|
+
|
|
73
|
+
# Теперь присваиваем какому-либо объекту
|
|
74
|
+
some_object_width = two_dim.width
|
|
75
|
+
some_object_height = two_dim.height
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 🛠️ Поддерживаемые технологии:
|
|
79
|
+
|
|
80
|
+
- `Python` версии 3.13.7 и выше
|
|
81
|
+
- Совместима с большинством популярных веб-фреймворков и библиотек Python
|
|
82
|
+
- Оптимизирован для работы с большими объемами данных и высоконагруженными приложениями
|
|
83
|
+
|
|
84
|
+
### 💬 Вопросы и поддержка:
|
|
85
|
+
|
|
86
|
+
Для подробной справки обратитесь к руководству по библиотеке в разделе документации:
|
|
87
|
+
|
|
88
|
+
🔗 Справочное руководство → [Документация библиотеки](https://gitflic.ru/project/babaev-an/anb-python-components/wiki)
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
# 📌🇬🇧 English Version
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Python Component Collection for Streamlining Application Development
|
|
97
|
+
|
|
98
|
+
**ANB Python Components** is a collection of useful classes and modules specifically tailored to accelerate the process
|
|
99
|
+
of developing software using the Python programming language. It offers a broad spectrum of tools that simplify everyday
|
|
100
|
+
developer tasks, from file manipulation and network requests to test automation and seamless integration with widely
|
|
101
|
+
used frameworks.
|
|
102
|
+
|
|
103
|
+
### ✅ Main Features:
|
|
104
|
+
|
|
105
|
+
- Handy tools for working with files and directories.
|
|
106
|
+
- Classes for handling files and folders.
|
|
107
|
+
- Classes for convenient state transfer.
|
|
108
|
+
- New custom_types such
|
|
109
|
+
as [GUID](https://gitflic.ru/project/babaev-an/anb-python-components/wiki/page?file=class_desc%2Ftypes%2Fguid.md), [TwoDimSize](https://gitflic.ru/project/babaev-an/anb-python-components/wiki/page?file=class_desc%2Ftypes%2Ftwo_dim_size.md),
|
|
110
|
+
and [VersionInfo](https://gitflic.ru/project/babaev-an/anb-python-components/wiki/page?file=class_desc%2Ftypes%2Fversion_info.md).
|
|
111
|
+
- Extensions for arrays, `bool`, `GUID`, and `str` custom_types.
|
|
112
|
+
- Class for converting any type into string representation and vice versa.
|
|
113
|
+
|
|
114
|
+
### ⚙️ Installation and Usage:
|
|
115
|
+
|
|
116
|
+
You can install this package via pip:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pip install anb-python-components --index-url https://registry.gitflic.ru/project/babaev-an/anb-python-components/package/-/pypi/simple
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Import required modules and start using them immediately:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from anb_python_components.custom_types.two_dim_size import TwoDimSize
|
|
126
|
+
|
|
127
|
+
# Example usage
|
|
128
|
+
two_dim = TwoDimSize.parse('100x150', 'x')
|
|
129
|
+
|
|
130
|
+
# Now assign it to some object
|
|
131
|
+
some_object_width = two_dim.width
|
|
132
|
+
some_object_height = two_dim.height
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 🛠️ Supported Technologies:
|
|
136
|
+
|
|
137
|
+
- **Python**: version 3.13.7 or higher
|
|
138
|
+
- Compatibility with most popular Python web frameworks and libraries
|
|
139
|
+
- Optimized for performance with large-scale datasets and highly loaded applications
|
|
140
|
+
|
|
141
|
+
### 💬 Questions and Support:
|
|
142
|
+
|
|
143
|
+
For comprehensive guidance and support, consult the library's documentation section:
|
|
144
|
+
|
|
145
|
+
🔗 Reference Guide → [Library Documentation](https://gitflic.ru/project/babaev-an/anb-python-components/wiki) (in Russian
|
|
146
|
+
Only)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# anb_python_components/__init__.py
|
|
2
|
+
|
|
3
|
+
# classes
|
|
4
|
+
from anb_python_components.classes.action_state import ActionState
|
|
5
|
+
from anb_python_components.classes.directory import Directory
|
|
6
|
+
from anb_python_components.classes.file import File
|
|
7
|
+
from anb_python_components.classes.interface import Interface
|
|
8
|
+
from anb_python_components.classes.shortcode_parser import ShortCodeParser
|
|
9
|
+
# custom_types
|
|
10
|
+
from anb_python_components.custom_types.guid import GUID
|
|
11
|
+
from anb_python_components.custom_types.object_array import ObjectArray
|
|
12
|
+
from anb_python_components.custom_types.shortcode_attributes import ShortCodeAttributes
|
|
13
|
+
from anb_python_components.custom_types.two_dim_size import TwoDimSize
|
|
14
|
+
from anb_python_components.custom_types.version_info import VersionInfo
|
|
15
|
+
# decorators
|
|
16
|
+
from anb_python_components.decorators.interface_decorators import implement, interface_required
|
|
17
|
+
# enums
|
|
18
|
+
from anb_python_components.enums.message_type import MessageType
|
|
19
|
+
from anb_python_components.enums.not_bool_action import NotBoolAction
|
|
20
|
+
from anb_python_components.enums.type_copy_strategy import TypeCopyStrategy
|
|
21
|
+
# exceptions
|
|
22
|
+
from anb_python_components.exceptions.wrong_type_exception import WrongTypeException
|
|
23
|
+
# extensions
|
|
24
|
+
from anb_python_components.extensions.array_extension import ArrayExtension
|
|
25
|
+
from anb_python_components.extensions.bool_extension import BoolExtension
|
|
26
|
+
from anb_python_components.extensions.string_extension import StringExtension
|
|
27
|
+
from anb_python_components.extensions.type_extension import TypeExtension
|
|
28
|
+
# models
|
|
29
|
+
from anb_python_components.models.action_state_message import ActionStateMessage
|
|
30
|
+
from anb_python_components.models.shortcode_model import ShortCodeModel
|
|
31
|
+
|
|
32
|
+
__all__ = [
|
|
33
|
+
'ActionState',
|
|
34
|
+
'Directory',
|
|
35
|
+
'File',
|
|
36
|
+
'Interface',
|
|
37
|
+
'ShortCodeParser',
|
|
38
|
+
'GUID',
|
|
39
|
+
'ObjectArray',
|
|
40
|
+
'ShortCodeAttributes',
|
|
41
|
+
'TwoDimSize',
|
|
42
|
+
'VersionInfo',
|
|
43
|
+
'interface_required',
|
|
44
|
+
'implement',
|
|
45
|
+
'MessageType',
|
|
46
|
+
'NotBoolAction',
|
|
47
|
+
'TypeCopyStrategy',
|
|
48
|
+
'WrongTypeException',
|
|
49
|
+
'ArrayExtension',
|
|
50
|
+
'BoolExtension',
|
|
51
|
+
'StringExtension',
|
|
52
|
+
"TypeExtension",
|
|
53
|
+
'ActionStateMessage',
|
|
54
|
+
'ShortCodeModel'
|
|
55
|
+
]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# anb_python_components/classes/__init__.py
|
|
2
|
+
|
|
3
|
+
from anb_python_components.classes.action_state import ActionState
|
|
4
|
+
from anb_python_components.classes.directory import Directory
|
|
5
|
+
from anb_python_components.classes.file import File
|
|
6
|
+
from anb_python_components.classes.interface import Interface
|
|
7
|
+
from anb_python_components.classes.shortcode_parser import ShortCodeParser
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
import copy
|
|
3
3
|
from typing import Callable
|
|
4
4
|
|
|
5
|
+
from anb_python_components.enums.message_type import MessageType
|
|
5
6
|
from anb_python_components.exceptions.wrong_type_exception import WrongTypeException
|
|
6
|
-
from anb_python_components.models.action_state_message import ActionStateMessage
|
|
7
|
+
from anb_python_components.models.action_state_message import ActionStateMessage
|
|
7
8
|
|
|
8
9
|
class ActionState[T]:
|
|
9
10
|
"""
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# anb_python_components/classes/interface.py
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
from functools import lru_cache
|
|
5
|
+
from typing import Any, Protocol, get_origin, runtime_checkable
|
|
6
|
+
|
|
7
|
+
@runtime_checkable
|
|
8
|
+
class Interface(Protocol):
|
|
9
|
+
"""
|
|
10
|
+
Базовый класс для объявления интерфейсов с расширенной проверкой.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
@classmethod
|
|
14
|
+
@lru_cache(maxsize = 128)
|
|
15
|
+
def verify (cls, obj_or_class) -> tuple[bool, list[str]]:
|
|
16
|
+
"""
|
|
17
|
+
Проверяет, что объект или класс реализует интерфейс.
|
|
18
|
+
:param obj_or_class: Объект (созданный класс) или класс (или, точнее, его имя), который должен реализовывать интерфейс.
|
|
19
|
+
:return: Кортеж (is_ok, problems), где is_ok — True, если объект или класс реализует интерфейс, иначе False,
|
|
20
|
+
а problems — список сообщений об ошибках, если is_ok == False.
|
|
21
|
+
"""
|
|
22
|
+
# Разбираем аргумент на объект или имя класса. Если аргумент — имя класса, то получаем его класс. В противном случае,
|
|
23
|
+
# возвращаем аргумент как объект.
|
|
24
|
+
target = obj_or_class if isinstance(obj_or_class, type) else obj_or_class.__class__
|
|
25
|
+
|
|
26
|
+
# Инициализируем список проблем
|
|
27
|
+
problems = []
|
|
28
|
+
|
|
29
|
+
# Собираем все методы интерфейса (включая унаследованные)
|
|
30
|
+
interface_methods = cls._get_all_interface_methods()
|
|
31
|
+
|
|
32
|
+
# Проходим по методам интерфейса
|
|
33
|
+
for method_name, signature in interface_methods.items():
|
|
34
|
+
# - если метод отсутствует в объекте
|
|
35
|
+
if not hasattr(target, method_name):
|
|
36
|
+
# -- добавляем в список проблем
|
|
37
|
+
problems.append(f"отсутствует метод '{method_name}' / missing method '{method_name}'")
|
|
38
|
+
# -- идём к следующему методу
|
|
39
|
+
continue
|
|
40
|
+
|
|
41
|
+
# - получаем именованный атрибут метода
|
|
42
|
+
target_method = getattr(target, method_name)
|
|
43
|
+
|
|
44
|
+
# - проверяем, что метод — вызываемый
|
|
45
|
+
if not callable(target_method):
|
|
46
|
+
# -- если нет, добавляем в список проблем
|
|
47
|
+
problems.append(f"'{method_name}' it is not callable")
|
|
48
|
+
# -- идём к следующему методу
|
|
49
|
+
continue
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
# - получаем сигнатуру метода
|
|
53
|
+
target_signature = inspect.signature(target_method)
|
|
54
|
+
|
|
55
|
+
# - сравниваем сигнатуры метода и интерфейса
|
|
56
|
+
cls._compare_signatures(signature, target_signature, method_name, problems)
|
|
57
|
+
except (ValueError, TypeError) as e:
|
|
58
|
+
# Если сигнатуру нельзя получить, добавляем в список проблем
|
|
59
|
+
problems.append(f"ошибка проверки сигнатуры / signature verification error '{method_name}': {e}")
|
|
60
|
+
|
|
61
|
+
# В результат вернём кортеж (is_ok, problems), где is_ok — True, если проблем нет, иначе False, а problems — список проблем.
|
|
62
|
+
return len(problems) == 0, problems
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def check (cls, obj_or_class) -> bool:
|
|
66
|
+
"""
|
|
67
|
+
Строгая проверка — поднимает исключение при несоответствии.
|
|
68
|
+
:param obj_or_class: Объект (созданный класс) или класс (или, точнее, его имя), который должен реализовывать интерфейс.
|
|
69
|
+
:return: True, если объект или класс реализует интерфейс.
|
|
70
|
+
"""
|
|
71
|
+
# Проверяем, что объект или класс реализует интерфейс методом verify и получаем результат проверки
|
|
72
|
+
is_ok, problems = cls.verify(obj_or_class)
|
|
73
|
+
|
|
74
|
+
# Если объект или класс не реализует интерфейс
|
|
75
|
+
if not is_ok:
|
|
76
|
+
# - получаем имя объекта или класса
|
|
77
|
+
target_name = obj_or_class.__name__ if isinstance(obj_or_class, type) else obj_or_class.__class__.__name__
|
|
78
|
+
|
|
79
|
+
# - генерируем исключение с проблемами
|
|
80
|
+
raise TypeError(
|
|
81
|
+
f"{target_name} не реализует интерфейс {cls.__name__}.\n" +
|
|
82
|
+
f"{target_name} not implements interface {cls.__name__}.\n" +
|
|
83
|
+
f"Проблемы / Problems:\n" +
|
|
84
|
+
"\n ".join(problems)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Возвращаем True, если объект или класс реализует интерфейс
|
|
88
|
+
return True
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def get_methods (cls) -> dict[str, inspect.Signature]:
|
|
92
|
+
"""
|
|
93
|
+
Возвращает словарь методов интерфейса с их сигнатурами.
|
|
94
|
+
:return: Словарь методов интерфейса с их сигнатурами.
|
|
95
|
+
"""
|
|
96
|
+
return cls._get_interface_methods(cls)
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def _get_all_interface_methods (cls) -> dict[str, inspect.Signature]:
|
|
100
|
+
"""
|
|
101
|
+
Собирает все методы из иерархии наследования интерфейсов.
|
|
102
|
+
:return: Словарь методов с их сигнатурами.
|
|
103
|
+
"""
|
|
104
|
+
# Создаем словарь методов
|
|
105
|
+
methods = {}
|
|
106
|
+
|
|
107
|
+
# Проходим по иерархии наследования интерфейсов рекурсивно
|
|
108
|
+
for base in reversed(cls.__mro__):
|
|
109
|
+
# - пропускаем базовый класс и сам интерфейс
|
|
110
|
+
if base is Interface or not issubclass(base, Interface):
|
|
111
|
+
continue
|
|
112
|
+
|
|
113
|
+
# - добавляем методы базового интерфейса
|
|
114
|
+
methods.update(cls._get_interface_methods(base))
|
|
115
|
+
|
|
116
|
+
# Возвращаем собранные методы
|
|
117
|
+
return methods
|
|
118
|
+
|
|
119
|
+
@staticmethod
|
|
120
|
+
def _get_interface_methods (interface_cls) -> dict[str, inspect.Signature]:
|
|
121
|
+
"""Извлекает методы интерфейса и их сигнатуры."""
|
|
122
|
+
methods = {}
|
|
123
|
+
for attr_name in dir(interface_cls):
|
|
124
|
+
if attr_name.startswith('_') or attr_name == 'verify':
|
|
125
|
+
continue
|
|
126
|
+
attr = getattr(interface_cls, attr_name)
|
|
127
|
+
if callable(attr):
|
|
128
|
+
try:
|
|
129
|
+
signature = inspect.signature(attr)
|
|
130
|
+
methods[attr_name] = signature
|
|
131
|
+
except (ValueError, TypeError):
|
|
132
|
+
# Если сигнатуру нельзя получить, оставляем пустую
|
|
133
|
+
methods[attr_name] = inspect.Signature()
|
|
134
|
+
return methods
|
|
135
|
+
|
|
136
|
+
@staticmethod
|
|
137
|
+
def _compare_signatures (
|
|
138
|
+
expected: inspect.Signature,
|
|
139
|
+
actual: inspect.Signature,
|
|
140
|
+
method_name: str,
|
|
141
|
+
problems: list[str]
|
|
142
|
+
) -> None:
|
|
143
|
+
"""
|
|
144
|
+
Сравнивает сигнатуры методов.
|
|
145
|
+
:param expected: Ожидаемая сигнатура.
|
|
146
|
+
:param actual: Текущая сигнатура.
|
|
147
|
+
:param method_name: Имя метода.
|
|
148
|
+
:param problems: Список проблем.
|
|
149
|
+
:return: None
|
|
150
|
+
"""
|
|
151
|
+
# Проверяем количество параметров
|
|
152
|
+
expected_params = list(expected.parameters.values())
|
|
153
|
+
actual_params = list(actual.parameters.values())
|
|
154
|
+
|
|
155
|
+
# Проверяем количество параметров
|
|
156
|
+
if len(expected_params) != len(actual_params):
|
|
157
|
+
# - если количество параметров не совпадает, добавляем в список проблем
|
|
158
|
+
problems.append(
|
|
159
|
+
f"'{method_name}': ожидается {len(expected_params)} параметров, получено {len(actual_params)} / {method_name}': expected {len(expected_params)} parameters, got {len(actual_params)}"
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# - прерываем выполнение
|
|
163
|
+
return
|
|
164
|
+
|
|
165
|
+
# Проверяем типы параметров (если указаны)
|
|
166
|
+
for i, (exp_param, act_param) in enumerate(zip(expected_params, actual_params)):
|
|
167
|
+
# - проверяем, что у ожидаемого параметра (exp_param) есть аннотация
|
|
168
|
+
if exp_param.annotation is not exp_param.empty:
|
|
169
|
+
# -- получаем тип ожидаемого параметра
|
|
170
|
+
expected_type = exp_param.annotation
|
|
171
|
+
# -- получаем тип текущего параметра
|
|
172
|
+
actual_type = act_param.annotation if act_param.annotation is not act_param.empty else Any
|
|
173
|
+
|
|
174
|
+
# -- сравниваем типы
|
|
175
|
+
if get_origin(expected_type) != get_origin(actual_type):
|
|
176
|
+
# --- если типы не совпадают, добавляем в список проблем
|
|
177
|
+
problems.append(
|
|
178
|
+
f"Тип аннотации не совпадает для / annotation type mismatch for parameter '{exp_param.name}'"
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
@classmethod
|
|
182
|
+
def register (cls, target_class):
|
|
183
|
+
"""
|
|
184
|
+
Регистрирует класс как реализующий интерфейс (для документации).
|
|
185
|
+
:param target_class: Класс, который должен реализовывать интерфейс.
|
|
186
|
+
:return: Регистрированный класс.
|
|
187
|
+
"""
|
|
188
|
+
# Проверяем, что класс реализует интерфейс
|
|
189
|
+
cls.check(target_class)
|
|
190
|
+
|
|
191
|
+
# Возвращаем класс
|
|
192
|
+
return target_class
|
|
@@ -4,8 +4,8 @@ import re
|
|
|
4
4
|
from typing import Callable, Dict
|
|
5
5
|
|
|
6
6
|
from anb_python_components.classes.action_state import ActionState
|
|
7
|
-
from anb_python_components.models.shortcode_model import ShortCodeModel
|
|
8
7
|
from anb_python_components.custom_types.shortcode_attributes import ShortCodeAttributes
|
|
8
|
+
from anb_python_components.models.shortcode_model import ShortCodeModel
|
|
9
9
|
|
|
10
10
|
class ShortCodeParser:
|
|
11
11
|
"""
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# anb_python_components/custom_types/__init__.py
|
|
2
|
+
|
|
3
|
+
from anb_python_components.custom_types.guid import GUID
|
|
4
|
+
from anb_python_components.custom_types.object_array import ObjectArray
|
|
5
|
+
from anb_python_components.custom_types.shortcode_attributes import ShortCodeAttributes
|
|
6
|
+
from anb_python_components.custom_types.two_dim_size import TwoDimSize
|
|
7
|
+
from anb_python_components.custom_types.version_info import VersionInfo
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# anb_python_components/decorators/interface_decorators.py
|
|
2
|
+
import inspect
|
|
3
|
+
from typing import Callable
|
|
4
|
+
|
|
5
|
+
from anb_python_components import Interface
|
|
6
|
+
|
|
7
|
+
def interface_required (signature: Callable | None = None, **kwargs) -> Callable:
|
|
8
|
+
"""
|
|
9
|
+
Декоратор для явного указания обязательных методов интерфейса.
|
|
10
|
+
Позволяет задать сигнатуру через аннотации.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def decorator (func) -> Callable:
|
|
14
|
+
"""
|
|
15
|
+
Декоратор для проверки сигнатуры.
|
|
16
|
+
:param func: Функция для проверки.
|
|
17
|
+
:return: Проверенная функция.
|
|
18
|
+
"""
|
|
19
|
+
# Если сигнатура указана
|
|
20
|
+
if signature is not None:
|
|
21
|
+
# - сохраняем сигнатуру в атрибуте сигнатуры
|
|
22
|
+
func.__signature__ = inspect.signature(signature)
|
|
23
|
+
else:
|
|
24
|
+
# - иначе сохраняем сигнатуру в атрибуте аннотаций
|
|
25
|
+
func.__annotations__ = kwargs
|
|
26
|
+
|
|
27
|
+
# Возвращаем функцию
|
|
28
|
+
return func
|
|
29
|
+
|
|
30
|
+
# Возвращаем функцию-декоратор
|
|
31
|
+
return decorator
|
|
32
|
+
|
|
33
|
+
def implement (interface):
|
|
34
|
+
"""
|
|
35
|
+
Декоратор для явного указания реализации интерфейса.
|
|
36
|
+
:param interface: Класс-интерфейс (наследник Interface)
|
|
37
|
+
:raise: TypeError: если класс не реализует интерфейс
|
|
38
|
+
:return: Оригинальный класс (с добавленным атрибутом __implements__)
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
def decorator (cls):
|
|
42
|
+
"""
|
|
43
|
+
Декоратор для реализации интерфейса.
|
|
44
|
+
:param cls: Класс для реализации интерфейса.
|
|
45
|
+
:return: Оригинальный класс с реализацией интерфейса.
|
|
46
|
+
"""
|
|
47
|
+
# 1. Проверяем, что interface действительно является интерфейсом
|
|
48
|
+
if not isinstance(interface, type) or not issubclass(interface, Interface):
|
|
49
|
+
raise TypeError(
|
|
50
|
+
f"{interface} не является интерфейсом (не наследуется от Interface) / is not an interface (does not inherit from Interface)"
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# 2. Выполняем строгую проверку реализации
|
|
54
|
+
try:
|
|
55
|
+
interface.check(cls)
|
|
56
|
+
except TypeError as e:
|
|
57
|
+
raise TypeError(
|
|
58
|
+
f"Класс {cls.__name__} не реализует интерфейс {interface.__name__} / class {cls.__name__} does not implement interface {interface.__name__}\n {e}"
|
|
59
|
+
) from e
|
|
60
|
+
|
|
61
|
+
# 3. Добавляем метаданные о реализации
|
|
62
|
+
if not hasattr(cls, '__implements__'):
|
|
63
|
+
cls.__implements__ = []
|
|
64
|
+
cls.__implements__.append(interface)
|
|
65
|
+
|
|
66
|
+
# 4. Сохраняем ссылку на интерфейс для интроспекции
|
|
67
|
+
impl_attr = f'__implements_{interface.__name__}'
|
|
68
|
+
setattr(cls, impl_attr, True)
|
|
69
|
+
|
|
70
|
+
# 5. Декоратор должен вернуть оригинальный класс
|
|
71
|
+
return cls
|
|
72
|
+
|
|
73
|
+
# Возвращаем функцию-декоратор
|
|
74
|
+
return decorator
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# anb_python_components/extensions/__init__.py
|
|
2
|
+
|
|
3
|
+
from anb_python_components.extensions.array_extension import ArrayExtension
|
|
4
|
+
from anb_python_components.extensions.bool_extension import BoolExtension
|
|
5
|
+
from anb_python_components.extensions.string_extension import StringExtension
|
|
6
|
+
from anb_python_components.extensions.type_extension import TypeExtension
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: anb_python_components
|
|
3
|
+
Version: 1.3.0
|
|
4
|
+
Summary: Набор компонентов Python, которые упрощают разработку / A set of Python components that simplify development
|
|
5
|
+
Home-page: https://gitflic.ru/project/babaev-an/anb-python-components
|
|
6
|
+
Author: Александр Бабаев
|
|
7
|
+
Author-email: contact_with_us@babaev-an.ru
|
|
8
|
+
Project-URL: Documentation, https://gitflic.ru/project/babaev-an/anb-python-components/wiki
|
|
9
|
+
Project-URL: Source, https://gitflic.ru/project/babaev-an/anb-python-components
|
|
10
|
+
Project-URL: Tracker, https://gitflic.ru/project/babaev-an/anb-python-components/issue?page=0
|
|
11
|
+
Keywords: python components development utils
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.14.0
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Dynamic: author
|
|
23
|
+
Dynamic: author-email
|
|
24
|
+
Dynamic: classifier
|
|
25
|
+
Dynamic: description
|
|
26
|
+
Dynamic: description-content-type
|
|
27
|
+
Dynamic: home-page
|
|
28
|
+
Dynamic: keywords
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
Dynamic: project-url
|
|
31
|
+
Dynamic: requires-python
|
|
32
|
+
Dynamic: summary
|
|
33
|
+
|
|
34
|
+
# 📌🇷🇺 Русская версия
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Набор компонентов Python для упрощения разработки приложений
|
|
39
|
+
|
|
40
|
+
**ANB Python Components** — это библиотека полезных классов и модулей, предназначенная для ускорения процесса разработки
|
|
41
|
+
программного обеспечения на языке программирования Python. Библиотека включает широкий спектр инструментов, облегчающих
|
|
42
|
+
выполнение повседневных задач разработчика, от обработки файлов и сетевых запросов до автоматизации тестирования и
|
|
43
|
+
интеграции с популярными фреймворками.
|
|
44
|
+
|
|
45
|
+
### ✅ Основные возможности:
|
|
46
|
+
|
|
47
|
+
- Удобные инструменты для работы с файлами и каталогами.
|
|
48
|
+
- Классы для работы с файлами и директориями.
|
|
49
|
+
- Классы для удобной передачи состояния.
|
|
50
|
+
- Новые
|
|
51
|
+
типы [GUID](https://gitflic.ru/project/babaev-an/anb-python-components/wiki/page?file=class_desc%2Ftypes%2Fguid.md),
|
|
52
|
+
[TwoDimSize](https://gitflic.ru/project/babaev-an/anb-python-components/wiki/page?file=class_desc%2Ftypes%2Ftwo_dim_size.md)
|
|
53
|
+
и [VersionInfo](https://gitflic.ru/project/babaev-an/anb-python-components/wiki/page?file=class_desc%2Ftypes%2Fversion_info.md).
|
|
54
|
+
- Расширение массивов, типа `bool`, типа `GUID`, типа `str`.
|
|
55
|
+
- Класс для перевода любого типа в строку и наоборот.
|
|
56
|
+
|
|
57
|
+
### ⚙️ Установка и использование:
|
|
58
|
+
|
|
59
|
+
Установить пакет можно через pip:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install anb-python-components --index-url https://registry.gitflic.ru/project/babaev-an/anb-python-components/package/-/pypi/simple
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Подключайте необходимые модули и начните пользоваться ими прямо сейчас:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from anb_python_components.custom_types.two_dim_size import TwoDimSize
|
|
69
|
+
|
|
70
|
+
# Пример использования
|
|
71
|
+
two_dim = TwoDimSize.parse('100x150', 'x')
|
|
72
|
+
|
|
73
|
+
# Теперь присваиваем какому-либо объекту
|
|
74
|
+
some_object_width = two_dim.width
|
|
75
|
+
some_object_height = two_dim.height
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 🛠️ Поддерживаемые технологии:
|
|
79
|
+
|
|
80
|
+
- `Python` версии 3.13.7 и выше
|
|
81
|
+
- Совместима с большинством популярных веб-фреймворков и библиотек Python
|
|
82
|
+
- Оптимизирован для работы с большими объемами данных и высоконагруженными приложениями
|
|
83
|
+
|
|
84
|
+
### 💬 Вопросы и поддержка:
|
|
85
|
+
|
|
86
|
+
Для подробной справки обратитесь к руководству по библиотеке в разделе документации:
|
|
87
|
+
|
|
88
|
+
🔗 Справочное руководство → [Документация библиотеки](https://gitflic.ru/project/babaev-an/anb-python-components/wiki)
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
# 📌🇬🇧 English Version
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Python Component Collection for Streamlining Application Development
|
|
97
|
+
|
|
98
|
+
**ANB Python Components** is a collection of useful classes and modules specifically tailored to accelerate the process
|
|
99
|
+
of developing software using the Python programming language. It offers a broad spectrum of tools that simplify everyday
|
|
100
|
+
developer tasks, from file manipulation and network requests to test automation and seamless integration with widely
|
|
101
|
+
used frameworks.
|
|
102
|
+
|
|
103
|
+
### ✅ Main Features:
|
|
104
|
+
|
|
105
|
+
- Handy tools for working with files and directories.
|
|
106
|
+
- Classes for handling files and folders.
|
|
107
|
+
- Classes for convenient state transfer.
|
|
108
|
+
- New custom_types such
|
|
109
|
+
as [GUID](https://gitflic.ru/project/babaev-an/anb-python-components/wiki/page?file=class_desc%2Ftypes%2Fguid.md), [TwoDimSize](https://gitflic.ru/project/babaev-an/anb-python-components/wiki/page?file=class_desc%2Ftypes%2Ftwo_dim_size.md),
|
|
110
|
+
and [VersionInfo](https://gitflic.ru/project/babaev-an/anb-python-components/wiki/page?file=class_desc%2Ftypes%2Fversion_info.md).
|
|
111
|
+
- Extensions for arrays, `bool`, `GUID`, and `str` custom_types.
|
|
112
|
+
- Class for converting any type into string representation and vice versa.
|
|
113
|
+
|
|
114
|
+
### ⚙️ Installation and Usage:
|
|
115
|
+
|
|
116
|
+
You can install this package via pip:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pip install anb-python-components --index-url https://registry.gitflic.ru/project/babaev-an/anb-python-components/package/-/pypi/simple
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Import required modules and start using them immediately:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from anb_python_components.custom_types.two_dim_size import TwoDimSize
|
|
126
|
+
|
|
127
|
+
# Example usage
|
|
128
|
+
two_dim = TwoDimSize.parse('100x150', 'x')
|
|
129
|
+
|
|
130
|
+
# Now assign it to some object
|
|
131
|
+
some_object_width = two_dim.width
|
|
132
|
+
some_object_height = two_dim.height
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 🛠️ Supported Technologies:
|
|
136
|
+
|
|
137
|
+
- **Python**: version 3.13.7 or higher
|
|
138
|
+
- Compatibility with most popular Python web frameworks and libraries
|
|
139
|
+
- Optimized for performance with large-scale datasets and highly loaded applications
|
|
140
|
+
|
|
141
|
+
### 💬 Questions and Support:
|
|
142
|
+
|
|
143
|
+
For comprehensive guidance and support, consult the library's documentation section:
|
|
144
|
+
|
|
145
|
+
🔗 Reference Guide → [Library Documentation](https://gitflic.ru/project/babaev-an/anb-python-components/wiki) (in Russian
|
|
146
|
+
Only)
|
|
@@ -5,11 +5,13 @@ anb_python_components/__init__.py
|
|
|
5
5
|
anb_python_components.egg-info/PKG-INFO
|
|
6
6
|
anb_python_components.egg-info/SOURCES.txt
|
|
7
7
|
anb_python_components.egg-info/dependency_links.txt
|
|
8
|
+
anb_python_components.egg-info/not-zip-safe
|
|
8
9
|
anb_python_components.egg-info/top_level.txt
|
|
9
10
|
anb_python_components/classes/__init__.py
|
|
10
11
|
anb_python_components/classes/action_state.py
|
|
11
12
|
anb_python_components/classes/directory.py
|
|
12
13
|
anb_python_components/classes/file.py
|
|
14
|
+
anb_python_components/classes/interface.py
|
|
13
15
|
anb_python_components/classes/shortcode_parser.py
|
|
14
16
|
anb_python_components/custom_types/__init__.py
|
|
15
17
|
anb_python_components/custom_types/guid.py
|
|
@@ -17,6 +19,8 @@ anb_python_components/custom_types/object_array.py
|
|
|
17
19
|
anb_python_components/custom_types/shortcode_attributes.py
|
|
18
20
|
anb_python_components/custom_types/two_dim_size.py
|
|
19
21
|
anb_python_components/custom_types/version_info.py
|
|
22
|
+
anb_python_components/decorators/__init__.py
|
|
23
|
+
anb_python_components/decorators/interface_decorators.py
|
|
20
24
|
anb_python_components/enums/__init__.py
|
|
21
25
|
anb_python_components/enums/message_type.py
|
|
22
26
|
anb_python_components/enums/not_bool_action.py
|
|
@@ -37,6 +41,7 @@ tests/classes/__init__.py
|
|
|
37
41
|
tests/classes/action_state_test.py
|
|
38
42
|
tests/classes/directory_test.py
|
|
39
43
|
tests/classes/file_test.py
|
|
44
|
+
tests/classes/interface_test.py
|
|
40
45
|
tests/classes/shortcode_parser_test.py
|
|
41
46
|
tests/custom_types/__init__.py
|
|
42
47
|
tests/custom_types/guid_test.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from os import path
|
|
2
|
+
|
|
3
|
+
from setuptools import find_packages, setup
|
|
4
|
+
|
|
5
|
+
# Получаем длинное описание из README.md
|
|
6
|
+
this_directory = path.abspath(path.dirname(__file__))
|
|
7
|
+
with open(path.join(this_directory, 'README.md'), encoding = 'utf-8') as f:
|
|
8
|
+
long_description = f.read()
|
|
9
|
+
|
|
10
|
+
setup(
|
|
11
|
+
name = 'anb_python_components',
|
|
12
|
+
version = '1.3.0',
|
|
13
|
+
description = 'Набор компонентов Python, которые упрощают разработку / A set of Python components that simplify development',
|
|
14
|
+
long_description = long_description,
|
|
15
|
+
long_description_content_type = 'text/markdown',
|
|
16
|
+
author = 'Александр Бабаев',
|
|
17
|
+
author_email = 'contact_with_us@babaev-an.ru',
|
|
18
|
+
url = 'https://gitflic.ru/project/babaev-an/anb-python-components',
|
|
19
|
+
packages = find_packages(),
|
|
20
|
+
install_requires = [],
|
|
21
|
+
python_requires = '>=3.14.0',
|
|
22
|
+
classifiers = [
|
|
23
|
+
'Development Status :: 5 - Production/Stable',
|
|
24
|
+
'Intended Audience :: Developers',
|
|
25
|
+
'License :: OSI Approved :: MIT License',
|
|
26
|
+
'Programming Language :: Python :: 3',
|
|
27
|
+
'Programming Language :: Python :: 3.14',
|
|
28
|
+
'Operating System :: OS Independent',
|
|
29
|
+
'Topic :: Software Development :: Libraries :: Python Modules',
|
|
30
|
+
],
|
|
31
|
+
keywords = 'python components development utils',
|
|
32
|
+
project_urls = {
|
|
33
|
+
'Documentation': 'https://gitflic.ru/project/babaev-an/anb-python-components/wiki',
|
|
34
|
+
'Source': 'https://gitflic.ru/project/babaev-an/anb-python-components',
|
|
35
|
+
'Tracker': 'https://gitflic.ru/project/babaev-an/anb-python-components/issue?page=0',
|
|
36
|
+
},
|
|
37
|
+
zip_safe = False,
|
|
38
|
+
)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# tests/classes/interface_test.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import unittest
|
|
5
|
+
|
|
6
|
+
from anb_python_components import Interface, implement, interface_required
|
|
7
|
+
|
|
8
|
+
class Drawable(Interface):
|
|
9
|
+
@interface_required
|
|
10
|
+
def draw (self) -> None: pass
|
|
11
|
+
|
|
12
|
+
@interface_required
|
|
13
|
+
def get_area (self) -> float: pass
|
|
14
|
+
|
|
15
|
+
class Renderable(Interface):
|
|
16
|
+
@interface_required(lambda self, quality: int)
|
|
17
|
+
def render (self, quality: int) -> bytes: pass
|
|
18
|
+
|
|
19
|
+
@implement(Drawable)
|
|
20
|
+
@implement(Renderable)
|
|
21
|
+
class Circle(Drawable, Renderable):
|
|
22
|
+
def __init__ (self, radius: float):
|
|
23
|
+
self.radius = radius
|
|
24
|
+
|
|
25
|
+
def draw (self) -> None:
|
|
26
|
+
print(f"Рисуем круг радиусом {self.radius}")
|
|
27
|
+
|
|
28
|
+
def get_area (self) -> float:
|
|
29
|
+
return 3.14159 * self.radius ** 2
|
|
30
|
+
|
|
31
|
+
def render (self, quality: int) -> bytes:
|
|
32
|
+
return b"PNG-data"
|
|
33
|
+
|
|
34
|
+
class InterfaceTest(unittest.TestCase):
|
|
35
|
+
def test_interface (self):
|
|
36
|
+
self.assertTrue(hasattr(Circle, '__implements_Drawable'))
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def check_drawable (drawable: Drawable):
|
|
40
|
+
drawable.draw()
|
|
41
|
+
return True
|
|
42
|
+
|
|
43
|
+
def test_drawable (self):
|
|
44
|
+
self.assertTrue(self.check_drawable(Circle(10)))
|
|
45
|
+
|
|
46
|
+
if __name__ == '__main__':
|
|
47
|
+
unittest.main()
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: anb_python_components
|
|
3
|
-
Version: 1.2.1
|
|
4
|
-
Author: Александр Бабаев
|
|
5
|
-
Author-email: contact_with_us@babaev-an.ru
|
|
6
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
7
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Dynamic: author
|
|
10
|
-
Dynamic: author-email
|
|
11
|
-
Dynamic: classifier
|
|
12
|
-
Dynamic: license-file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# anb_python_components/__init__.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# anb_python_components/classes/__init__.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# anb_python_components/enums/__init__.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# anb_python_components/exceptions/__init__.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# anb_python_components/extensions/__init__.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# anb_python_components/models/__init__.py
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: anb_python_components
|
|
3
|
-
Version: 1.2.1
|
|
4
|
-
Author: Александр Бабаев
|
|
5
|
-
Author-email: contact_with_us@babaev-an.ru
|
|
6
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
7
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Dynamic: author
|
|
10
|
-
Dynamic: author-email
|
|
11
|
-
Dynamic: classifier
|
|
12
|
-
Dynamic: license-file
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# setup.py
|
|
2
|
-
from setuptools import find_packages, setup
|
|
3
|
-
|
|
4
|
-
setup(
|
|
5
|
-
# Имя пакета
|
|
6
|
-
name = 'anb_python_components',
|
|
7
|
-
# Версия пакета
|
|
8
|
-
version = '1.2.1',
|
|
9
|
-
# Описание пакета
|
|
10
|
-
summary = 'Набор компонентов Python, которые упрощают разработку / A set of Python components that simplify development',
|
|
11
|
-
# Автор пакета
|
|
12
|
-
author = 'Александр Бабаев',
|
|
13
|
-
author_email = 'contact_with_us@babaev-an.ru',
|
|
14
|
-
# Автоматически находит пакеты внутри текущего каталога
|
|
15
|
-
packages = find_packages(),
|
|
16
|
-
|
|
17
|
-
# Обязательные зависимости
|
|
18
|
-
install_requires = [],
|
|
19
|
-
|
|
20
|
-
classifiers = [
|
|
21
|
-
# Язык программирования (минимальная версия Python)
|
|
22
|
-
'Programming Language :: Python :: 3.14',
|
|
23
|
-
# Лицензия
|
|
24
|
-
'License :: OSI Approved :: MIT License'
|
|
25
|
-
]
|
|
26
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{anb_python_components-1.2.1 → anb_python_components-1.3.0}/anb_python_components/classes/file.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/classes/action_state_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/classes/shortcode_parser_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/custom_types/object_array_test.py
RENAMED
|
File without changes
|
{anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/custom_types/two_dim_size_test.py
RENAMED
|
File without changes
|
{anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/custom_types/version_info_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/extensions/array_extension_test.py
RENAMED
|
File without changes
|
{anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/extensions/bool_extension_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{anb_python_components-1.2.1 → anb_python_components-1.3.0}/tests/extensions/type_extension_test.py
RENAMED
|
File without changes
|