makcu 0.2.1__py3-none-any.whl → 2.1.2__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.
- makcu/__main__.py +109 -19
- makcu/conftest.py +3 -0
- makcu/connection.py +2 -4
- makcu/controller.py +1 -1
- makcu/makcu.pyi +1 -3
- makcu/mouse.py +1 -3
- {makcu-0.2.1.dist-info → makcu-2.1.2.dist-info}/METADATA +15 -15
- makcu-2.1.2.dist-info/RECORD +16 -0
- makcu-0.2.1.dist-info/RECORD +0 -16
- {makcu-0.2.1.dist-info → makcu-2.1.2.dist-info}/WHEEL +0 -0
- {makcu-0.2.1.dist-info → makcu-2.1.2.dist-info}/licenses/LICENSE +0 -0
- {makcu-0.2.1.dist-info → makcu-2.1.2.dist-info}/top_level.txt +0 -0
makcu/__main__.py
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
import sys
|
2
2
|
import os
|
3
3
|
from pathlib import Path
|
4
|
-
from typing import List, NoReturn
|
4
|
+
from typing import List, NoReturn, Optional, Tuple
|
5
5
|
import pytest
|
6
6
|
import time
|
7
7
|
from makcu import create_controller, MakcuConnectionError, MakcuController
|
8
8
|
import json
|
9
9
|
import re
|
10
|
+
import subprocess
|
11
|
+
|
12
|
+
makcu_version = "v2.1.2"
|
10
13
|
|
11
14
|
def debug_console():
|
12
15
|
controller = create_controller()
|
@@ -60,7 +63,31 @@ def test_port(port: str) -> None:
|
|
60
63
|
except Exception as e:
|
61
64
|
print(f"❌ Unexpected error: {e}")
|
62
65
|
|
63
|
-
def
|
66
|
+
def check_pytest_html_installed() -> bool:
|
67
|
+
"""Check if pytest-html is installed."""
|
68
|
+
try:
|
69
|
+
import pytest_html
|
70
|
+
return True
|
71
|
+
except ImportError:
|
72
|
+
return False
|
73
|
+
|
74
|
+
def find_writable_directory() -> Path:
|
75
|
+
"""Find a writable directory for the HTML report."""
|
76
|
+
# Try current working directory first
|
77
|
+
cwd = Path.cwd()
|
78
|
+
if os.access(cwd, os.W_OK):
|
79
|
+
return cwd
|
80
|
+
|
81
|
+
# Try user's home directory
|
82
|
+
home = Path.home()
|
83
|
+
if os.access(home, os.W_OK):
|
84
|
+
return home
|
85
|
+
|
86
|
+
# Try temp directory as last resort
|
87
|
+
import tempfile
|
88
|
+
return Path(tempfile.gettempdir())
|
89
|
+
|
90
|
+
def parse_html_results(html_file: Path) -> Tuple[List[Tuple[str, str, int]], int]:
|
64
91
|
if not html_file.exists():
|
65
92
|
raise FileNotFoundError(f"HTML report not found: {html_file}")
|
66
93
|
|
@@ -102,6 +129,12 @@ def parse_html_results(html_file: Path):
|
|
102
129
|
return test_results, total_ms
|
103
130
|
|
104
131
|
def run_tests() -> NoReturn:
|
132
|
+
# Check if pytest-html is installed
|
133
|
+
if not check_pytest_html_installed():
|
134
|
+
print("❌ pytest-html is not installed. Please install it via:")
|
135
|
+
print(" pip install pytest-html")
|
136
|
+
sys.exit(1)
|
137
|
+
|
105
138
|
try:
|
106
139
|
from rich.console import Console
|
107
140
|
from rich.table import Table
|
@@ -110,12 +143,11 @@ def run_tests() -> NoReturn:
|
|
110
143
|
from rich.align import Align
|
111
144
|
from rich import print as rprint
|
112
145
|
from rich.text import Text
|
113
|
-
import subprocess
|
114
146
|
|
115
147
|
console = Console()
|
116
148
|
|
117
149
|
header = Panel.fit(
|
118
|
-
"[bold cyan]Makcu Test Suite
|
150
|
+
f"[bold cyan]Makcu Test Suite {makcu_version}[/bold cyan]\n[dim]High-Performance Python Library[/dim]",
|
119
151
|
border_style="bright_blue"
|
120
152
|
)
|
121
153
|
console.print(Align.center(header))
|
@@ -123,7 +155,20 @@ def run_tests() -> NoReturn:
|
|
123
155
|
|
124
156
|
package_dir: Path = Path(__file__).resolve().parent
|
125
157
|
test_file: Path = package_dir / "test_suite.py"
|
126
|
-
|
158
|
+
|
159
|
+
# Find writable directory and create HTML path
|
160
|
+
writable_dir = find_writable_directory()
|
161
|
+
html_file: Path = writable_dir / "latest_pytest.html"
|
162
|
+
|
163
|
+
# Clean up old report if it exists
|
164
|
+
if html_file.exists():
|
165
|
+
try:
|
166
|
+
html_file.unlink()
|
167
|
+
except Exception:
|
168
|
+
pass
|
169
|
+
|
170
|
+
console.print(f"[dim]Running pytest to generate: {html_file}[/dim]")
|
171
|
+
console.print(f"[dim]Working directory: {Path.cwd()}[/dim]")
|
127
172
|
|
128
173
|
start_time = time.time()
|
129
174
|
|
@@ -138,6 +183,7 @@ def run_tests() -> NoReturn:
|
|
138
183
|
) as progress:
|
139
184
|
task = progress.add_task("[cyan]Running tests...", total=100)
|
140
185
|
|
186
|
+
# Run pytest with explicit output capturing
|
141
187
|
result = subprocess.run(
|
142
188
|
[
|
143
189
|
sys.executable, "-m", "pytest",
|
@@ -146,15 +192,36 @@ def run_tests() -> NoReturn:
|
|
146
192
|
"-q",
|
147
193
|
"--tb=no",
|
148
194
|
"--html", str(html_file),
|
149
|
-
"--self-contained-html"
|
195
|
+
"--self-contained-html",
|
196
|
+
"-v" # Add verbose to help debug
|
150
197
|
],
|
151
|
-
|
152
|
-
stderr=subprocess.DEVNULL,
|
198
|
+
capture_output=True,
|
153
199
|
text=True
|
154
200
|
)
|
155
201
|
|
156
202
|
progress.update(task, completed=100)
|
157
203
|
|
204
|
+
# Check if HTML file was created
|
205
|
+
if not html_file.exists():
|
206
|
+
console.print(f"[red]❌ HTML report was not created at: {html_file}[/red]")
|
207
|
+
console.print(f"[yellow]pytest exit code: {result.returncode}[/yellow]")
|
208
|
+
if result.stdout:
|
209
|
+
console.print("[yellow]stdout:[/yellow]")
|
210
|
+
console.print(result.stdout)
|
211
|
+
if result.stderr:
|
212
|
+
console.print("[red]stderr:[/red]")
|
213
|
+
console.print(result.stderr)
|
214
|
+
|
215
|
+
# Try to run tests without HTML report
|
216
|
+
console.print("\n[yellow]Running tests without HTML report...[/yellow]")
|
217
|
+
result2 = subprocess.run(
|
218
|
+
[sys.executable, "-m", "pytest", str(test_file), "-v"],
|
219
|
+
capture_output=True,
|
220
|
+
text=True
|
221
|
+
)
|
222
|
+
console.print(result2.stdout)
|
223
|
+
sys.exit(1)
|
224
|
+
|
158
225
|
try:
|
159
226
|
test_results, total_ms = parse_html_results(html_file)
|
160
227
|
except (FileNotFoundError, ValueError) as e:
|
@@ -232,6 +299,10 @@ def run_tests() -> NoReturn:
|
|
232
299
|
perf_text = Text("⚠️ No test results parsed. Check your test suite.", style="bold red")
|
233
300
|
|
234
301
|
console.print(Align.center(Panel(perf_text, border_style="green")))
|
302
|
+
|
303
|
+
# Print the location of the HTML report
|
304
|
+
console.print(f"\n[dim]HTML report saved to: {html_file}[/dim]")
|
305
|
+
|
235
306
|
sys.exit(0 if failed == 0 else 1)
|
236
307
|
|
237
308
|
except ImportError:
|
@@ -240,16 +311,35 @@ def run_tests() -> NoReturn:
|
|
240
311
|
|
241
312
|
package_dir: Path = Path(__file__).resolve().parent
|
242
313
|
test_file: Path = package_dir / "test_suite.py"
|
243
|
-
|
314
|
+
|
315
|
+
# Find writable directory
|
316
|
+
writable_dir = find_writable_directory()
|
317
|
+
html_file: Path = writable_dir / "latest_pytest.html"
|
318
|
+
|
319
|
+
print(f"HTML report will be saved to: {html_file}")
|
320
|
+
|
321
|
+
# Use subprocess instead of pytest.main for better control
|
322
|
+
result = subprocess.run(
|
323
|
+
[
|
324
|
+
sys.executable, "-m", "pytest",
|
325
|
+
str(test_file),
|
326
|
+
"--rootdir", str(package_dir),
|
327
|
+
"-q",
|
328
|
+
"--tb=no",
|
329
|
+
"--html", str(html_file),
|
330
|
+
"--self-contained-html"
|
331
|
+
],
|
332
|
+
capture_output=True,
|
333
|
+
text=True
|
334
|
+
)
|
244
335
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
])
|
336
|
+
if not html_file.exists():
|
337
|
+
print(f"\n❌ HTML report was not created. pytest exit code: {result.returncode}")
|
338
|
+
if result.stdout:
|
339
|
+
print("stdout:", result.stdout)
|
340
|
+
if result.stderr:
|
341
|
+
print("stderr:", result.stderr)
|
342
|
+
sys.exit(1)
|
253
343
|
|
254
344
|
try:
|
255
345
|
test_results, total_ms = parse_html_results(html_file)
|
@@ -264,12 +354,12 @@ def run_tests() -> NoReturn:
|
|
264
354
|
except (FileNotFoundError, ValueError):
|
265
355
|
print("\n⚠️ Could not parse HTML results for summary")
|
266
356
|
|
267
|
-
if result != 0:
|
357
|
+
if result.returncode != 0:
|
268
358
|
print("\n❌ Some tests failed.")
|
269
359
|
else:
|
270
360
|
print("\n✅ All tests passed.")
|
271
361
|
|
272
|
-
sys.exit(result)
|
362
|
+
sys.exit(result.returncode)
|
273
363
|
|
274
364
|
def main() -> None:
|
275
365
|
args: List[str] = sys.argv[1:]
|
makcu/conftest.py
CHANGED
makcu/connection.py
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
import serial
|
2
2
|
import threading
|
3
3
|
import time
|
4
|
-
import
|
5
|
-
from typing import Optional, Dict, Callable, List, Any, Tuple, Union
|
4
|
+
from typing import Optional, Dict, Callable
|
6
5
|
from serial.tools import list_ports
|
7
|
-
from dataclasses import dataclass
|
6
|
+
from dataclasses import dataclass
|
8
7
|
from collections import deque
|
9
8
|
from concurrent.futures import Future
|
10
9
|
import logging
|
11
10
|
import asyncio
|
12
|
-
import re
|
13
11
|
from .errors import MakcuConnectionError, MakcuTimeoutError
|
14
12
|
from .enums import MouseButton
|
15
13
|
|
makcu/controller.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import asyncio
|
2
2
|
import random
|
3
3
|
import time
|
4
|
-
from typing import Optional, Dict, Callable, Union, List
|
4
|
+
from typing import Optional, Dict, Callable, Union, List
|
5
5
|
from concurrent.futures import ThreadPoolExecutor
|
6
6
|
from .mouse import Mouse
|
7
7
|
from .connection import SerialTransport
|
makcu/makcu.pyi
CHANGED
@@ -1,7 +1,5 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import List
|
2
2
|
from .controller import MakcuController
|
3
|
-
from .enums import MouseButton
|
4
|
-
from .errors import MakcuError, MakcuConnectionError, MakcuCommandError, MakcuTimeoutError, MakcuResponseError
|
5
3
|
|
6
4
|
__version__: str
|
7
5
|
__all__: List[str]
|
makcu/mouse.py
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
from typing import Dict,
|
1
|
+
from typing import Dict, Union
|
2
2
|
from .enums import MouseButton
|
3
3
|
from .connection import SerialTransport
|
4
4
|
from .errors import MakcuCommandError
|
5
5
|
from serial.tools import list_ports
|
6
|
-
import time
|
7
|
-
|
8
6
|
|
9
7
|
class AxisButton:
|
10
8
|
def __init__(self, name: str) -> None:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: makcu
|
3
|
-
Version:
|
3
|
+
Version: 2.1.2
|
4
4
|
Summary: Python library for Makcu hardware device control
|
5
5
|
Author: SleepyTotem
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
@@ -701,14 +701,14 @@ Requires-Python: >=3.7
|
|
701
701
|
Description-Content-Type: text/markdown
|
702
702
|
License-File: LICENSE
|
703
703
|
Requires-Dist: pyserial>=3.5
|
704
|
-
|
705
|
-
Requires-Dist: pytest>=
|
706
|
-
Requires-Dist:
|
707
|
-
Requires-Dist:
|
708
|
-
Requires-Dist:
|
704
|
+
Requires-Dist: pytest>=7.0
|
705
|
+
Requires-Dist: pytest-html>=3.1
|
706
|
+
Requires-Dist: build>=0.10
|
707
|
+
Requires-Dist: twine>=4.0
|
708
|
+
Requires-Dist: rich>=14.0
|
709
709
|
Dynamic: license-file
|
710
710
|
|
711
|
-
# 🖱️ Makcu Python Library v2.
|
711
|
+
# 🖱️ Makcu Python Library v2.1.2
|
712
712
|
|
713
713
|
[](https://pypi.org/project/makcu/)
|
714
714
|
[](https://pypi.org/project/makcu/)
|
@@ -716,15 +716,15 @@ Dynamic: license-file
|
|
716
716
|
|
717
717
|
Makcu Py Lib is a high-performance Python library for controlling Makcu devices — now with **async/await support**, **zero-delay command execution**, and **automatic reconnection**!
|
718
718
|
|
719
|
-
##
|
719
|
+
## What's New in v2.0
|
720
720
|
|
721
|
-
-
|
722
|
-
-
|
723
|
-
-
|
724
|
-
-
|
725
|
-
-
|
726
|
-
-
|
727
|
-
-
|
721
|
+
- **Async/Await Support**: Full async API for modern Python applications
|
722
|
+
- **Zero-Delay Commands**: Removed all `sleep()` calls with proper command tracking
|
723
|
+
- **Auto-Reconnection**: Automatic device reconnection on disconnect
|
724
|
+
- **Parallel Operations**: Execute multiple commands simultaneously
|
725
|
+
- **Enhanced Debugging**: Better logging and error tracking
|
726
|
+
- **Gaming-Optimized**: Sub-3ms command execution for 240Hz+ gaming
|
727
|
+
- **Ultra-Fast Performance**: 10-50x faster than >=v1.4
|
728
728
|
|
729
729
|
---
|
730
730
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
makcu/__init__.py,sha256=HyjxvhE5feNyh4ZMY5U0U_X-7BzltSh_gOsX_o5mSLA,1745
|
2
|
+
makcu/__main__.py,sha256=9zqNog6Ugh1QjsZUOh7ZDTa1KwiOxLfDoOiBw2neiCo,14385
|
3
|
+
makcu/conftest.py,sha256=9BAV65DARtS4rELiMI5Gb6I-shxdnzCBA4g1lOYjG5s,896
|
4
|
+
makcu/connection.py,sha256=OT3cB7T8eJT4boCqajdPQtlTEMy-W9n9dqIIIVbL3Xc,15135
|
5
|
+
makcu/controller.py,sha256=csQMJ97zSv-i6sI8EHkqosFByS859B-hg2unvjHPKcA,13059
|
6
|
+
makcu/enums.py,sha256=VmvCLmpghVHuTAkvCGMfA14MgWTtFVMfsGQQNnJ58Ts,126
|
7
|
+
makcu/errors.py,sha256=X_eWPKkVgcyryT6-_7jjVkcHKtrAZAsarbfMRpIcz58,242
|
8
|
+
makcu/makcu.pyi,sha256=tSmJ3zs6zFClZll5DcWd17ZQr9nvDDJqhKXDR1hr7dk,247
|
9
|
+
makcu/mouse.py,sha256=CzUI3vr_IrvYuEfGzDWgtm6wSUl9kYimvmHaR2azuL0,8406
|
10
|
+
makcu/py.typed,sha256=lI_IPBO6A6a5eY5kRQDNsdSydUb3sFWtcC_ML8FNftU,111
|
11
|
+
makcu/test_suite.py,sha256=7Rsq5sKeR4zvCMTNZDv6TCYMKs7B3EVTuwyIDgHfdk8,4092
|
12
|
+
makcu-2.1.2.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
13
|
+
makcu-2.1.2.dist-info/METADATA,sha256=B_TaI8tz6CQi6ERMvtIbGxfokjjZY-Z5-hrJDCO8jps,55063
|
14
|
+
makcu-2.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
15
|
+
makcu-2.1.2.dist-info/top_level.txt,sha256=IRO1UVb5LK_ovjau0g4oObyXQqy00tVEE-yF5lPgw1w,6
|
16
|
+
makcu-2.1.2.dist-info/RECORD,,
|
makcu-0.2.1.dist-info/RECORD
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
makcu/__init__.py,sha256=HyjxvhE5feNyh4ZMY5U0U_X-7BzltSh_gOsX_o5mSLA,1745
|
2
|
-
makcu/__main__.py,sha256=6D21UxHHEd1USLo5CLsGAm3i-HPmZ_j7BBjHbUer3Zg,11097
|
3
|
-
makcu/conftest.py,sha256=t4ZP5WeZv-lgfplgbwojiJWQXeuYASU9jNDRrsSX2V4,863
|
4
|
-
makcu/connection.py,sha256=Xz8KsfhPu2S3KfRnoeASM-6gmfRZklME5MQjaRawrjk,15193
|
5
|
-
makcu/controller.py,sha256=kxHGtGZTE4JHZozZeRaet_AXK-69LZG_ZP6ZPg8gqjw,13064
|
6
|
-
makcu/enums.py,sha256=VmvCLmpghVHuTAkvCGMfA14MgWTtFVMfsGQQNnJ58Ts,126
|
7
|
-
makcu/errors.py,sha256=X_eWPKkVgcyryT6-_7jjVkcHKtrAZAsarbfMRpIcz58,242
|
8
|
-
makcu/makcu.pyi,sha256=a8_vQ43MAqVxcASQiCHoYYG_LkfM5NEBAab5dgxcVK4,424
|
9
|
-
makcu/mouse.py,sha256=d-6wcRrNgfLE6QQ26YLbQj-u4EaGAMXn0bVsb0cncoM,8442
|
10
|
-
makcu/py.typed,sha256=lI_IPBO6A6a5eY5kRQDNsdSydUb3sFWtcC_ML8FNftU,111
|
11
|
-
makcu/test_suite.py,sha256=7Rsq5sKeR4zvCMTNZDv6TCYMKs7B3EVTuwyIDgHfdk8,4092
|
12
|
-
makcu-0.2.1.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
|
13
|
-
makcu-0.2.1.dist-info/METADATA,sha256=uHpFIqMrVUFtti2luLjVpH2mqSl2uwQ5a39FeAPJwRs,55161
|
14
|
-
makcu-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
15
|
-
makcu-0.2.1.dist-info/top_level.txt,sha256=IRO1UVb5LK_ovjau0g4oObyXQqy00tVEE-yF5lPgw1w,6
|
16
|
-
makcu-0.2.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|