From 43885ec13554552f62f0bb39657e2f25fdf4191d Mon Sep 17 00:00:00 2001 From: Alex Tavarez Date: Thu, 8 Jan 2026 09:45:23 -0500 Subject: [PATCH] feature: implemented some numeric and sequence methods for 'SSHKey' class and added a function --- sshkey_man.py | 82 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 17 deletions(-) diff --git a/sshkey_man.py b/sshkey_man.py index 8614867..e7af3a8 100644 --- a/sshkey_man.py +++ b/sshkey_man.py @@ -25,10 +25,12 @@ class SSHKeyType(Enum): # @TODO create unit tests for below class class SSHKey: - def __init__(self, *path: ExecutedPath): + def __init__(self, *path: ExecutedPath | str): if len(path) > 2 or len(path) < 1: raise ValueError + path = tuple(map(lambda s: Path(s) if isinstance(s, str) else s, path)) + self.__idx: int = 0 self.__prev: Self | None = None self.__next: Self | None = None @@ -93,17 +95,11 @@ class SSHKey: def __neqcontent__(self, other: Self) -> bool: return self.__value.read_text() != other._SSHKey__value.read_text() - def __add__(self, other: Self | ExecutedPath | str): - raise NotImplementedError - - def __radd__(self, other: Self | ExecutedPath | str): - raise NotImplementedError - - def __sub__(self, other: Self | ExecutedPath | str): - raise NotImplementedError - - def __rsub__(self, other: Self | ExecutedPath | str): - raise NotImplementedError + def __len__(self): + if isinstance(self.__value, tuple): + return len(self.__value) + else: + return 1 def update(self, *path: ExecutedPath | str) -> Self | Never: if len(path) > 2 or len(path) < 1: @@ -118,6 +114,45 @@ class SSHKey: return self + def __add__(self, other: Self | ExecutedPath | str): + if isinstance(self.__value, tuple): + raise ValueError + + if isinstance(other, Self): + if isinstance(other.__SSHKey__value, tuple): + raise ValueError + + result = self.update(self.__value, other._SSHKey__value) + elif isinstance(other, (str, ExecutedPath)): + result = self.update(self.__value, other) + else: + raise TypeError + + return result + + def __radd__(self, other: Self | ExecutedPath | str): + if isinstance(self.__value, tuple): + raise ValueError + + if isinstance(other, Self): + if isinstance(other.__SSHKey__value, tuple): + raise ValueError + + result = self.update(other._SSHKey__value, self.__value) + elif isinstance(other, (str, ExecutedPath)): + result = self.update(other, self.__value) + else: + raise TypeError + + return result + + # @TODO write following 2 subtraction algorithms using 'set' data type conversion and methods + def __sub__(self, other: Self | ExecutedPath | str): + raise NotImplementedError + + def __rsub__(self, other: Self | ExecutedPath | str): + raise NotImplementedError + def replace(self, old: ExecutedPath | str | tuple[ExecutedPath | str] | list[ExecutedPath | str], new: ExecutedPath | str | tuple[ExecutedPath | str] | list[ExecutedPath | str]) -> Self | Never: if isinstance(old, str): old = Path(old) @@ -183,10 +218,18 @@ class SSHKey: return result @property - def status(self) -> Never: - # @TODO this method should return string or Enum value after analyzing whether this key is public or private + def status(self) -> str | Never: + # @TODO analyze 'read' return value of this class's instance to check whether it is a private key, + # unless '__value' of this class's instance is a tuple, in which case it is a dual key raise NotImplementedError + def reverse(self) -> Never: + if isinstance(self.__value, tuple): + v1, v2 = *self.__value + result = self.update(v2, v1) + else: + result = self + return result def prev(arg): if isinstance(arg, SSHKey): @@ -200,6 +243,12 @@ def stream_equal(s1, s2) -> bool | Never: else: raise TypeError +def stream_unequal(s1, s2) -> bool | Never: + if isinstance(s1, SSHKey) and isinstance(s2, SSHKey): + return s1._SSHKey__neqcontent__(s2) + else: + raise TypeError + # @TODO create unit tests for below class class SSHKeyCollection(Sequence): @@ -385,20 +434,19 @@ class SSHKeyCollection(Sequence): return self.__last - # @TODO make sure to implement below method def __contains__(self) -> bool | Never: raise NotImplementedError def __missing__(self) -> Never: raise NotImplementedError - # @TODO make sure to implement below method def __iter__(self) -> Self | Never: raise NotImplementedError def count(self, query: RegEx | str) -> int | Never: raise NotImplementedError + # @TODO make sure to implement below method def pull(self, query: RegEx | str = "*") -> Never: raise NotImplementedError @@ -409,7 +457,7 @@ class SSHKeyCollection(Sequence): raise NotImplementedError - +# @TODO maybe move to separate module for classes for handling users and groups class UserSSH: def __init__(self, username: str = "root", paths: Apps | None = None, keys: dict = dict(), password: str = "password123", fate: RootFate = RootFate.disposal.name): self.username = username