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 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 parse_html_results(html_file: Path):
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 v2.0[/bold cyan]\n[dim]High-Performance Python Library[/dim]",
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
- html_file: Path = package_dir.parent / "latest_pytest.html"
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
- stdout=subprocess.DEVNULL,
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
- html_file: Path = package_dir.parent / "latest_pytest.html"
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
- result = pytest.main([
246
- str(test_file),
247
- "--rootdir", str(package_dir),
248
- "-q",
249
- "--tb=no",
250
- "--html", str(html_file),
251
- "--self-contained-html"
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
@@ -8,6 +8,9 @@ def makcu(request):
8
8
 
9
9
  def cleanup():
10
10
  if ctrl.is_connected():
11
+
12
+ time.sleep(0.1)
13
+
11
14
  ctrl.lock_left(False)
12
15
  ctrl.lock_right(False)
13
16
  ctrl.lock_middle(False)
makcu/connection.py CHANGED
@@ -1,15 +1,13 @@
1
1
  import serial
2
2
  import threading
3
3
  import time
4
- import struct
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, field
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, Any
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 Optional, Dict, Callable, List, Union
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, Optional, List, Union, Any
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: 0.2.1
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
- Provides-Extra: dev
705
- Requires-Dist: pytest>=7.0; extra == "dev"
706
- Requires-Dist: pytest-html>=3.1; extra == "dev"
707
- Requires-Dist: build>=0.10; extra == "dev"
708
- Requires-Dist: twine>=4.0; extra == "dev"
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.0
711
+ # 🖱️ Makcu Python Library v2.1.2
712
712
 
713
713
  [![PyPI Version](https://img.shields.io/pypi/v/makcu.svg)](https://pypi.org/project/makcu/)
714
714
  [![Python Support](https://img.shields.io/pypi/pyversions/makcu.svg)](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
- ## 🚀 What's New in v2.0
719
+ ## What's New in v2.0
720
720
 
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
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,,
@@ -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