nano-dev-utils 0.3.5__py3-none-any.whl → 0.4.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.
Potentially problematic release.
This version of nano-dev-utils might be problematic. Click here for more details.
- nano_dev_utils/release_ports.py +2 -7
- nano_dev_utils/timers.py +22 -18
- {nano_dev_utils-0.3.5.dist-info → nano_dev_utils-0.4.2.dist-info}/METADATA +36 -27
- nano_dev_utils-0.4.2.dist-info/RECORD +8 -0
- nano_dev_utils-0.3.5.dist-info/RECORD +0 -8
- {nano_dev_utils-0.3.5.dist-info → nano_dev_utils-0.4.2.dist-info}/WHEEL +0 -0
- {nano_dev_utils-0.3.5.dist-info → nano_dev_utils-0.4.2.dist-info}/licenses/LICENSE.md +0 -0
nano_dev_utils/release_ports.py
CHANGED
|
@@ -2,12 +2,8 @@ import platform
|
|
|
2
2
|
import subprocess
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
logging.basicConfig(filename='port release.log',
|
|
7
|
-
level=logging.INFO,
|
|
8
|
-
format='%(asctime)s - %(levelname)s: %(message)s',
|
|
9
|
-
datefmt='%d-%m-%Y %H:%M:%S')
|
|
10
5
|
lgr = logging.getLogger(__name__)
|
|
6
|
+
"""Module-level logger. Configure using logging.basicConfig() in your application."""
|
|
11
7
|
|
|
12
8
|
PROXY_SERVER = 6277
|
|
13
9
|
INSPECTOR_CLIENT = 6274
|
|
@@ -152,5 +148,4 @@ class PortsRelease:
|
|
|
152
148
|
else:
|
|
153
149
|
lgr.error(self._log_terminate_failed(pid=pid, port=port))
|
|
154
150
|
except Exception as e:
|
|
155
|
-
lgr.error(self._log_unexpected_error(e))
|
|
156
|
-
|
|
151
|
+
lgr.error(self._log_unexpected_error(e))
|
nano_dev_utils/timers.py
CHANGED
|
@@ -1,35 +1,39 @@
|
|
|
1
1
|
from functools import wraps
|
|
2
2
|
import time
|
|
3
|
+
from typing import Callable, ParamSpec, TypeVar
|
|
4
|
+
P = ParamSpec('P')
|
|
5
|
+
R = TypeVar('R')
|
|
3
6
|
|
|
4
7
|
|
|
5
8
|
class Timer:
|
|
6
9
|
def __init__(self, precision=4, verbose=False):
|
|
7
10
|
self.precision = precision
|
|
8
11
|
self.verbose = verbose
|
|
12
|
+
self.units = [
|
|
13
|
+
(1e9, 's'),
|
|
14
|
+
(1e6, 'ms'),
|
|
15
|
+
(1e3, 'μs'),
|
|
16
|
+
(1.0, 'ns')
|
|
17
|
+
]
|
|
9
18
|
|
|
10
|
-
def timeit(self, func):
|
|
19
|
+
def timeit(self, func: Callable[P, R]) -> Callable[P, R]:
|
|
20
|
+
"""Decorator that times function execution with automatic unit scaling."""
|
|
11
21
|
@wraps(func)
|
|
12
|
-
def
|
|
13
|
-
|
|
22
|
+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
23
|
+
start = time.perf_counter_ns()
|
|
14
24
|
result = func(*args, **kwargs)
|
|
15
|
-
|
|
16
|
-
total_ns = end_time - start_time
|
|
25
|
+
elapsed = time.perf_counter_ns() - start
|
|
17
26
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
value = total_ns / 1_000_000
|
|
26
|
-
unit = "ms"
|
|
27
|
-
else:
|
|
28
|
-
value = total_ns / 1_000_000_000
|
|
29
|
-
unit = "s"
|
|
27
|
+
value = elapsed
|
|
28
|
+
unit = 'ns'
|
|
29
|
+
|
|
30
|
+
for divisor, unit in self.units:
|
|
31
|
+
if elapsed >= divisor or unit == 'ns':
|
|
32
|
+
value = elapsed / divisor
|
|
33
|
+
break
|
|
30
34
|
|
|
31
35
|
extra_info = f'{args} {kwargs} ' if self.verbose else ''
|
|
32
36
|
print(f'{func.__name__} {extra_info}took {value:.{self.precision}f} [{unit}]')
|
|
33
37
|
return result
|
|
34
38
|
|
|
35
|
-
return
|
|
39
|
+
return wrapper
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nano_dev_utils
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.2
|
|
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
|
|
@@ -24,22 +24,23 @@ This module provides a `Timer` class for measuring the execution time of code bl
|
|
|
24
24
|
|
|
25
25
|
#### `Timer` Class
|
|
26
26
|
|
|
27
|
-
* **`__init__(self, precision=4, verbose=False)`**: Initializes a `Timer` instance.
|
|
28
|
-
* `precision
|
|
27
|
+
* **`__init__(self, precision: int = 4, verbose: bool = False)`**: Initializes a `Timer` instance.
|
|
28
|
+
* `precision`: The number of decimal places to record and
|
|
29
29
|
display time durations. Defaults to 4.
|
|
30
|
-
* `verbose
|
|
31
|
-
|
|
30
|
+
* `verbose`: Optionally displays the function's positional arguments (args) and keyword arguments (kwargs).
|
|
31
|
+
Defaults to `False`.
|
|
32
32
|
|
|
33
|
-
* **`timeit(self, func
|
|
34
|
-
|
|
35
|
-
*
|
|
36
|
-
|
|
33
|
+
* **`timeit(self, func: Callable[P, R]) -> Callable[P, R]`**:
|
|
34
|
+
Decorator that times function execution with automatic unit scaling.
|
|
35
|
+
* When the decorated function is called, this decorator records the start and end times,
|
|
36
|
+
calculates the total execution time, prints the function name and execution
|
|
37
|
+
time (optionally including arguments), and returns the result of the original function.
|
|
37
38
|
|
|
38
39
|
#### Example Usage:
|
|
39
40
|
|
|
40
41
|
```python
|
|
41
42
|
import time
|
|
42
|
-
from
|
|
43
|
+
from nano_dev_utils.timers import Timer
|
|
43
44
|
|
|
44
45
|
timer = Timer(precision=6, verbose=True)
|
|
45
46
|
|
|
@@ -66,13 +67,13 @@ This module provides an `Importer` class for lazy loading and caching module imp
|
|
|
66
67
|
* **`import_mod_from_lib(self, library: str, module_name: str) -> ModuleType | Any`**: Lazily imports a module from a specified library and caches it.
|
|
67
68
|
* `library` (str): The name of the library (e.g., "os", "requests").
|
|
68
69
|
* `module_name` (str): The name of the module to import within the library (e.g., "path", "get").
|
|
69
|
-
* Returns the imported module. If the module has already been imported, it returns
|
|
70
|
+
* Returns the imported module. If the module has already been imported, it returns a cached instance.
|
|
70
71
|
* Raises `ImportError` if the module cannot be found.
|
|
71
72
|
|
|
72
73
|
#### Example Usage:
|
|
73
74
|
|
|
74
75
|
```python
|
|
75
|
-
from
|
|
76
|
+
from nano_dev_utils.dynamic_importer import Importer
|
|
76
77
|
|
|
77
78
|
importer = Importer()
|
|
78
79
|
|
|
@@ -90,34 +91,42 @@ print(f"Imported os.path again (cached): {os_path_again}")
|
|
|
90
91
|
### `release_ports.py`
|
|
91
92
|
|
|
92
93
|
This module provides a `PortsRelease` class to identify and release processes
|
|
93
|
-
listening on specified TCP ports.
|
|
94
|
+
listening on specified TCP ports.
|
|
95
|
+
It supports Windows, Linux, and macOS.
|
|
94
96
|
|
|
95
97
|
#### `PortsRelease` Class
|
|
96
98
|
|
|
97
|
-
* **`__init__(self, default_ports:
|
|
99
|
+
* **`__init__(self, default_ports: list[int] | None = None)`**:
|
|
98
100
|
* Initializes a `PortsRelease` instance.
|
|
99
|
-
* `default_ports
|
|
100
|
-
* If not provided, it defaults to `[6277, 6274]`.
|
|
101
|
+
* `default_ports`: A list of default ports to manage. If not provided, it defaults to `[6277, 6274]`.
|
|
101
102
|
|
|
102
|
-
* **`get_pid_by_port(port: int) ->
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
* **`get_pid_by_port(self, port: int) -> int | None`**: A static method that attempts to find
|
|
104
|
+
a process ID (PID) listening on a given `port`.
|
|
105
|
+
* It uses platform-specific commands (`netstat`, `ss`, `lsof`).
|
|
106
|
+
* Returns the PID if found, otherwise `None`.
|
|
105
107
|
|
|
106
|
-
* **`kill_process(pid: int) -> bool`**: A static method that attempts to kill the process
|
|
107
|
-
with the given `pid`.
|
|
108
|
+
* **`kill_process(self, pid: int) -> bool`**: A static method that attempts to kill the process
|
|
109
|
+
with the given `pid`.
|
|
110
|
+
* It uses platform-specific commands (`taskkill`, `kill -9`).
|
|
108
111
|
* Returns `True` if the process was successfully killed, `False` otherwise.
|
|
109
112
|
|
|
110
|
-
* **`release_all(self, ports:
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
|
|
114
|
-
* For each port, it first tries to get the PID and then attempts to kill the process.
|
|
113
|
+
* **`release_all(self, ports: list[int] | None = None) -> None`**: Releases all processes listening on the specified `ports`.
|
|
114
|
+
* `ports`: A list of ports to release.
|
|
115
|
+
* If `None`, it uses the `default_ports` defined during initialization.
|
|
116
|
+
* For each port, it first tries to get the PID and then attempts to kill the process.
|
|
115
117
|
* It logs the actions and any errors encountered. Invalid port numbers in the provided list are skipped.
|
|
116
118
|
|
|
117
119
|
#### Example Usage:
|
|
118
120
|
|
|
119
121
|
```python
|
|
120
|
-
|
|
122
|
+
import logging
|
|
123
|
+
from nano_dev_utils import PortsRelease
|
|
124
|
+
|
|
125
|
+
# in case you're interested in logging
|
|
126
|
+
logging.basicConfig(filename='port release.log',
|
|
127
|
+
level=logging.INFO, # specify here desire level, e.g. DEBUG etc.
|
|
128
|
+
format='%(asctime)s - %(levelname)s: %(message)s',
|
|
129
|
+
datefmt='%d-%m-%Y %H:%M:%S')
|
|
121
130
|
|
|
122
131
|
# Create an instance with default ports
|
|
123
132
|
port_releaser = PortsRelease()
|
|
@@ -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=9tScRYGWrzCaiK8UkiRV8vfflSEYyueokyn0mspivek,5910
|
|
4
|
+
nano_dev_utils/timers.py,sha256=gDIsJekCz8VmlakTs5ttQY-K05J1e0kOtNpyTtCuav0,1232
|
|
5
|
+
nano_dev_utils-0.4.2.dist-info/METADATA,sha256=CGzGDb4SjgAHJ_mWudrcWH64vXm14ELlgC2TQUL5tzE,5333
|
|
6
|
+
nano_dev_utils-0.4.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
7
|
+
nano_dev_utils-0.4.2.dist-info/licenses/LICENSE.md,sha256=Muenl7Bw_LdtHZtlOMAP7Kt97gDCq8WWp2605eDWhHU,1089
|
|
8
|
+
nano_dev_utils-0.4.2.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=lw4pNCvkVG36UIMlibpPzKUlNPlvwuYQ3klAd7XLSug,6042
|
|
4
|
-
nano_dev_utils/timers.py,sha256=niQhXzMuwUh7cdOPi8trKySbv8pFkP4XO5cLBqOxlng,1142
|
|
5
|
-
nano_dev_utils-0.3.5.dist-info/METADATA,sha256=AZDVeHhP4MN7Gn7I-LBvz51R7uuBcMky4YOyZTy0B6Q,5069
|
|
6
|
-
nano_dev_utils-0.3.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
7
|
-
nano_dev_utils-0.3.5.dist-info/licenses/LICENSE.md,sha256=Muenl7Bw_LdtHZtlOMAP7Kt97gDCq8WWp2605eDWhHU,1089
|
|
8
|
-
nano_dev_utils-0.3.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|