Coverage for src/engines/base.py: 100.00%
34 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-22 10:53 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-22 10:53 +0000
1#!/usr/bin/env python3
3# Standard libraries
4from typing import Any, List, Optional
6# Components
7from ..system.platform import Platform
9# Base class
10class Base:
12 # Members
13 _child: Optional[Any] = None
15 # Constructor
16 def __init__(self, command: str) -> None:
18 # Virtual method
19 raise NotImplementedError() # pragma: no cover
21 # Read
22 def _read(self) -> bytes | List[bytes | str] | str:
24 # Virtual method
25 raise NotImplementedError() # pragma: no cover
27 # Is alive
28 def isalive(self) -> bool:
30 # Result
31 assert self._child is not None
32 return bool(self._child.isalive())
34 # Read
35 def read(self, masks: Optional[List[str]] = None) -> None:
37 # Read stream
38 while True:
40 # Acquire output
41 output = self._read()
43 # Interrupted stream
44 if not output:
45 break
47 # Print stream
48 if isinstance(output, (bytes, str)):
49 if isinstance(output, bytes):
50 output = output.decode('utf-8', errors='ignore')
51 output = output.replace('\x1b[6n', '')
52 if masks:
53 for mask in masks:
54 output = output.replace(mask, '')
55 print(output, end='')
56 Platform.flush()
58 # Lines lines
59 elif isinstance(output, list): # pragma: no cover
60 for line in output:
61 if isinstance(line, bytes):
62 line = line.decode('utf-8', errors='ignore')
63 line = line.replace('\x1b[6n', '')
64 if masks:
65 for mask in masks:
66 line = line.replace(mask, '')
67 print(line)
68 Platform.flush()
70 # Send
71 def send(self, key: bytes | str) -> None:
73 # Send key
74 assert self._child is not None
75 self._child.send(key)
77 # Status
78 def status(self) -> int:
80 # Fallback status
81 assert self._child is not None
82 if self._child.exitstatus is None:
83 return 1
85 # Process status
86 return int(self._child.exitstatus)
88 # Terminate
89 def terminate(self, force: bool = False) -> None:
91 # Terminate process
92 assert self._child is not None
93 self._child.terminate(force=force)