nano-dev-utils 0.4.4__py3-none-any.whl → 0.5.3__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.

Potentially problematic release.


This version of nano-dev-utils might be problematic. Click here for more details.

@@ -5,11 +5,14 @@ Copyright (c) 2025 Yaron Dayan
5
5
  from .dynamic_importer import Importer
6
6
  from .timers import Timer
7
7
  from .release_ports import PortsRelease, PROXY_SERVER, INSPECTOR_CLIENT
8
+ from importlib.metadata import version
9
+
10
+ __version__ = version('nano-dev-utils')
8
11
 
9
12
  __all__ = [
10
- "Importer",
11
- "Timer",
12
- "PortsRelease",
13
- "PROXY_SERVER",
14
- "INSPECTOR_CLIENT",
13
+ 'Importer',
14
+ 'Timer',
15
+ 'PortsRelease',
16
+ 'PROXY_SERVER',
17
+ 'INSPECTOR_CLIENT',
15
18
  ]
@@ -25,6 +25,3 @@ class Importer:
25
25
  return module
26
26
  except ModuleNotFoundError as e:
27
27
  raise ImportError(f'Could not import {lib_mod}') from e
28
-
29
-
30
-
@@ -11,8 +11,11 @@ INSPECTOR_CLIENT = 6274
11
11
 
12
12
  class PortsRelease:
13
13
  def __init__(self, default_ports: list[int] | None = None):
14
- self.default_ports: list[int] = default_ports \
15
- if default_ports is not None else [PROXY_SERVER, INSPECTOR_CLIENT]
14
+ self.default_ports: list[int] = (
15
+ default_ports
16
+ if default_ports is not None
17
+ else [PROXY_SERVER, INSPECTOR_CLIENT]
18
+ )
16
19
 
17
20
  @staticmethod
18
21
  def _log_process_found(port: int, pid: int) -> str:
@@ -31,8 +34,9 @@ class PortsRelease:
31
34
  return f'Invalid port number: {port}. Skipping.'
32
35
 
33
36
  @staticmethod
34
- def _log_terminate_failed(pid: int, port: int | None = None,
35
- error: str | None = None) -> str:
37
+ def _log_terminate_failed(
38
+ pid: int, port: int | None = None, error: str | None = None
39
+ ) -> str:
36
40
  base_msg = f'Failed to terminate process {pid}'
37
41
  if port:
38
42
  base_msg += f' (on port {port})'
@@ -61,17 +65,17 @@ class PortsRelease:
61
65
  system = platform.system()
62
66
  try:
63
67
  cmd: str = {
64
- "Windows": f"netstat -ano | findstr :{port}",
65
- "Linux": f"ss -lntp | grep :{port}",
66
- "Darwin": f"lsof -i :{port}",
67
- }.get(system, "")
68
+ 'Windows': f'netstat -ano | findstr :{port}',
69
+ 'Linux': f'ss -lntp | grep :{port}',
70
+ 'Darwin': f'lsof -i :{port}',
71
+ }.get(system, '')
68
72
  if not cmd:
69
73
  lgr.error(self._log_unsupported_os())
70
74
  return None
71
75
 
72
- process = subprocess.Popen(cmd, shell=True,
73
- stdout=subprocess.PIPE,
74
- stderr=subprocess.PIPE)
76
+ process = subprocess.Popen(
77
+ cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
78
+ )
75
79
  output, error = process.communicate()
76
80
  if error:
77
81
  lgr.error(self._log_cmd_error(error))
@@ -81,21 +85,21 @@ class PortsRelease:
81
85
  for line in lines:
82
86
  if str(port) in line:
83
87
  parts: list[str] = line.split()
84
- if system == "Windows" and len(parts) > 4:
88
+ if system == 'Windows' and len(parts) > 4:
85
89
  try:
86
90
  return int(parts[4])
87
91
  except ValueError:
88
92
  lgr.error(self._log_line_parse_failed(line))
89
93
  return None
90
- elif system == "Linux":
94
+ elif system == 'Linux':
91
95
  for part in parts:
92
- if "pid=" in part:
96
+ if 'pid=' in part:
93
97
  try:
94
- return int(part.split("=")[1])
98
+ return int(part.split('=')[1])
95
99
  except ValueError:
96
100
  lgr.error(self._log_line_parse_failed(line))
97
101
  return None
98
- elif system == "Darwin" and len(parts) > 1:
102
+ elif system == 'Darwin' and len(parts) > 1:
99
103
  try:
100
104
  return int(parts[1])
101
105
  except ValueError:
@@ -113,7 +117,7 @@ class PortsRelease:
113
117
  'Windows': f'taskkill /F /PID {pid}',
114
118
  'Linux': f'kill -9 {pid}',
115
119
  'Darwin': f'kill -9 {pid}',
116
- }.get(platform.system(), "") # fallback to empty string
120
+ }.get(platform.system(), '') # fallback to empty string
117
121
  if not cmd:
118
122
  lgr.error(self._log_unsupported_os())
119
123
  return False
@@ -148,4 +152,4 @@ class PortsRelease:
148
152
  else:
149
153
  lgr.error(self._log_terminate_failed(pid=pid, port=port))
150
154
  except Exception as e:
151
- lgr.error(self._log_unexpected_error(e))
155
+ lgr.error(self._log_unexpected_error(e))
nano_dev_utils/timers.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from functools import wraps
2
2
  import time
3
3
  from typing import Callable, ParamSpec, TypeVar
4
+
4
5
  P = ParamSpec('P')
5
6
  R = TypeVar('R')
6
7
 
@@ -9,15 +10,11 @@ class Timer:
9
10
  def __init__(self, precision=4, verbose=False):
10
11
  self.precision = precision
11
12
  self.verbose = verbose
12
- self.units = [
13
- (1e9, 's'),
14
- (1e6, 'ms'),
15
- (1e3, 'μs'),
16
- (1.0, 'ns')
17
- ]
13
+ self.units = [(1e9, 's'), (1e6, 'ms'), (1e3, 'μs'), (1.0, 'ns')]
18
14
 
19
15
  def timeit(self, func: Callable[P, R]) -> Callable[P, R]:
20
16
  """Decorator that times function execution with automatic unit scaling."""
17
+
21
18
  @wraps(func)
22
19
  def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
23
20
  start = time.perf_counter_ns()
@@ -33,7 +30,9 @@ class Timer:
33
30
  break
34
31
 
35
32
  extra_info = f'{args} {kwargs} ' if self.verbose else ''
36
- print(f'{func.__name__} {extra_info}took {value:.{self.precision}f} [{unit}]')
33
+ print(
34
+ f'{func.__name__} {extra_info}took {value:.{self.precision}f} [{unit}]'
35
+ )
37
36
  return result
38
37
 
39
38
  return wrapper
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nano_dev_utils
3
- Version: 0.4.4
3
+ Version: 0.5.3
4
4
  Summary: A collection of small Python utilities for developers.
5
5
  Project-URL: Homepage, https://github.com/yaronday/nano_utils
6
6
  Project-URL: Issues, https://github.com/yaronday/nano_utils/issues
@@ -10,6 +10,9 @@ License-File: LICENSE.md
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: >=3.10
13
+ Provides-Extra: test
14
+ Requires-Dist: pytest-mock>=3.14.0; extra == 'test'
15
+ Requires-Dist: pytest>=8.2.0; extra == 'test'
13
16
  Description-Content-Type: text/markdown
14
17
 
15
18
  # nano_dev_utils
@@ -142,4 +145,4 @@ port_releaser.release_all()
142
145
 
143
146
  ## License
144
147
  This project is licensed under the MIT License.
145
- See [LICENSE](https://github.com/yaronday/nano_dev_utils/blob/master/LICENSE.md) for details.
148
+ See [LICENSE](LICENSE.md) for details.
@@ -0,0 +1,8 @@
1
+ nano_dev_utils/__init__.py,sha256=imiI367TPj5s4IFmi-VrKJLbdkIxdIPISNscthoaS9U,454
2
+ nano_dev_utils/dynamic_importer.py,sha256=cm2VwDYSGwhGZNO3uMX-O0LaKtEFtzkPm7BrZW4igG4,911
3
+ nano_dev_utils/release_ports.py,sha256=sgmoPax9Hpcse1rHbBSnDJWTkvV6aWpZ5hQFxBKhGR8,5886
4
+ nano_dev_utils/timers.py,sha256=EJFFU9y5qv9w9mfjtBsrgyCXj7NoBpXH0AzPewFnRa0,1205
5
+ nano_dev_utils-0.5.3.dist-info/METADATA,sha256=OgEVESoryfQXgRwkK5ipyJm1KeLMCC1yeisGQsfqego,5419
6
+ nano_dev_utils-0.5.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
+ nano_dev_utils-0.5.3.dist-info/licenses/LICENSE.md,sha256=Muenl7Bw_LdtHZtlOMAP7Kt97gDCq8WWp2605eDWhHU,1089
8
+ nano_dev_utils-0.5.3.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- nano_dev_utils/__init__.py,sha256=NFw7FWw1oJnOmRLe8btPbLJX7e5O78Keaw5fow29tOQ,371
2
- nano_dev_utils/dynamic_importer.py,sha256=ufMEQKhtlDIYorjWVv58CKm-GWCwwgzp2pSSMznzlkc,917
3
- nano_dev_utils/release_ports.py,sha256=9tScRYGWrzCaiK8UkiRV8vfflSEYyueokyn0mspivek,5910
4
- nano_dev_utils/timers.py,sha256=gDIsJekCz8VmlakTs5ttQY-K05J1e0kOtNpyTtCuav0,1232
5
- nano_dev_utils-0.4.4.dist-info/METADATA,sha256=JDkLCI843UHrDbVeYZ5wJYpdOHd4XQKpGUTkZvLwVcc,5355
6
- nano_dev_utils-0.4.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
- nano_dev_utils-0.4.4.dist-info/licenses/LICENSE.md,sha256=Muenl7Bw_LdtHZtlOMAP7Kt97gDCq8WWp2605eDWhHU,1089
8
- nano_dev_utils-0.4.4.dist-info/RECORD,,