Passed
Push — main ( 520e83...b06663 )
by Douglas
01:43
created

pocketutils.tools.sys_tools   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 62
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 39
dl 0
loc 62
rs 10
c 0
b 0
f 0
wmc 7

4 Methods

Rating   Name   Duplication   Size   Complexity  
A SystemTools.trace_signals() 0 9 2
A ExitHandler.__call__() 0 5 2
A SystemTools.trace_exit() 0 6 1
A SignalHandler.__call__() 0 5 2
1
"""
2
Low-level tools (e.g. memory management).
3
"""
4
import atexit
5
import signal
6
import sys
7
import traceback
8
from collections import Callable
0 ignored issues
show
Bug introduced by
The name Callable does not seem to exist in module collections.
Loading history...
9
from dataclasses import dataclass
10
from typing import Any, Union
11
12
from pocketutils.core.input_output import Writeable
0 ignored issues
show
Bug introduced by
The name core does not seem to exist in module pocketutils.
Loading history...
13
14
from pocketutils.tools.base_tools import BaseTools
15
16
17
@dataclass(frozen=True, repr=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
18
class SignalHandler:
19
    name: str
20
    code: int
21
    desc: str
22
    sink: Union[Writeable, Callable[[str], Any]]
23
24
    def __call__(self):
25
        sys.stderr.write(f"~~{self.name}[{self.code}] ({self.desc})~~")
26
        traceback.print_stack(file=sys.stderr)
27
        for line in traceback.format_stack():
28
            sys.stderr.write(line)
29
30
31
@dataclass(frozen=True, repr=True)
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
32
class ExitHandler:
33
    sink: Writeable
34
35
    def __call__(self):
36
        self.sink.write(f"~~EXIT~~")
0 ignored issues
show
introduced by
Using an f-string that does not have any interpolated variables
Loading history...
37
        traceback.print_stack(file=sys.stderr)
38
        for line in traceback.format_stack():
39
            self.sink.write(line)
40
41
42
class SystemTools(BaseTools):
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
43
    @classmethod
44
    def trace_signals(cls, sink: Writeable = sys.stderr) -> None:
45
        """
46
        Registers signal handlers for all signals that log the traceback.
47
        Uses ``signal.signal``.
48
        """
49
        for sig in signal.valid_signals():
0 ignored issues
show
Bug introduced by
The Module signal does not seem to have a member named valid_signals.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
50
            handler = SignalHandler(sig.name, sig.value, signal.strsignal(sig), sink)
0 ignored issues
show
Bug introduced by
The Module signal does not seem to have a member named strsignal.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
51
            signal.signal(sig.value, handler)
52
53
    @classmethod
54
    def trace_exit(cls, sink: Writeable = sys.stderr) -> None:
55
        """
56
        Registers an exit handler via ``atexit.register`` that logs the traceback.
57
        """
58
        atexit.register(ExitHandler(sink))
59
60
61
__all__ = ["SignalHandler", "ExitHandler", "SystemTools"]
62