hardpy 0.3.0__py3-none-any.whl → 0.5.0__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.
@@ -0,0 +1,303 @@
1
+ # Copyright (c) 2024 Everypin
2
+ # GNU General Public License v3.0 (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
3
+
4
+ import base64
5
+ from abc import ABC, abstractmethod
6
+ from ast import literal_eval
7
+ from copy import deepcopy
8
+ from dataclasses import dataclass
9
+ from enum import Enum
10
+ from typing import Any, Final
11
+
12
+ from hardpy.pytest_hardpy.utils.exception import WidgetInfoError
13
+
14
+
15
+ class WidgetType(Enum):
16
+ """Dialog box widget type."""
17
+
18
+ BASE = "base"
19
+ TEXT_INPUT = "textinput"
20
+ NUMERIC_INPUT = "numericinput"
21
+ RADIOBUTTON = "radiobutton"
22
+ CHECKBOX = "checkbox"
23
+ IMAGE = "image"
24
+ STEP = "step"
25
+ MULTISTEP = "multistep"
26
+
27
+
28
+ class IWidget(ABC):
29
+ """Dialog box widget interface."""
30
+
31
+ def __init__(self, widget_type: WidgetType):
32
+ self.type: Final[str] = widget_type.value
33
+ self.info: dict = {}
34
+
35
+ @abstractmethod
36
+ def convert_data(self, input_data: str | None) -> Any | None:
37
+ """Get the widget data in the correct format.
38
+
39
+ Args:
40
+ input_data (str | None): input string or nothing.
41
+
42
+ Returns:
43
+ Any: Widget data in the correct format
44
+ """
45
+ raise NotImplementedError
46
+
47
+
48
+ class BaseWidget(IWidget):
49
+ """Widget info interface."""
50
+
51
+ def __init__(self, widget_type: WidgetType = WidgetType.BASE):
52
+ super().__init__(WidgetType.BASE)
53
+
54
+ def convert_data(self, input_data: str | None = None) -> bool: # noqa: WPS324
55
+ """Get base widget data, i.e. None.
56
+
57
+ Args:
58
+ input_data (str): input string
59
+
60
+ Returns:
61
+ bool: True if confirm button is pressed
62
+ """
63
+ return True
64
+
65
+
66
+ class TextInputWidget(IWidget):
67
+ """Text input widget."""
68
+
69
+ def __init__(self):
70
+ """Initialize the TextInputWidget."""
71
+ super().__init__(WidgetType.TEXT_INPUT)
72
+
73
+ def convert_data(self, input_data: str) -> str:
74
+ """Get the text input data in the string format.
75
+
76
+ Args:
77
+ input_data (str): input string
78
+
79
+ Returns:
80
+ str: Text input string data
81
+ """
82
+ return input_data
83
+
84
+
85
+ class NumericInputWidget(IWidget):
86
+ """Numeric input widget."""
87
+
88
+ def __init__(self):
89
+ """Initialize the NumericInputWidget."""
90
+ super().__init__(WidgetType.NUMERIC_INPUT)
91
+
92
+ def convert_data(self, input_data: str) -> float | None:
93
+ """Get the numeric widget data in the correct format.
94
+
95
+ Args:
96
+ input_data (str): input string
97
+
98
+ Returns:
99
+ float | None: Numeric data or None if the input is not a number
100
+ """
101
+ try:
102
+ return float(input_data)
103
+ except ValueError:
104
+ return None
105
+
106
+
107
+ class RadiobuttonWidget(IWidget):
108
+ """Radiobutton widget."""
109
+
110
+ def __init__(self, fields: list[str]):
111
+ """Initialize the RadiobuttonWidget.
112
+
113
+ Args:
114
+ fields (list[str]): Radiobutton fields.
115
+
116
+ Raises:
117
+ ValueError: If the fields list is empty.
118
+ """
119
+ super().__init__(WidgetType.RADIOBUTTON)
120
+ if not fields:
121
+ raise ValueError("RadiobuttonWidget must have at least one field")
122
+ self.info["fields"] = fields
123
+
124
+ def convert_data(self, input_data: str) -> str:
125
+ """Get the radiobutton widget data in the correct format.
126
+
127
+ Args:
128
+ input_data (str): input string
129
+
130
+ Returns:
131
+ str: Radiobutton string data
132
+ """
133
+ return input_data
134
+
135
+
136
+ class CheckboxWidget(IWidget):
137
+ """Checkbox widget."""
138
+
139
+ def __init__(self, fields: list[str]):
140
+ """Initialize the CheckboxWidget.
141
+
142
+ Args:
143
+ fields (list[str]): Checkbox fields.
144
+
145
+ Raises:
146
+ ValueError: If the fields list is empty.
147
+ """
148
+ super().__init__(WidgetType.CHECKBOX)
149
+ if not fields:
150
+ raise ValueError("RadiobuttonWidget must have at least one field")
151
+ self.info["fields"] = fields
152
+
153
+ def convert_data(self, input_data: str) -> list[str] | None:
154
+ """Get the checkbox widget data in the correct format.
155
+
156
+ Args:
157
+ input_data (str): input string
158
+
159
+ Returns:
160
+ (list[str] | None): Checkbox string data or None if the input is not a list
161
+ """
162
+ try:
163
+ return literal_eval(input_data)
164
+ except ValueError:
165
+ return None
166
+
167
+
168
+ class ImageWidget(IWidget):
169
+ """Image widget."""
170
+
171
+ def __init__(self, address: str, format: str = "image", width: int = 100):
172
+ """Validate the image fields and defines the base64 if it does not exist.
173
+
174
+ Args:
175
+ address (str): image address
176
+ format (str): image format
177
+ width (int): image width
178
+
179
+ Raises:
180
+ WidgetInfoError: If both address and base64 are specified.
181
+ """
182
+ super().__init__(WidgetType.IMAGE)
183
+
184
+ if width < 1:
185
+ raise WidgetInfoError("Width must be positive")
186
+
187
+ self.info["address"] = address
188
+ self.info["format"] = format
189
+ self.info["width"] = width
190
+
191
+ try:
192
+ with open(address, "rb") as file:
193
+ file_data = file.read()
194
+ except FileNotFoundError:
195
+ raise WidgetInfoError("The image address is invalid")
196
+ self.info["base64"] = base64.b64encode(file_data).decode("utf-8")
197
+
198
+ def convert_data(self, input_data: str | None = None) -> bool:
199
+ """Get the image widget data, i.e. None.
200
+
201
+ Args:
202
+ input_data (str | None): input string or nothing.
203
+
204
+ Returns:
205
+ bool: True if confirm button is pressed
206
+ """
207
+ return True
208
+
209
+
210
+ class StepWidget(IWidget):
211
+ """Step widget.
212
+
213
+ Args:
214
+ title (str): Step title
215
+ text (str | None): Step text
216
+ widget (ImageWidget | None): Step widget
217
+
218
+ Raises:
219
+ WidgetInfoError: If the text or widget are not provided.
220
+ """
221
+
222
+ def __init__(self, title: str, text: str | None, widget: ImageWidget | None):
223
+ super().__init__(WidgetType.STEP)
224
+ if text is None and widget is None:
225
+ raise WidgetInfoError("Text or widget must be provided")
226
+ self.info["title"] = title
227
+ if isinstance(text, str):
228
+ self.info["text"] = text
229
+ if isinstance(widget, ImageWidget):
230
+ self.info["widget"] = widget.__dict__
231
+
232
+ def convert_data(self, input_data: str) -> bool:
233
+ """Get the step widget data in the correct format.
234
+
235
+ Args:
236
+ input_data (str): input string
237
+
238
+ Returns:
239
+ bool: True if confirm button is pressed
240
+ """
241
+ return True
242
+
243
+
244
+ class MultistepWidget(IWidget):
245
+ """Multistep widget."""
246
+
247
+ def __init__(self, steps: list[StepWidget]):
248
+ """Initialize the MultistepWidget.
249
+
250
+ Args:
251
+ steps (list[StepWidget]): A list with info about the steps.
252
+
253
+ Raises:
254
+ ValueError: If the provided list of steps is empty.
255
+ """
256
+ super().__init__(WidgetType.MULTISTEP)
257
+ if not steps:
258
+ raise ValueError("MultistepWidget must have at least one step")
259
+ self.info["steps"] = []
260
+ for step in steps:
261
+ self.info["steps"].append(step.__dict__)
262
+
263
+ def convert_data(self, input_data: str) -> bool:
264
+ """Get the multistep widget data in the correct format.
265
+
266
+ Args:
267
+ input_data (str): input string
268
+
269
+ Returns:
270
+ bool: True if confirm button is pressed
271
+ """
272
+ return True
273
+
274
+
275
+ @dataclass
276
+ class DialogBox:
277
+ """Dialog box data.
278
+
279
+ Args:
280
+ dialog_text (str): dialog text
281
+ title_bar (str | None): title bar
282
+ widget (IWidget | None): widget info
283
+ """
284
+
285
+ def __init__(
286
+ self,
287
+ dialog_text: str,
288
+ title_bar: str | None = None,
289
+ widget: IWidget | None = None,
290
+ ):
291
+ self.widget: IWidget = BaseWidget() if widget is None else widget
292
+ self.dialog_text: str = dialog_text
293
+ self.title_bar: str | None = title_bar
294
+
295
+ def to_dict(self) -> dict:
296
+ """Convert DialogBox to dictionary.
297
+
298
+ Returns:
299
+ dict: DialogBox dictionary.
300
+ """
301
+ dbx_dict = deepcopy(self.__dict__)
302
+ dbx_dict["widget"] = deepcopy(self.widget.__dict__)
303
+ return dbx_dict
@@ -14,3 +14,17 @@ class DuplicateSerialNumberError(HardpyError):
14
14
 
15
15
  def __init__(self):
16
16
  super().__init__(self.__doc__) # type: ignore
17
+
18
+
19
+ class DuplicateDialogBoxError(HardpyError):
20
+ """The dialog box has already been determined."""
21
+
22
+ def __init__(self):
23
+ super().__init__(self.__doc__) # type: ignore
24
+
25
+
26
+ class WidgetInfoError(HardpyError):
27
+ """The widget info is not correct."""
28
+
29
+ def __init__(self, message):
30
+ super().__init__(message)
@@ -1,8 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hardpy
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: HardPy library for device testing
5
- Project-URL: repository, https://github.com/everypindevices/hardpy
5
+ Project-URL: Homepage, https://github.com/everypinio/hardpy/
6
+ Project-URL: Documentation, https://everypinio.github.io/hardpy/
7
+ Project-URL: Repository, https://github.com/everypinio/hardpy/
8
+ Project-URL: Changelog, https://everypinio.github.io/hardpy/changelog/
6
9
  Author: Everypin
7
10
  License-File: LICENSE
8
11
  Classifier: Development Status :: 4 - Beta
@@ -36,7 +39,7 @@ Requires-Dist: wemake-python-styleguide; extra == 'dev'
36
39
  Description-Content-Type: text/markdown
37
40
 
38
41
  <h1 align="center">
39
- <img src="https://everypinio.github.io/hardpy/img/logo512.png" alt="HardPy" style="width:200px;">
42
+ <img src="https://everypinio.github.io/hardpy/img/logo256.png" alt="HardPy" style="width:200px;">
40
43
  </h1>
41
44
 
42
45
  <h1 align="center">
@@ -62,13 +65,13 @@ HardPy is a python library for creating a test bench for devices.
62
65
  HardPy allows you to:
63
66
 
64
67
  * Create test benches for devices using [pytest](https://docs.pytest.org/);
65
- * Use a browser to view, run, and stop tests;
68
+ * Use a browser to view, start, stop, and interact with tests;
66
69
  * Store test results in the [CouchDB](https://couchdb.apache.org/) database.
67
70
 
68
71
  ## To Install
69
72
 
70
73
  ```bash
71
- pip3 install hardpy
74
+ pip install hardpy
72
75
  ```
73
76
 
74
77
  ## Examples
@@ -1,10 +1,10 @@
1
- hardpy/__init__.py,sha256=RwEQwrdXAtjf2UKOTyXiOUvMKOpXCy7TrJR03V4HY98,864
1
+ hardpy/__init__.py,sha256=_opqN5uChXP1nbR703eYrghBQ8wCR593sc5k04lCboM,1414
2
2
  hardpy/hardpy_panel/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- hardpy/hardpy_panel/api.py,sha256=ool8MvCH9SFGHooOloboListg1Mas4FciMQsyRjhWGE,1567
4
- hardpy/hardpy_panel/runner.py,sha256=J8c2Pzemwr1Xzs0SOIqLqUNNf_4Jb5BJN_fo4pU3Za4,1866
5
- hardpy/hardpy_panel/frontend/dist/asset-manifest.json,sha256=Z6KDx9WMNghh4d_7w52kTSdEec-lup56JR6JEP3WY94,2824
3
+ hardpy/hardpy_panel/api.py,sha256=zm24Spyhl7bqqJTcfyIydajq0_mqrAaxzac53V-Y_-Q,1979
4
+ hardpy/hardpy_panel/runner.py,sha256=lJFVFAbh-y6utBKW7pEqlbAPgS1PLGTP3s-YRE52Sq4,2121
5
+ hardpy/hardpy_panel/frontend/dist/asset-manifest.json,sha256=WKgjuP2ksuEcMXfMu-965znPimRRRa9gNuzhU16L4kg,2824
6
6
  hardpy/hardpy_panel/frontend/dist/favicon.ico,sha256=sgIk5PKUKEKBDpkSrc8dJgjpObp0iF82Mec0GpfKId4,15406
7
- hardpy/hardpy_panel/frontend/dist/index.html,sha256=u1IJG5LkBLmaPgL-dYJ4rIfmxzf0xNhmmOupezuobgg,656
7
+ hardpy/hardpy_panel/frontend/dist/index.html,sha256=JsA4OoOv3mDXVkADLj1GvLAdDWb4U8coml1T7tYbfqg,656
8
8
  hardpy/hardpy_panel/frontend/dist/logo512.png,sha256=-fIMbqX7PYUpheK4kX1C1erRTe_hHZwFQYDLrAbhFRU,34188
9
9
  hardpy/hardpy_panel/frontend/dist/manifest.json,sha256=PfmJlN2JMJtHS6OnhU4b4X5wPQC_yRBdjesjoirObSA,502
10
10
  hardpy/hardpy_panel/frontend/dist/static/css/main.e8a862f1.css,sha256=gNl6kGMBhtswNrUU6X2S6uosRU7xhxqI_p9gsEtBUqE,318244
@@ -21,9 +21,9 @@ hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-all-paths.f63155c9.c
21
21
  hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-all-paths.f63155c9.chunk.js.map,sha256=p1xKHRK4AZutkZsQHiWSNU61tYp7I3iUuyLLm3eqkHQ,2833
22
22
  hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-split-paths-by-size-loader.52a072d3.chunk.js,sha256=Jl5xm_jQ9IXKhCagHHvnIhwYXb379Q5FFBiqPoKdUIE,605
23
23
  hardpy/hardpy_panel/frontend/dist/static/js/blueprint-icons-split-paths-by-size-loader.52a072d3.chunk.js.map,sha256=amJiG2QaJMRR9Y2M0C2soOqd75xdQHhsVKjwrDSIIT0,2224
24
- hardpy/hardpy_panel/frontend/dist/static/js/main.8ef63e9b.js,sha256=9SXZe8r-m8MAvgrl4PaSoD0o6oBWPHudDGDuyCoGQwY,982299
25
- hardpy/hardpy_panel/frontend/dist/static/js/main.8ef63e9b.js.LICENSE.txt,sha256=ForPNukClWMEP3pF9LMYoU-ve-LsyCH-rYU8eLki_FY,2315
26
- hardpy/hardpy_panel/frontend/dist/static/js/main.8ef63e9b.js.map,sha256=P_8SM0ZMRM_x_RqxwaL6yF0DS7na9I_aMnBgBu8x8Fg,4943986
24
+ hardpy/hardpy_panel/frontend/dist/static/js/main.da686f40.js,sha256=20nf2pUAWN6a3DcOxklP_Jb6HJoWrr0qEJ6CQc0iaQA,1061346
25
+ hardpy/hardpy_panel/frontend/dist/static/js/main.da686f40.js.LICENSE.txt,sha256=ForPNukClWMEP3pF9LMYoU-ve-LsyCH-rYU8eLki_FY,2315
26
+ hardpy/hardpy_panel/frontend/dist/static/js/main.da686f40.js.map,sha256=LbY-5IH1ePKLPGT6gshR1eK_5j2L4U_Bpl5T7WLkXpo,5301647
27
27
  hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.520846c6beb41df528c8.eot,sha256=PTCTrQYNHX2hIPUaYWtOKrI30-iQGXt_EGxq6JCXie0,117628
28
28
  hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.5c52b39c697f2323ce8b.svg,sha256=lDCQy06aS-9bmhwuFOUs-EdcR8MP2wqwAwky5oamtkQ,509417
29
29
  hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-16.84db1772f4bfb529f64f.woff,sha256=edyqQN0nw4dNBs1pgr7pQB7nJhhR6T_YfklFcG_fHj0,53344
@@ -36,20 +36,20 @@ hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.afbadb627d43b7
36
36
  hardpy/hardpy_panel/frontend/dist/static/media/blueprint-icons-20.e857f5a5132b8bfa71a1.woff,sha256=mQZTxE1PyyAL16VWuASOvXlZFwuI4aCPvbrhfgpdIdU,55356
37
37
  hardpy/hardpy_panel/frontend/dist/static/media/logo_smol.5b16f92447a4a9e80331.png,sha256=E4K7drvhJCg9HcTpRihOXZhVJVBZ7-W97Se-3tDb46o,14485
38
38
  hardpy/pytest_hardpy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- hardpy/pytest_hardpy/plugin.py,sha256=lL3ZNVVSlS7VzpVDiF_SWbnbFBbK9vXtD6JZwqBoObA,10973
40
- hardpy/pytest_hardpy/pytest_call.py,sha256=CrbAw_W6A1HU06xIcylivgNKVUzGoo0B0ikNqflHbDo,6171
41
- hardpy/pytest_hardpy/pytest_wrapper.py,sha256=bC8ROwAEjo3TpXpNtHXUS-C_fpIyeCPtgfGBSZ82aI8,3554
39
+ hardpy/pytest_hardpy/plugin.py,sha256=2-0ql5By6ROROEcHtxlXwpJ3zIqUeLC7GSOBE7AAkM4,12643
40
+ hardpy/pytest_hardpy/pytest_call.py,sha256=mjRF1cXWmCRe9CL_Bz_kbEKUyDSldF7Ja1FkmjHIDdE,8442
41
+ hardpy/pytest_hardpy/pytest_wrapper.py,sha256=18kCuS-TVXcXC2QiMsrbc5gHjv48tIMv0F3xAJCdi_U,4508
42
42
  hardpy/pytest_hardpy/db/__init__.py,sha256=MxDufncz0zgRAxrndvPXXW4NrU7rRP7MzIrR7S5Cwwo,558
43
43
  hardpy/pytest_hardpy/db/base_connector.py,sha256=7KUgPY-GmAo8MFN4OFpG5y3WH1xjohRnpeQ1gxQF1tg,751
44
44
  hardpy/pytest_hardpy/db/base_server.py,sha256=uBnq5zGkzEIq_EGzLw0C8kfDEDvQyN52Y6L41KKL9FQ,397
45
45
  hardpy/pytest_hardpy/db/base_store.py,sha256=DiYaBOwufEOdtDpo9dUb3ZaZ7-c1FInAWjLpUXSEFHA,2668
46
- hardpy/pytest_hardpy/db/const.py,sha256=ffYW54TP0aNF5LhW3g_2G5kVuvqAMWfuJqNDzWZg2nI,618
46
+ hardpy/pytest_hardpy/db/const.py,sha256=b4Hq0gaT8SF5YBg21EIHoF3RMMHD3nRJBpvGmvVYQn0,648
47
47
  hardpy/pytest_hardpy/db/runstore.py,sha256=50amoTIO7OTqd5Ks1_7uTzqjCldLpTapkxbIQOgj1sQ,1023
48
- hardpy/pytest_hardpy/db/schema.py,sha256=iIclTudP0tauTWLYiEW9MMlvBfuWOteA7eRzDU5gKwI,6859
48
+ hardpy/pytest_hardpy/db/schema.py,sha256=AAf1qXEge0Bd2xwwx4A2DBOtUkbE36DTpbsOPczPUZ4,7529
49
49
  hardpy/pytest_hardpy/db/statestore.py,sha256=1BUfA4oqG4vx7z5v_uUYi_Un6YA769JeuShxDicrl9Q,636
50
50
  hardpy/pytest_hardpy/reporter/__init__.py,sha256=RONapygH3c_FyXokAlyCVJXGV2cV_jCYDxLymvvA1uE,322
51
51
  hardpy/pytest_hardpy/reporter/base.py,sha256=M-lwli64ty9FW8HlGEpUyoFsZv48tyNgzPjCWVUrATY,1941
52
- hardpy/pytest_hardpy/reporter/hook_reporter.py,sha256=TE6IzQVH10ce8JXWtep80kgyVOicU02C75FDpV6NfSQ,9895
52
+ hardpy/pytest_hardpy/reporter/hook_reporter.py,sha256=kZ3jx--ne9l3a27TmVdZCPBoqy53EuHYg2fHDGuJNes,10068
53
53
  hardpy/pytest_hardpy/reporter/runner_reporter.py,sha256=NXkBIoERqmLI-GYtHavmOWC5t6NIpcAE-NECrUKIAJs,827
54
54
  hardpy/pytest_hardpy/result/__init__.py,sha256=NMeCGx3yh8ds9VpaUpuNFDxbwgYFq3e-o7W6rYIv8uI,346
55
55
  hardpy/pytest_hardpy/result/couchdb_config.py,sha256=QZryfA2QoHIjzbVT3OAD76DCNppCghtRWdZMZ5v7KhY,611
@@ -57,15 +57,16 @@ hardpy/pytest_hardpy/result/report_loader/__init__.py,sha256=FuHuD6IFZyaKj0yu5ur
57
57
  hardpy/pytest_hardpy/result/report_loader/couchdb_loader.py,sha256=1BGncK1NnwYJanm5TYETjMkqR7tmrUfGK8Sgnp2JZC8,2203
58
58
  hardpy/pytest_hardpy/result/report_reader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
59
  hardpy/pytest_hardpy/result/report_reader/couchdb_reader.py,sha256=WqetspIsQzu3iJ_HGo3XNkx4iXj6RC9o_SaRqyT-c-c,5634
60
- hardpy/pytest_hardpy/utils/__init__.py,sha256=IeOr27pgzvMolQtEXJxODJKNdQAFww8EjjW-Gy1Gx2M,684
61
- hardpy/pytest_hardpy/utils/config_data.py,sha256=F8khHsvkEsJjDnoHeLjI0rgsAfETN7nSlEP2snf2kio,990
60
+ hardpy/pytest_hardpy/utils/__init__.py,sha256=UjvjcEV2r5nBB2hmez5cSq-TNdH6NNKmfSDVwxj66cE,1181
61
+ hardpy/pytest_hardpy/utils/config_data.py,sha256=953nSUndqfiqk6oVMb7GYA4RYCFPIKkPpSthXgKtKKY,1113
62
62
  hardpy/pytest_hardpy/utils/const.py,sha256=rjW1Rzhe2vCr8GeQqeN_pafepGDYhjhY4u1VfTOVI6U,625
63
- hardpy/pytest_hardpy/utils/exception.py,sha256=5GnVkOchSPDEXaOXaruO0YzKXoY7b3Y5mVU5-51ZKRg,457
63
+ hardpy/pytest_hardpy/utils/dialog_box.py,sha256=XmKQoPuBmesgv8fBm3FvIarRGxYFbvYq54vXnINA5fw,8196
64
+ hardpy/pytest_hardpy/utils/exception.py,sha256=khifykRuFS7GyIyQcJeMg6VOgwhPPvzNqnIuyD2onzg,785
64
65
  hardpy/pytest_hardpy/utils/node_info.py,sha256=VnEbhKBNAL5xpuFtJTCg90TmkjkFCQA59F5W2RcOlx4,3157
65
66
  hardpy/pytest_hardpy/utils/progress_calculator.py,sha256=r0qb3p6_yDIyLeCshF3Ceo5pCzd3BoTahL4rCD2oMNw,1041
66
67
  hardpy/pytest_hardpy/utils/singleton.py,sha256=C8cgRDydnG2b5dcN1LCLw4aM-AUMAvJc1W39mTkNWlQ,614
67
- hardpy-0.3.0.dist-info/METADATA,sha256=lWSZtZSy7b_PISotSgTw3lyM1X2uJPj0dVmOfI2A9N8,4096
68
- hardpy-0.3.0.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
69
- hardpy-0.3.0.dist-info/entry_points.txt,sha256=q73g5GfznSUpjkayi0SV4uaAtrf7D-7rmDoWoEZmZe0,120
70
- hardpy-0.3.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
71
- hardpy-0.3.0.dist-info/RECORD,,
68
+ hardpy-0.5.0.dist-info/METADATA,sha256=uzKt39irvwMS6Y73kXPR1JRW-VEEfg1tEszfUTvPtiM,4305
69
+ hardpy-0.5.0.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
70
+ hardpy-0.5.0.dist-info/entry_points.txt,sha256=q73g5GfznSUpjkayi0SV4uaAtrf7D-7rmDoWoEZmZe0,120
71
+ hardpy-0.5.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
72
+ hardpy-0.5.0.dist-info/RECORD,,