nano-dev-utils 0.2.1__py3-none-any.whl → 0.3.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.
- nano_dev_utils/__init__.py +2 -1
- nano_dev_utils/release_ports.py +14 -14
- nano_dev_utils/timers.py +19 -8
- {nano_dev_utils-0.2.1.dist-info → nano_dev_utils-0.3.3.dist-info}/METADATA +2 -3
- nano_dev_utils-0.3.3.dist-info/RECORD +8 -0
- nano_dev_utils-0.2.1.dist-info/RECORD +0 -8
- {nano_dev_utils-0.2.1.dist-info → nano_dev_utils-0.3.3.dist-info}/WHEEL +0 -0
- {nano_dev_utils-0.2.1.dist-info → nano_dev_utils-0.3.3.dist-info}/licenses/LICENSE.md +0 -0
nano_dev_utils/__init__.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
"""
|
|
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
|
nano_dev_utils/release_ports.py
CHANGED
|
@@ -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:
|
|
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:
|
|
40
|
-
error:
|
|
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) ->
|
|
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:
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
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.
|
|
13
|
+
start_time = time.perf_counter_ns()
|
|
14
14
|
result = func(*args, **kwargs)
|
|
15
|
-
end_time = time.
|
|
16
|
-
|
|
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.
|
|
3
|
+
Version: 0.3.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
|
|
7
7
|
Author-email: Yaron Dayan <yaronday77@gmail.com>
|
|
8
|
-
License
|
|
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=sW09aj3_6tzm6mOQbBuqZjp6O2PnpG0_2Ol4Zs_nXe4,902
|
|
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.3.dist-info/METADATA,sha256=CsZ-gMgfclYXXmRyKJz7XaDoQJTQqa29AJuvIm1sJEM,5049
|
|
6
|
+
nano_dev_utils-0.3.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
7
|
+
nano_dev_utils-0.3.3.dist-info/licenses/LICENSE.md,sha256=Muenl7Bw_LdtHZtlOMAP7Kt97gDCq8WWp2605eDWhHU,1089
|
|
8
|
+
nano_dev_utils-0.3.3.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,,
|
|
File without changes
|
|
File without changes
|