diff --git a/docs/requirements.txt b/docs/requirements.txt index b9f36d6..1a49c79 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,39 +1,39 @@ alabaster==0.7.12 -astroid==2.9.0 +astroid==2.9.3 atomicwrites==1.4.0 -attrs==21.2.0 +attrs==21.4.0 babel==2.9.1 certifi==2021.10.8 -charset-normalizer==2.0.8 +charset-normalizer==2.0.10 colorama==0.4.4 -coverage==6.2 +coverage==6.3 docutils==0.17.1 idna==3.3 imagesize==1.3.0 -importlib-metadata==4.8.2 +importlib-metadata==4.10.1 iniconfig==1.1.1 intelhex==2.3.0 isort==5.10.1 jinja2==3.0.3 -lazy-object-proxy==1.6.0 +lazy-object-proxy==1.7.1 markupsafe==2.0.1 mccabe==0.6.1 mypy-extensions==0.4.3 mypy==0.910 packaging==21.3 -platformdirs==2.4.0 +platformdirs==2.4.1 pluggy==1.0.0 py==1.11.0 -pygments==2.10.0 -pylint==2.12.1 -pyparsing==3.0.6 +pygments==2.11.2 +pylint==2.12.2 +pyparsing==3.0.7 pyserial==3.5 pytest==6.2.5 pytz==2021.3 -requests==2.26.0 +requests==2.27.1 snowballstemmer==2.2.0 sphinx-rtd-theme==1.0.0 -sphinx==4.3.1 +sphinx==4.4.0 sphinxcontrib-applehelp==1.0.2 sphinxcontrib-devhelp==1.0.2 sphinxcontrib-htmlhelp==2.0.0 @@ -42,7 +42,7 @@ sphinxcontrib-qthelp==1.0.3 sphinxcontrib-serializinghtml==1.1.5 toml==0.10.2 typed-ast==1.4.3 -typing-extensions==4.0.0 -urllib3==1.26.7 +typing-extensions==4.0.1 +urllib3==1.26.8 wrapt==1.13.3 -zipp==3.6.0 \ No newline at end of file +zipp==3.7.0 \ No newline at end of file diff --git a/embutils/__init__.py b/embutils/__init__.py index c9880e6..8fcdd88 100644 --- a/embutils/__init__.py +++ b/embutils/__init__.py @@ -1 +1,12 @@ -__version__ = '0.7.4' +#!/usr/bin/python +# -*- coding: ascii -*- +""" +Embutils module. + +:date: 2021 +:author: Christian Wiche +:contact: cwichel@gmail.com +:license: The MIT License (MIT) +""" +# ------------------------------------- +__version__ = '0.7.5' diff --git a/embutils/repo/__init__.py b/embutils/repo/__init__.py index c6d1170..9d6b177 100644 --- a/embutils/repo/__init__.py +++ b/embutils/repo/__init__.py @@ -1,6 +1,13 @@ -from .build import build_cubeide, build_iar -from .version import ( - VersionHandler, - AbstractVersionUpdater, AbstractVersionExporter, AbstractVersionStorage, - GitBuildVersionUpdater, CCppVersionExporter, SimpleVersionStorage, - ) +#!/usr/bin/python +# -*- coding: ascii -*- +""" +Embutils repository utilities. + +:date: 2021 +:author: Christian Wiche +:contact: cwichel@gmail.com +:license: The MIT License (MIT) +""" +# ------------------------------------- +from .build import * +from .version import * diff --git a/embutils/repo/build.py b/embutils/repo/build.py index 8bd5acf..00410fe 100644 --- a/embutils/repo/build.py +++ b/embutils/repo/build.py @@ -8,11 +8,14 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ - +# ------------------------------------- from ..utils.path import TPPath, Path from ..utils.subprocess import execute +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -76,3 +79,10 @@ def build_iar(config: str, project: TPPath, res = execute(cmd=cmd, pipe=pipe, log=log) if not pipe and res.returncode: print(f"Command:\n{cmd}\nFailed with error:\n{res.stderr}") + + +# -->> Export <<----------------------- +__all__ = [ + "build_cubeide", + "build_iar", + ] diff --git a/embutils/repo/version.py b/embutils/repo/version.py index 9ed0fe6..e6c182e 100644 --- a/embutils/repo/version.py +++ b/embutils/repo/version.py @@ -8,6 +8,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import abc import datetime as dt @@ -22,6 +23,9 @@ from ..utils.version import Version +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ #: Source path PATH_THIS = Path(os.path.abspath(os.path.dirname(__file__))) @@ -149,6 +153,59 @@ def export(self, path: TPPath = os.getcwd(), author: str = "Unknown") -> None: self.exporter.export(version=self, path=path, author=author) +class CCppVersionExporter(AbstractVersionExporter): + """ + C/C++ Version Exporter. + Implements the logic to export the version number to a C/C++ header file + """ + #: Item print size. + ITEMSIZE = 20 + #: Default exported version filename. + FILENAME = "version.h" + #: Supported header file extensions. + SUFFIXES = [".h", ".hpp"] + #: C/C++ header template. + TEMPLATE = PATH_TMPL / "template_version_c.h" + + def export(self, version: Version, path: TPPath, author: str = "Unknown") -> None: + """ + Exports the version number to a C/C++ header using a header template. + + :param Version version: Version to be exported. + :param TPPath path: Target file path. + :param str author: Exported file owner. + """ + # Check file + path = Path.validate_file(path=path, none_ok=False, default=self.FILENAME) + if path.suffix.lower() not in self.SUFFIXES: + raise FileTypeError(f"Header path doesnt have the right suffix ({self.SUFFIXES}): {path}.") + + # Generate header + with path.open(mode="w", encoding="utf-8") as file: + tmpl = self.TEMPLATE.open(mode="r", encoding="utf-8").read() + file.write(tmpl.format( + file=path.name, author=author, + guard=f"_{path.stem}_H_".upper(), + date=f"{dt.datetime.now().strftime('%m/%d/%Y %H:%M:%S')}", + major=self._format(item=version.major), + minor=self._format(item=version.minor), + build=self._format(item=version.build), + version=f"{version}" + )) + + def _format(self, item: int) -> str: + """ + Formats the version number item. + + :param int item: Version item value. + + :return: Item entry. + :rtype: str + """ + hexval = f"0x{item:0{closest_multi(ref=len(hex(item)[2:]), base=2)}X}U" + return f"{hexval:{self.ITEMSIZE}s} /* DEC: {str(item):<{self.ITEMSIZE}s} */" + + class SimpleVersionStorage(AbstractVersionStorage): """ Simple Version Storage. @@ -205,59 +262,18 @@ def update(self, version: Version, path: TPPath) -> None: :param TPPath path: Path in which the repository is initialized. """ # Update the build number with the commit number - ret = execute(cmd="git rev-parse --short HEAD", cwd=f"{path}", pipe=False) + ret = execute(cmd="git rev-parse --short HEAD", cwd=path, pipe=False) ret = (ret.stderr + ret.stdout).lower().strip() version.build = self.NO_BUILD if ("not a git" in ret) else int(ret, 16) -class CCppVersionExporter(AbstractVersionExporter): - """ - C/C++ Version Exporter. - Implements the logic to export the version number to a C/C++ header file - """ - #: Item print size. - ITEMSIZE = 20 - #: Default exported version filename. - FILENAME = "version.h" - #: Supported header file extensions. - SUFFIXES = [".h", ".hpp"] - #: C/C++ header template. - TEMPLATE = PATH_TMPL / "template_version_c.h" - - def export(self, version: Version, path: TPPath, author: str = "Unknown") -> None: - """ - Exports the version number to a C/C++ header using a header template. - - :param Version version: Version to be exported. - :param TPPath path: Target file path. - :param str author: Exported file owner. - """ - # Check file - path = Path.validate_file(path=path, none_ok=False, default=self.FILENAME) - if path.suffix.lower() not in self.SUFFIXES: - raise FileTypeError(f"Header path doesnt have the right suffix ({self.SUFFIXES}): {path}.") - - # Generate header - with path.open(mode="w", encoding="utf-8") as file: - tmpl = self.TEMPLATE.open(mode="r", encoding="utf-8").read() - file.write(tmpl.format( - file=path.name, author=author, - guard=f"_{path.stem}_H_".upper(), - date=f"{dt.datetime.now().strftime('%m/%d/%Y %H:%M:%S')}", - major=self._format(item=version.major), - minor=self._format(item=version.minor), - build=self._format(item=version.build), - version=f"{version}" - )) - - def _format(self, item: int) -> str: - """ - Formats the version number item. - - :param int item: Version item value. - - :return: Item entry. - :rtype: str - """ - hexval = f"0x{item:0{closest_multi(ref=len(hex(item)[2:]), base=2)}X}U" - return f"{hexval:{self.ITEMSIZE}s} /* DEC: {str(item):<{self.ITEMSIZE}s} */" +# -->> Export <<----------------------- +__all__ = [ + "AbstractVersionExporter", + "AbstractVersionStorage", + "AbstractVersionUpdater", + "VersionHandler", + "CCppVersionExporter", + "SimpleVersionStorage", + "GitBuildVersionUpdater", + ] diff --git a/embutils/serial/__init__.py b/embutils/serial/__init__.py index 8e3e277..8f77812 100644 --- a/embutils/serial/__init__.py +++ b/embutils/serial/__init__.py @@ -1,3 +1,14 @@ -from .device import Device, DeviceList, DeviceScanner -from .stream import Stream, AbstractSerializedStreamCodec -from .interface import Interface +#!/usr/bin/python +# -*- coding: ascii -*- +""" +Embutils serial utilities. + +:date: 2021 +:author: Christian Wiche +:contact: cwichel@gmail.com +:license: The MIT License (MIT) +""" +# ------------------------------------- +from .device import * +from .stream import * +from .interface import * diff --git a/embutils/serial/device.py b/embutils/serial/device.py index 655f926..62eb15c 100644 --- a/embutils/serial/device.py +++ b/embutils/serial/device.py @@ -8,6 +8,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import threading as th import typing as tp @@ -22,6 +23,9 @@ from ..utils.time import Timer +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -267,10 +271,10 @@ def filter(self, port: str = None, dev_id: int = None) -> "DeviceList": """ dev_list = self # Filter by port - if isinstance(port, str): + if port is not None: dev_list = DeviceList([dev for dev in dev_list if dev.port == port]) # Filter by ID - if isinstance(dev_id, int): + if dev_id is not None: dev_list = DeviceList([dev for dev in dev_list if dev.id == dev_id]) return dev_list @@ -444,3 +448,11 @@ def _scan(self) -> None: name=f"{self.__class__.__name__}.on_scan_period", task=self.on_scan_period.emit )) + + +# -->> Export <<----------------------- +__all__ = [ + "Device", + "DeviceList", + "DeviceScanner", + ] diff --git a/embutils/serial/interface.py b/embutils/serial/interface.py index 8a8167e..bd83439 100644 --- a/embutils/serial/interface.py +++ b/embutils/serial/interface.py @@ -10,6 +10,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import time import typing as tp @@ -20,6 +21,9 @@ from .stream import Stream +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ #: CallBack definition. AbstractSerialized -> bool CBSerialized2Bool = tp.Callable[[AbstractSerialized], bool] @@ -195,3 +199,10 @@ def on_received(item: AbstractSerialized) -> None: state = "Received" if recv else "Timeout" SDK_LOG.debug(f"Item response: {state} after {tim.elapsed():.03f}[s]") return recv + + +# -->> Export <<----------------------- +__all__ = [ + "CBSerialized2Bool", + "Interface", + ] diff --git a/embutils/serial/stream.py b/embutils/serial/stream.py index 8a78619..25409ec 100644 --- a/embutils/serial/stream.py +++ b/embutils/serial/stream.py @@ -8,6 +8,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import abc import time @@ -21,6 +22,9 @@ from .device import Device +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -242,3 +246,10 @@ def _transfer_debug(item: AbstractSerialized, received: bool) -> None: """ action = "recv" if received else "sent" SDK_LOG.debug(f"Item {action}: {item}") + + +# -->> Export <<----------------------- +__all__ = [ + "AbstractSerializedStreamCodec", + "Stream", + ] diff --git a/embutils/utils/__init__.py b/embutils/utils/__init__.py index 3eb9da3..12446a6 100644 --- a/embutils/utils/__init__.py +++ b/embutils/utils/__init__.py @@ -1,18 +1,29 @@ -from .binary import bin_to_hex, merge_bin, merge_hex -from .bytes import bitmask, reverse_bits, reverse_bytes -from .cobs import COBS -from .common import TPAny, TPByte, TPPath, TPText, CBAny2Any, CBAny2None, CBNone2None -from .crc import CRC -from .enum import IntEnum -from .events import EventHook -from .logger import SDK_LOG, Logger -from .math import closest_multi, closest_pow -from .path import Path, FileTypeError -from .serialized import AbstractSerialized, AbstractSerializedCodec -from .service import AbstractService -from .stream import StreamRedirect -from .subprocess import execute -from .threading import SDK_TP, AbstractThreadTask, SimpleThreadTask, ThreadPool, get_threads, sync -from .time import Timer, timer -from .venv import activate, deactivate -from .version import Version +#!/usr/bin/python +# -*- coding: ascii -*- +""" +Embutils general utilities. + +:date: 2021 +:author: Christian Wiche +:contact: cwichel@gmail.com +:license: The MIT License (MIT) +""" +# ------------------------------------- +from .binary import * +from .bytes import * +from .cobs import * +from .common import * +from .crc import * +from .enum import * +from .events import * +from .logger import * +from .math import * +from .path import * +from .serialized import * +from .service import * +from .stream import * +from .subprocess import * +from .threading import * +from .time import * +from .venv import * +from .version import * diff --git a/embutils/utils/binary.py b/embutils/utils/binary.py index 70a44a1..aa0f187 100644 --- a/embutils/utils/binary.py +++ b/embutils/utils/binary.py @@ -8,6 +8,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import typing as tp @@ -16,6 +17,9 @@ from .path import TPPath, Path +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ RECORD_BYTES = 32 @@ -37,10 +41,10 @@ def bin_to_hex(src: TPPath, out: TPPath = None, off: int = 0x08000000) -> intelh out = Path.validate_file(path=out, none_ok=True) # Generate HEX tmp = intelhex.IntelHex() - tmp.loadbin(fobj=f"{src}", offset=off) + tmp.loadbin(fobj=str(src), offset=off) # Save if required if out is not None: - tmp.write_hex_file(f=f"{out}", byte_count=RECORD_BYTES) + tmp.write_hex_file(f=str(out), byte_count=RECORD_BYTES) return tmp @@ -62,11 +66,11 @@ def merge_bin(src: tp.List[tp.Tuple[TPPath, int]], out: TPPath = None) -> intelh # Merge all BIN files tmp = intelhex.IntelHex() for file, addr in src: - this = bin_to_hex(src=file, off=addr) + this = bin_to_hex(src=str(file), off=addr) tmp.merge(other=this, overlap="replace") # Save if required if out is not None: - tmp.write_hex_file(f=f"{out}", byte_count=RECORD_BYTES) + tmp.write_hex_file(f=str(out), byte_count=RECORD_BYTES) return tmp @@ -86,9 +90,17 @@ def merge_hex(src: tp.List[TPPath], out: TPPath = None) -> intelhex.IntelHex: # Merge all HEX files tmp = intelhex.IntelHex() for file in src: - this = intelhex.IntelHex(source=f"{file}") + this = intelhex.IntelHex(source=str(file)) tmp.merge(other=this, overlap="replace") # Save if required if out is not None: - tmp.write_hex_file(f=f"{out}", byte_count=RECORD_BYTES) + tmp.write_hex_file(f=str(out), byte_count=RECORD_BYTES) return tmp + + +# -->> Export <<----------------------- +__all__ = [ + "bin_to_hex", + "merge_bin", + "merge_hex" + ] diff --git a/embutils/utils/bytes.py b/embutils/utils/bytes.py index 03bc13b..b20f349 100644 --- a/embutils/utils/bytes.py +++ b/embutils/utils/bytes.py @@ -8,6 +8,10 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- + + +# -->> Tunables <<--------------------- # -->> Definitions <<------------------ @@ -60,3 +64,11 @@ def reverse_bytes(value: int, size: int = None) -> int: val = value & bitmask(bit=((8 * size) - 1), fill=True) aux = val.to_bytes(length=size, byteorder="big") return int.from_bytes(bytes=aux[::-1], byteorder="big") + + +# -->> Export <<----------------------- +__all__ = [ + "bitmask", + "reverse_bits", + "reverse_bytes", + ] diff --git a/embutils/utils/cobs.py b/embutils/utils/cobs.py index 970bd41..008fd3d 100644 --- a/embutils/utils/cobs.py +++ b/embutils/utils/cobs.py @@ -8,12 +8,16 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import typing as tp import attr +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -123,3 +127,9 @@ def decode(data: bytearray) -> bytearray: if block.zero: out.append(0x00) return out + + +# -->> Export <<----------------------- +__all__ = [ + "COBS", + ] diff --git a/embutils/utils/common.py b/embutils/utils/common.py index d4d6f96..8981f10 100644 --- a/embutils/utils/common.py +++ b/embutils/utils/common.py @@ -8,6 +8,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import pathlib as pl import typing as tp @@ -18,16 +19,16 @@ # -->> Definitions <<------------------ #: TyPe definition. Any value. -TPAny = tp.TypeVar("TPAny") +TPAny = tp.Any #: TyPe definition. Path sources. -TPByte = tp.TypeVar("TPByte", bytes, bytearray) +TPByte = tp.Union[bytes, bytearray] #: TyPe definition. Path sources. -TPText = tp.TypeVar("TPText", bytes, bytearray, str) +TPText = tp.Union[TPByte, str] #: TyPe definition. Path sources. -TPPath = tp.TypeVar("TPPath", bytes, bytearray, str, pl.Path) +TPPath = tp.Union[TPText, pl.Path] #: CallBack definition. Any -> Any CBAny2Any = tp.Callable[..., TPAny] @@ -40,3 +41,15 @@ # -->> API <<-------------------------- + + +# -->> Export <<----------------------- +__all__ = [ + "TPAny", + "TPByte", + "TPText", + "TPPath", + "CBAny2Any", + "CBAny2None", + "CBNone2None", + ] diff --git a/embutils/utils/crc.py b/embutils/utils/crc.py index a8269a7..a9c1dc9 100644 --- a/embutils/utils/crc.py +++ b/embutils/utils/crc.py @@ -8,12 +8,16 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import typing as tp from .bytes import bitmask, reverse_bits +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -268,3 +272,9 @@ def _lookup_normal(self) -> tp.List[int]: # Store the value on the table out.append(self._mask & byte) return out + + +# -->> Export <<----------------------- +__all__ = [ + "CRC", + ] diff --git a/embutils/utils/enum.py b/embutils/utils/enum.py index c119a0f..086ef45 100644 --- a/embutils/utils/enum.py +++ b/embutils/utils/enum.py @@ -8,10 +8,14 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import enum +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -61,3 +65,9 @@ def has_value(cls, value: int) -> bool: """ # pylint: disable=E1101 return value in getattr(cls, "_value2member_map_") + + +# -->> Export <<----------------------- +__all__ = [ + "IntEnum", + ] diff --git a/embutils/utils/events.py b/embutils/utils/events.py index 29faa48..7331fab 100644 --- a/embutils/utils/events.py +++ b/embutils/utils/events.py @@ -8,10 +8,14 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- from .common import CBAny2None +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -105,3 +109,9 @@ def emit(self, *args, **kwargs) -> None: """ for callback in self._callbacks: callback(*args, **kwargs) + + +# -->> Export <<----------------------- +__all__ = [ + "EventHook", + ] diff --git a/embutils/utils/logger.py b/embutils/utils/logger.py index 31e419f..ba252e8 100644 --- a/embutils/utils/logger.py +++ b/embutils/utils/logger.py @@ -8,6 +8,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import collections as coll import logging as log @@ -15,6 +16,9 @@ from .enum import IntEnum +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -89,3 +93,10 @@ def set_level(self, level: Level = Level.DEBUG) -> None: # -->> Instances <<-------------------- #: Embutils internal logger SDK_LOG = Logger(name="EMBUTILS") + + +# -->> Export <<----------------------- +__all__ = [ + "Logger", + "SDK_LOG", + ] diff --git a/embutils/utils/math.py b/embutils/utils/math.py index 73154df..541db0b 100644 --- a/embutils/utils/math.py +++ b/embutils/utils/math.py @@ -8,10 +8,14 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import math +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -49,3 +53,10 @@ def closest_pow(ref: float, base: float, force_next: bool = False) -> float: if (val < ref) or (force_next and (val == ref)): val = base ** (aux + 1) return val + + +# -->> Export <<----------------------- +__all__ = [ + "closest_multi", + "closest_pow", + ] diff --git a/embutils/utils/path.py b/embutils/utils/path.py index e05677d..d5850e9 100644 --- a/embutils/utils/path.py +++ b/embutils/utils/path.py @@ -8,6 +8,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import pathlib as pl import typing as tp @@ -15,6 +16,9 @@ from .common import TPAny, TPByte, TPPath +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -38,17 +42,14 @@ def __new__(cls, *args, **kwargs) -> 'Path': :raises TypeError: Input type cant be converted to a path. """ - tp_byte = getattr(TPByte, "__constraints__") - tp_path = getattr(TPPath, "__constraints__") - # Avoid not compatible types path = [] for item in args: # Check type - if not isinstance(item, tp_path): - raise TypeError(f"Argument should be a compatible type ({tp_path}). {type(item)} is not supported.") + if not isinstance(item, getattr(TPPath, "__args__")): + raise TypeError(f"Argument should be a compatible type ({TPPath}). {type(item)} is not supported.") # Convert - if isinstance(item, tp_byte): + if isinstance(item, getattr(TPByte, "__args__")): path.append(bytes(item).decode(errors="ignore")) else: path.append(str(item)) @@ -187,3 +188,10 @@ def validate_file( raise FileTypeError(f"Validation failed: {path} exists but is not a file.") return path + + +# -->> Export <<----------------------- +__all__ = [ + "FileTypeError", + "Path", + ] diff --git a/embutils/utils/serialized.py b/embutils/utils/serialized.py index 8724fc9..bd581af 100644 --- a/embutils/utils/serialized.py +++ b/embutils/utils/serialized.py @@ -8,11 +8,15 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import abc import typing as tp +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -90,3 +94,10 @@ def decode(self, data: bytearray) -> tp.Optional[AbstractSerialized]: :returns: Deserialized object if able, None otherwise. :rtype: Optional[AbstractSerialized] """ + + +# -->> Export <<----------------------- +__all__ = [ + "AbstractSerialized", + "AbstractSerializedCodec", + ] diff --git a/embutils/utils/service.py b/embutils/utils/service.py index 275b772..fcc70c7 100644 --- a/embutils/utils/service.py +++ b/embutils/utils/service.py @@ -8,6 +8,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import abc import threading as th @@ -17,6 +18,9 @@ from .threading import SDK_TP, SimpleThreadTask +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -179,3 +183,9 @@ def _on_end(self) -> None: """ Optional. Called upon service termination. """ + + +# -->> Export <<----------------------- +__all__ = [ + "AbstractService", + ] diff --git a/embutils/utils/stream.py b/embutils/utils/stream.py index 80dece2..2a60aa1 100644 --- a/embutils/utils/stream.py +++ b/embutils/utils/stream.py @@ -8,7 +8,10 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- +import contextlib as ctx +import io import queue import threading as th import typing as tp @@ -16,10 +19,24 @@ from .threading import SDK_TP, SimpleThreadTask +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ # -->> API <<-------------------------- +@ctx.contextmanager +def unclosable(file: io.IOBase): + """ + Makes file unclosable during the context execution. + """ + close = file.close + file.close = lambda: None + yield file + file.close = close + + class StreamRedirect: """ Stream redirect utility implementation. @@ -73,3 +90,10 @@ def _read(self) -> None: self._queue.put(line.decode()) self._queue.put(None) self._src.close() + + +# -->> Export <<----------------------- +__all__ = [ + "unclosable", + "StreamRedirect", + ] diff --git a/embutils/utils/subprocess.py b/embutils/utils/subprocess.py index 90974df..0c1e650 100644 --- a/embutils/utils/subprocess.py +++ b/embutils/utils/subprocess.py @@ -8,6 +8,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import subprocess as sp import sys @@ -17,6 +18,9 @@ from .stream import StreamRedirect +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -73,3 +77,9 @@ def execute(cmd: str, cwd: TPPath = None, log: TPPath = None, pipe: bool = True) # Return result return res + + +# -->> Export <<----------------------- +__all__ = [ + "execute", + ] diff --git a/embutils/utils/threading.py b/embutils/utils/threading.py index fdfd70c..67e3679 100644 --- a/embutils/utils/threading.py +++ b/embutils/utils/threading.py @@ -8,6 +8,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import abc import functools as fc @@ -19,6 +20,9 @@ from .logger import SDK_LOG +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -269,3 +273,15 @@ def execute(self) -> None: # -->> Instances <<-------------------- #: Embutils internal thread pool SDK_TP = ThreadPool(size=10, name="EMBUTILS_Thread_") + + +# -->> Export <<----------------------- +__all__ = [ + "sync", + "get_threads", + "AbstractThreadTask", + "ThreadWorker", + "ThreadPool", + "SimpleThreadTask", + "SDK_TP", + ] diff --git a/embutils/utils/time.py b/embutils/utils/time.py index 4ba777d..acaa42b 100644 --- a/embutils/utils/time.py +++ b/embutils/utils/time.py @@ -8,6 +8,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import functools as fc import time @@ -16,6 +17,9 @@ from .common import TPAny, CBAny2Any +# -->> Tunables <<--------------------- + + # -->> Definitions <<------------------ @@ -80,3 +84,10 @@ def elapsed(self, update: bool = False) -> float: if update: self._start = now return ret + + +# -->> Export <<----------------------- +__all__ = [ + "timer", + "Timer", + ] diff --git a/embutils/utils/venv.py b/embutils/utils/venv.py index 36a84cb..e4d3274 100644 --- a/embutils/utils/venv.py +++ b/embutils/utils/venv.py @@ -10,6 +10,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import os import site @@ -21,6 +22,7 @@ from .common import TPAny from .path import Path + # -->> Tunables <<--------------------- @@ -109,3 +111,12 @@ def deactivate() -> None: # Restore system prefix sys.prefix = old_venv.sys_prefix + + +# -->> Export <<----------------------- +__all__ = [ + "VENV", + "VENVS", + "activate", + "deactivate", + ] diff --git a/embutils/utils/version.py b/embutils/utils/version.py index c92096e..64de612 100644 --- a/embutils/utils/version.py +++ b/embutils/utils/version.py @@ -8,6 +8,7 @@ :contact: cwichel@gmail.com :license: The MIT License (MIT) """ +# ------------------------------------- import re @@ -15,6 +16,7 @@ from ..utils.common import TPAny, TPText + # -->> Tunables <<--------------------- @@ -58,8 +60,7 @@ def parse(self, text: TPAny) -> None: :raises ValueError: Input is not a string or contents don't match a version pattern. """ # Avoid not compatible types - constraints = getattr(TPText, "__constraints__") - if not isinstance(text, constraints): + if not isinstance(text, getattr(TPText, "__args__")): raise ValueError(f"Parameter with value '{text}' can't be converted to text.") # Ensure format and search @@ -94,3 +95,9 @@ def from_str(text: TPAny, hex_build: bool = False) -> 'Version': ver = Version(hex_build=hex_build) ver.parse(text=text) return ver + + +# -->> Export <<----------------------- +__all__ = [ + "Version", + ] diff --git a/pyproject.toml b/pyproject.toml index fa4767a..8eae8c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.poetry] -version = "0.7.4" +version = "0.7.5" name = "embutils" license = "MIT" readme = "README.md"