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

@@ -1,6 +1,7 @@
1
- """Nano-Utils-Yaronday - A collection of small Python utilities for developers.
1
+ """nano-dev-utils - A collection of small Python utilities for developers.
2
2
  Copyright (c) 2025 Yaron Dayan
3
3
  """
4
+
4
5
  from .dynamic_importer import Importer
5
6
  from .timers import Timer
6
7
  from .release_ports import PortsRelease, PROXY_SERVER, INSPECTOR_CLIENT
@@ -17,12 +17,14 @@ class Importer:
17
17
  if module_name in self.imported_modules:
18
18
  return self.imported_modules[module_name]
19
19
 
20
+ lib_mod = f'{library}.{module_name}'
21
+
20
22
  try:
21
- module = importlib.import_module(f"{library}.{module_name}")
23
+ module = importlib.import_module(lib_mod)
22
24
  self.imported_modules[module_name] = module
23
25
  return module
24
26
  except ModuleNotFoundError as e:
25
- raise ImportError(f"Could not import {library}.{module_name}") from e
27
+ raise ImportError(f'Could not import {lib_mod}') from e
26
28
 
27
29
 
28
30
 
@@ -1,7 +1,6 @@
1
1
  import platform
2
2
  import subprocess
3
3
  import logging
4
- from typing import Optional
5
4
 
6
5
 
7
6
  logging.basicConfig(filename='port release.log',
@@ -15,7 +14,7 @@ INSPECTOR_CLIENT = 6274
15
14
 
16
15
 
17
16
  class PortsRelease:
18
- def __init__(self, default_ports: Optional[list[int]] = None):
17
+ def __init__(self, default_ports: list[int] | None = None):
19
18
  self.default_ports: list[int] = default_ports \
20
19
  if default_ports is not None else [PROXY_SERVER, INSPECTOR_CLIENT]
21
20
 
@@ -36,8 +35,8 @@ class PortsRelease:
36
35
  return f'Invalid port number: {port}. Skipping.'
37
36
 
38
37
  @staticmethod
39
- def _log_terminate_failed(pid: int, port: Optional[int] = None,
40
- error: Optional[str] = None) -> str:
38
+ def _log_terminate_failed(pid: int, port: int | None = None,
39
+ error: str | None = None) -> str:
41
40
  base_msg = f'Failed to terminate process {pid}'
42
41
  if port:
43
42
  base_msg += f' (on port {port})'
@@ -61,14 +60,15 @@ class PortsRelease:
61
60
  def _log_unsupported_os() -> str:
62
61
  return f'Unsupported OS: {platform.system()}'
63
62
 
64
- def get_pid_by_port(self, port: int) -> Optional[int]:
63
+ def get_pid_by_port(self, port: int) -> int | None:
65
64
  """Gets the process ID (PID) listening on the specified port."""
65
+ system = platform.system()
66
66
  try:
67
- cmd: Optional[str] = {
67
+ cmd: str = {
68
68
  "Windows": f"netstat -ano | findstr :{port}",
69
69
  "Linux": f"ss -lntp | grep :{port}",
70
70
  "Darwin": f"lsof -i :{port}",
71
- }.get(platform.system())
71
+ }.get(system, "")
72
72
  if not cmd:
73
73
  lgr.error(self._log_unsupported_os())
74
74
  return None
@@ -85,13 +85,13 @@ class PortsRelease:
85
85
  for line in lines:
86
86
  if str(port) in line:
87
87
  parts: list[str] = line.split()
88
- if platform.system() == "Windows" and len(parts) > 4:
88
+ if system == "Windows" and len(parts) > 4:
89
89
  try:
90
90
  return int(parts[4])
91
91
  except ValueError:
92
92
  lgr.error(self._log_line_parse_failed(line))
93
93
  return None
94
- elif platform.system() == "Linux":
94
+ elif system == "Linux":
95
95
  for part in parts:
96
96
  if "pid=" in part:
97
97
  try:
@@ -99,7 +99,7 @@ class PortsRelease:
99
99
  except ValueError:
100
100
  lgr.error(self._log_line_parse_failed(line))
101
101
  return None
102
- elif platform.system() == "Darwin" and len(parts) > 1:
102
+ elif system == "Darwin" and len(parts) > 1:
103
103
  try:
104
104
  return int(parts[1])
105
105
  except ValueError:
@@ -113,11 +113,11 @@ class PortsRelease:
113
113
  def kill_process(self, pid: int) -> bool:
114
114
  """Kills the process with the specified PID."""
115
115
  try:
116
- cmd: Optional[str] = {
116
+ cmd: str = {
117
117
  'Windows': f'taskkill /F /PID {pid}',
118
118
  'Linux': f'kill -9 {pid}',
119
119
  'Darwin': f'kill -9 {pid}',
120
- }.get(platform.system())
120
+ }.get(platform.system(), "") # fallback to empty string
121
121
  if not cmd:
122
122
  lgr.error(self._log_unsupported_os())
123
123
  return False
@@ -132,7 +132,7 @@ class PortsRelease:
132
132
  lgr.error(self._log_unexpected_error(e))
133
133
  return False
134
134
 
135
- def release_all(self, ports: Optional[list[int]] = None) -> None:
135
+ def release_all(self, ports: list[int] | None = None) -> None:
136
136
  try:
137
137
  ports_to_release: list[int] = self.default_ports if ports is None else ports
138
138
 
@@ -141,7 +141,7 @@ class PortsRelease:
141
141
  lgr.error(self._log_invalid_port(port))
142
142
  continue
143
143
 
144
- pid: Optional[int] = self.get_pid_by_port(port)
144
+ pid: int | None = self.get_pid_by_port(port)
145
145
  if pid is None:
146
146
  lgr.info(self._log_no_process(port))
147
147
  continue
nano_dev_utils/timers.py CHANGED
@@ -10,15 +10,26 @@ class Timer:
10
10
  def timeit(self, func):
11
11
  @wraps(func)
12
12
  def timeit_wrapper(*args, **kwargs):
13
- start_time = time.perf_counter()
13
+ start_time = time.perf_counter_ns()
14
14
  result = func(*args, **kwargs)
15
- end_time = time.perf_counter()
16
- total_time = end_time - start_time
17
- extra_info = f'{args} {kwargs} ' if self.verbose else ''
18
- print(f'{func.__name__} {extra_info}took {total_time:.{self.precision}f} [s]')
19
- return result
20
- return timeit_wrapper
21
-
15
+ end_time = time.perf_counter_ns()
16
+ total_ns = end_time - start_time
22
17
 
18
+ if total_ns < 1_000: # 1μs
19
+ value = total_ns
20
+ unit = "ns"
21
+ elif total_ns < 1_000_000: # < 1ms
22
+ value = total_ns / 1_000
23
+ unit = "μs"
24
+ elif total_ns < 1_000_000_000: # < 1s
25
+ value = total_ns / 1_000_000
26
+ unit = "ms"
27
+ else:
28
+ value = total_ns / 1_000_000_000
29
+ unit = "s"
23
30
 
31
+ extra_info = f'{args} {kwargs} ' if self.verbose else ''
32
+ print(f'{func.__name__} {extra_info}took {value:.{self.precision}f} [{unit}]')
33
+ return result
24
34
 
35
+ return timeit_wrapper
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nano_dev_utils
3
- Version: 0.2.1
3
+ Version: 0.3.4
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
7
7
  Author-email: Yaron Dayan <yaronday77@gmail.com>
8
- License-Expression: MIT
8
+ License: MIT
9
9
  License-File: LICENSE.md
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python :: 3
@@ -29,7 +29,6 @@ This module provides a `Timer` class for measuring the execution time of code bl
29
29
  * display time durations. Defaults to 4.
30
30
  * `verbose` (bool, optional): If `True`, the function's arguments and keyword
31
31
  * arguments will be included in the printed timing output. Defaults to `False`.
32
- * `timing_records` (list): A list to store the recorded timing durations as formatted strings.
33
32
 
34
33
  * **`timeit(self, func)`**: A decorator that measures the execution time of the decorated function.
35
34
  * When the decorated function is called, this decorator records the start and end times,
@@ -0,0 +1,8 @@
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=lw4pNCvkVG36UIMlibpPzKUlNPlvwuYQ3klAd7XLSug,6042
4
+ nano_dev_utils/timers.py,sha256=niQhXzMuwUh7cdOPi8trKySbv8pFkP4XO5cLBqOxlng,1142
5
+ nano_dev_utils-0.3.4.dist-info/METADATA,sha256=-zrL2OSOxADIeiXy1gKvOLzd-B2wA2haY5wbkYZv3jA,5049
6
+ nano_dev_utils-0.3.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
+ nano_dev_utils-0.3.4.dist-info/licenses/LICENSE.md,sha256=Muenl7Bw_LdtHZtlOMAP7Kt97gDCq8WWp2605eDWhHU,1089
8
+ nano_dev_utils-0.3.4.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- nano_dev_utils/__init__.py,sha256=qcbhac5zx27mAgmNvwwHzNxyYsMRK-WElB8n4e8c81A,374
2
- nano_dev_utils/dynamic_importer.py,sha256=sW09aj3_6tzm6mOQbBuqZjp6O2PnpG0_2Ol4Zs_nXe4,902
3
- nano_dev_utils/release_ports.py,sha256=HpKL7kawNrLE5RPLByoX_nflaLkQfTnlZKyEIZqSG8g,6081
4
- nano_dev_utils/timers.py,sha256=_WBY0EQLTn3m-41hw0bzpZ2jR9jn2pmbhfAOWmQkKho,690
5
- nano_dev_utils-0.2.1.dist-info/METADATA,sha256=561_a1OX9cNMOcu_0cabbp86RfgjjWUHpSAMNGkdqtU,5159
6
- nano_dev_utils-0.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
- nano_dev_utils-0.2.1.dist-info/licenses/LICENSE.md,sha256=Muenl7Bw_LdtHZtlOMAP7Kt97gDCq8WWp2605eDWhHU,1089
8
- nano_dev_utils-0.2.1.dist-info/RECORD,,