python-snippet/getattr.py

128 lines
4.1 KiB
Python

"""
Petit commentaire à destionation de BitBucket :)
Création dynamique de commandes pour enrober une interface en ligne de commande.
Par exemple pour RTC d'IBM:
Toutes les commandes commencent par 'scm -a n -u y'
Soit donc avec le format 'command [-option option_value]'
Les sous-commandes peuvent avoir des arguments avec ou sans étiquette:
'scm checkin --comment "mon commentaire" path/to/checkin/'
Les sous-commandes peuvent aussi avoir des sous-commandes:
'scm create workspace --description "bla" --stream "stream" "WS_Name"'
Mais cela ne va pas plus loin : 'scm sub1 sub2 options'
Toutes les commandes ne supportent pas le format json en sortie
Toutes les commandes ne requièrent pas le référentiel
Note:
Plutôt que de renvoyer un nouvel objet, on devrait faire circuler le parent
et le faire évoluer progressivement
"""
class CommandUncallable:
def __init__(self, root, callable, head={}, tail={}):
self.root = root
self.tail = tail
for k, v in head.items():
self.root = self.root + f" -{k} {v}"
self.callable = callable
def __call__(self, *args, **kwargs):
print(' arg: ', args)
for arg in args:
self.root = " ".join([self.root, arg])
print(' kwa: ', kwargs)
for key, value in kwargs.items():
opt = f"-{key} {value}"
self.root = " ".join([self.root, opt])
print(' tai: ', self.tail)
for key, value in self.tail.items():
opt = f"-{key} {value}"
self.root = " ".join([self.root, opt])
print(' obj: ', self)
print(' cmd: ', self.root)
def __getattr__(self, name):
"""Return a callable object of this same type so that you can just keep
chaining together calls and just adding that missing attribute to the
arguments"""
return self.callable(" ".join([self.root, name]), self.callable, tail=self.tail)
class Command(CommandUncallable):
def __call__(self, *args, **kwargs):
CommandUncallable.__call__(self, *args, **kwargs)
return self
class ScmCommand(CommandUncallable):
def __init__(self, root):
CommandUncallable.__init__(
self, root, CommandUncallable,
head={'a':'n','u':'y'},
tail={'r':'RTC_CLI', '-json':''}
)
class CommandSelf:
def __init__(self, root, head={}, tail={}):
self.root = root
self.command = root
for k, v in head.items():
self.command = self.command + f" -{k} {v}"
self.tail = tail
def toto(self):
pass
def __call__(self, *args, **kwargs):
for arg in args:
self.command = " ".join([self.command, arg])
for key, value in kwargs.items():
opt = f"-{key} {value}"
self.command = " ".join([self.command, opt])
for key, value in self.tail.items():
opt = f"-{key} {value}"
self.command = " ".join([self.command, opt])
print(' cmd: ', self.command)
def __getattr__(self, name):
print(f" getattr: {name}")
for method in vars(self):
print(method)
#if name in vars(getattr(self, method)):
# return getattr(getattr(self, method), name)
self.command = " ".join([self.command, name])
return self
def set_default(self, opt):
print(f" Setting defaults with {opt}")
if __name__ == "__main__":
command = Command(
'scm', Command,
head={'a':'n','u':'y'},
tail={'r':'RTC_CLI'}
)
print(' cmd: ', command, '\n')
print(f"First command:")
command.list.connections('localhost')
print(f"\nSecond command:")
command.create(style='inplace').workspace('WS_Name', s='S_Name')
print(f"\nWith ScmCommand class:")
scm = ScmCommand('scm')
print(' scm: ', scm)
scm.create.workspace('WS_Name', s='Stream_Name')
print(f"\nWith CommandSelf class:")
scm_self = CommandSelf('scm', {'a':'n','u':'y'}, {'r':'RTC_CLI'})
scm_self.create.workspace('WS_Name', s='Stream_Name')