Browse Source

Some changes of the code design of the variables properies and some comments are added.

packages
Иванов Денис 2 years ago
parent
commit
f879ea0ae2
  1. 13
      calculate/utils/files.py
  2. 177
      calculate/vars/datavars.py
  3. 80
      calculate/vars/vars_loader.py
  4. 496
      tests/vars/test_namespace.py
  5. 63
      tests/vars/variables/level/__init__.py
  6. 3
      tests/vars/variables/level/level2/__init__.py
  7. 1
      tests/vars/variables/main/__init__.py
  8. 14
      tests/vars/variables/os/__init__.py

13
calculate/utils/files.py

@ -10,15 +10,6 @@ import sys
import contextlib
def listDirectory(dn, fullpath=False):
if path.exists(dn):
if fullpath:
return [path.join(dn, x) for x in os.listdir(dn)]
else:
return os.listdir(dn)
return []
class FilesError(Exception):
pass
@ -397,11 +388,11 @@ def quite_unlink(file_path):
pass
def list_directory(directory_path, full_path=False, only_dir=False):
def list_directory(directory_path, fullpath=False, only_dir=False):
if not path.exists(directory_path):
return []
try:
if full_path:
if fullpath:
if only_dir:
return [node.path for node in os.scandir(directory_path)
if os.path.isdir(node.path)]

177
calculate/vars/datavars.py

@ -13,7 +13,7 @@ class BaseClass:
BASE_CLASS = "BaseClass"
@classmethod
def isImplementation(cls, check_class):
def is_implementation(cls, check_class):
'''Метод для проверки того, что класс является производным базового
класса, а не самим базовым. Используется в автозагрузке переменных из
модулей.'''
@ -42,16 +42,20 @@ class CyclicVariableError(VariableError):
class VariableProperty:
'''Базовый класс для объектов свойств.'''
def __init__(self, parent):
self.parent = parent
class StringVariable(VariableProperty):
'''Класс свойства, соответствующий переменным просто хранящим строки как
значения.'''
pass
class ListVariable(VariableProperty):
def setValue(self, value, force=False):
'''Класс свойства, соответствующий переменным хранящим списки значений.'''
def set_value(self, value, force=False):
if isinstance(value, (list, tuple)):
return value
elif isinstance(value, str):
@ -66,7 +70,7 @@ class ListVariable(VariableProperty):
class ReadonlyVariable(VariableProperty):
def setValue(self, value, force=False):
def set_value(self, value, force=False):
if not force:
raise VariableError(
_("Attempting to rewrite readonly variable {}").format(
@ -75,10 +79,10 @@ class ReadonlyVariable(VariableProperty):
class IntegerVariable(VariableProperty):
reMatch = re.compile(r"^-?\d+$")
re_match = re.compile(r"^-?\d+$")
def check(self, value):
if value and not self.reMatch.match(value):
if value and not self.re_match.match(value):
raise VariableError(
_("The value of variable '{varname}' must be integer").format(
varname=self.parent.name))
@ -103,12 +107,12 @@ class ChoiceVariable(VariableProperty):
def choice(self):
if self.parent.__class__.choice == Variable.choice and \
self.parent.__class__.choiceComment == Variable.choiceComment:
self.parent.__class__.choice_comment == Variable.choice_comment:
raise VariableError(_("Wrong choice variable {}").format(
self.parent.name))
return [x[0] for x in self.parent.choiceComment()]
return [x[0] for x in self.parent.choice_comment()]
def choiceComment(self):
def choice_comment(self):
return [(x, x) for x in self.parent.choice()]
@ -117,7 +121,7 @@ class DefaultValue(VariableProperty):
self.value = value
self.parent = None
def getValue(self, invalidate_subs=None):
def get_value(self, invalidate_subs=None):
if self.parent._value is None:
self.parent._unsubscribe_depends()
self.parent._value = self.value
@ -156,7 +160,8 @@ class Variable(BaseClass):
@property
def fullname(self):
return "{}.{}".format(self.vars.getFullname(), self.name)
'''Метод для получения полного имени переменной.'''
return "{}.{}".format(self.vars.get_fullname(), self.name)
def addProperty(self, prop):
prop.parent = self
@ -196,7 +201,7 @@ class Variable(BaseClass):
self.invalidate_subs = set()
self._emit_invalidate(slots)
def setParent(self, namespace):
def set_parent(self, namespace):
self.vars = namespace
@contextmanager
@ -207,8 +212,8 @@ class Variable(BaseClass):
finally:
self.calculating = False
def getValue(self, invalidate_sub=None):
for f in self.callProperties("getValue"):
def get_value(self, invalidate_sub=None):
for f in self.call_properties("get_value"):
f(invalidate_sub)
if self.calculating:
raise CyclicVariableError(self.name)
@ -227,21 +232,25 @@ class Variable(BaseClass):
return self.post_get(self._value)
def post_get(self, value):
for f in self.callProperties("post_get"):
for f in self.call_properties("post_get"):
ret = f(value)
if ret is not None:
return ret
return value
def callProperties(self, fname, *args):
for prop in self._properties:
f = getattr(prop, fname, None)
if f:
yield f
def setValue(self, value, force=False):
for f in self.callProperties("setValue"):
value = f(value, force)
def call_properties(self, method_name, *args):
'''Метод для вызова указанного метода у всех объектов, которыми владеет
переменная.'''
for _property in self._properties:
method = getattr(_property, method_name, None)
if method:
yield method
def set_value(self, value, force=False):
'''Метод для установки некоторого заданного значения всем объектам,
принадлежащим переменной.'''
for setter in self.call_properties("set_value"):
value = setter(value, force)
value = self.set(value)
self.check(value)
self.invalidate()
@ -249,26 +258,28 @@ class Variable(BaseClass):
self._unsubscribe_depends()
def check(self, value):
'''Метод для проверки значения устанавливаемого значения.'''
for f in self.callProperties("check"):
f(value)
'''Метод для проверки корректности устанавливаемого значения путем
вызова проверочных методов всех объектов, которыми владеет переменная.
'''
for checker in self.call_properties("check"):
checker(value)
def get(self):
'''Метод для заполнения переменной.'''
return self.value
def getCommentValue(self, invalidate_sub=None):
def get_comment_value(self, invalidate_sub=None):
'''Этот метод вызывается внутри методов get.'''
val = self.getComment()
val = self.get_comment()
if invalidate_sub is not None:
self.update_subscribe(invalidate_sub)
return val
def getComment(self):
'''Комментарий к значению.'''
for f in self.callProperties("getComment"):
def get_comment(self):
'''Метод для установки .'''
for f in self.call_properties("get_comment"):
return f()
return self.getValue()
return self.get_value()
def set(self, value):
'''Метод для модификации переменной.'''
@ -276,12 +287,12 @@ class Variable(BaseClass):
def choice(self):
'''Метод возвращет список доступных значений для переменной.'''
for f in self.callProperties("choice"):
for f in self.call_properties("choice"):
return f()
return []
def choiceComment(self):
for f in self.callProperties("choiceComment"):
def choice_comment(self):
for f in self.call_properties("choice_comment"):
return f()
return []
@ -291,6 +302,7 @@ class NamespaceError(Exception):
class Namespace(BaseClass):
'''Класс пространства имен.'''
BASE_CLASS = "Namespace"
def __init__(self, name="", parent=None):
@ -299,11 +311,13 @@ class Namespace(BaseClass):
self.childs = {}
self.parent = parent or self
self.root = self
self._nextns = 0
self._next_namespace = 0
def getFullname(self):
def get_fullname(self):
'''Метод для получения полного имени пространства имен, включающего в
себя имена всех родительских пространств имен.'''
if self.parent is not self and self.parent.parent is not self.parent:
return "{}.{}".format(self.parent.getFullname(), self._name)
return "{}.{}".format(self.parent.get_fullname(), self._name)
else:
return self._name
@ -315,22 +329,24 @@ class Namespace(BaseClass):
else:
raise VariableNotFoundError(
_("Variable or namespace {varname} not found").format(
varname="{}.{}".format(self.getFullname(),
name)))
varname="{}.{}".format(self.get_fullname(),
name)))
def clearChilds(self):
def clear_childs(self):
'''Метод для глубокой очистки пространства имен от всех дочерних
пространств имен.'''
for child in self.childs.values():
child.clearChilds()
child.clear_childs()
self.childs = {}
def __getitem__(self, name):
return getattr(self, str(name))
def __setitem__(self, name, value):
return getattr(self, str(name)).setValue(value)
return getattr(self, str(name)).set_value(value)
def __iter__(self):
'''Сортировка: вначале числовые ключи потом прочие.'''
# Сортировка: вначале числовые ключи потом прочие.
def sortkey(x):
k, v = x
if k.isdigit():
@ -343,39 +359,46 @@ class Namespace(BaseClass):
def __contains__(self, name):
return name in self.childs or name in self.variables
def addStringVariable(self, varname, value):
def add_string_variable(self, varname: str, value: str):
'''Метод для добавления переменной с помощью строк.'''
var = Variable(varname)
var.value = value
var.setParent(self)
var.set_parent(self)
self.variables[varname] = var
def addVariable(self, variable):
def add_variable(self, variable: Variable):
'''Метод для добавления переменной.'''
self.variables[variable.name] = variable
variable.setParent(self)
variable.set_parent(self)
def _getNextNamespaceName(self):
name = str(self._nextns)
def _get_next_namespace_name(self):
'''Метод для получения имени следующего по счету пространства имен.'''
name = str(self._next_namespace)
while name in self.childs:
self._nextns += 1
name = str(self._nextns)
self._next_namespace += 1
name = str(self._next_namespace)
return name
def addNamespace(self, namespace=None, name=None):
def add_namespace(self, namespace=None, name=None):
'''Метод для добавления пространств имен.'''
if name is None:
if namespace is None:
name = self._getNextNamespaceName()
name = self._get_next_namespace_name()
else:
name = namespace._name
if namespace is None:
namespace = Namespace(name)
self.childs[name] = namespace
namespace.parent = self
namespace.root = self.root
return namespace
class HashVariable(Namespace):
"""Классс переменных представляющих собой словарь."""
'''Класс переменных, представляющих собой словарь.'''
BASE_CLASS = "HashVariable"
class HashValue(Variable):
@ -386,10 +409,10 @@ class HashVariable(Namespace):
self.parent = None
self.master_variable = master_variable
def getValue(self, invalidate_sub=None):
def get_value(self, invalidate_sub=None):
return self.master_variable.getHashValue(self.name, invalidate_sub)
def setValue(self, value, force=False):
def set_value(self, value, force=False):
return self.master_variable.setHashValue(self.name, value, force)
def invalidate(self):
@ -399,19 +422,19 @@ class HashVariable(Namespace):
BASE_CLASS = "Data"
def getHashValue(self, name, invalidate_sub=None):
return self.getValue(invalidate_sub)[name]
return self.get_value(invalidate_sub)[name]
def setHashValue(self, name, value, force):
if name in self.readonly_vars and not force:
raise VariableError(
_("Attempting to rewrite readonly variable {}").
format(name))
data = self.getValue().copy()
data = self.get_value().copy()
data[name] = value
self.setValue(data, force)
self.set_value(data, force)
def getValue(self, invalidate_sub=None):
return self.master_variable.getValue(invalidate_sub)
def get_value(self, invalidate_sub=None):
return self.master_variable.get_value(invalidate_sub)
hash_vars = []
readonly_vars = []
@ -425,13 +448,13 @@ class HashVariable(Namespace):
if not self.hash_vars:
raise VariableError(
_("Missed '{attrname}' attribute for hash variable {varname}").
format(attrname="hash_vars", varname=self.getFullname()))
format(attrname="hash_vars", varname=self.get_fullname()))
self.master_variable = self.Data(name)
self.master_variable.setParent(parent)
self.master_variable.set_parent(parent)
self.master_variable.readonly_vars = self.readonly_vars
for varname in self.hash_vars:
var = self.HashValue(varname, self.master_variable)
self.addVariable(var)
self.add_variable(var)
def invalidate(self):
self.master_variable.invalidate()
@ -465,7 +488,7 @@ class TableVariable(Namespace):
BASE_CLASS = "Data"
def getTableValue(self, name, index, invalidate_sub=None):
data = self.getValue(invalidate_sub)
data = self.get_value(invalidate_sub)
return data[index][name]
def setTableValue(self, name, index, value, force):
@ -473,15 +496,15 @@ class TableVariable(Namespace):
raise VariableError(
_("Attempting to rewrite readonly variable {}").format(
name))
data = [x.copy() for x in self.getValue()]
data = [x.copy() for x in self.get_value()]
rowdata = data[index]
rowdata[name] = value
self.setValue(data, force)
self.set_value(data, force)
@property
def childs(self):
if self._childs is None:
value = self.master_variable.getValue()
value = self.master_variable.get_value()
self._childs = {}
for i, row in enumerate(value):
hashvar = self.TableHashVariable(self.master_variable.name,
@ -494,11 +517,11 @@ class TableVariable(Namespace):
def childs(self, value):
self._childs = value
def getValue(self, invalidate_sub=None):
return self.master_variable.getValue(invalidate_sub)
def get_value(self, invalidate_sub=None):
return self.master_variable.get_value(invalidate_sub)
def setValue(self, value, force=False):
self.master_variable.setValue(value, force)
def set_value(self, value, force=False):
self.master_variable.set_value(value, force)
def invalidate(self):
self.master_variable.invalidate()
@ -510,8 +533,8 @@ class TableVariable(Namespace):
self._childs = None
self.master_variable.update_subscribe(self._drop_childs)
def clearChilds(self):
super().clearChilds()
def clear_childs(self):
super().clear_childs()
self._drop_childs()
def __init__(self, name, parent=None):
@ -522,8 +545,8 @@ class TableVariable(Namespace):
raise VariableError(
_("Missed '{attrname}' attribute for table variable {varname}").
format(attrname="hash_vars",
varname=self.getFullname()))
varname=self.get_fullname()))
self.master_variable = self.Data(name)
self.master_variable.setParent(parent)
self.master_variable.set_parent(parent)
self.master_variable.readonly_vars = self.readonly_vars
self.master_variable.update_subscribe(self._drop_childs)

80
calculate/vars/vars_loader.py

@ -9,7 +9,7 @@ from calculate.vars.datavars import Variable, Namespace, HashVariable,\
TableVariable, IniCreated, DefaultValue
from calculate.utils.gentoo import ProfileWalker
from calculate.utils.fs import readFile
from calculate.utils.files import listDirectory
from calculate.utils.files import list_directory
class NamespaceIniFiller(CalculateIniParser):
@ -28,7 +28,7 @@ class NamespaceIniFiller(CalculateIniParser):
self.curns = self.ns
for section in sections:
if section not in self.curns.childs:
self.curns.addNamespace(Namespace(section))
self.curns.add_namespace(Namespace(section))
self.curns = self.curns[section]
def clear_section(self, sections):
@ -37,16 +37,16 @@ class NamespaceIniFiller(CalculateIniParser):
if section not in curns.childs:
return
curns = curns[section]
curns.clearChilds()
curns.clear_childs()
def change_value(self, key, value):
self.curns[key].setValue(value)
self.curns[key].set_value(value)
def define_variable(self, key, value):
self.curns.addStringVariable(key, value)
self.curns.add_string_variable(key, value)
def append_value(self, key, value):
l = self.curns[key].getValue().split(",")
l = self.curns[key].get_value().split(",")
vlist = value.split(",")
for v in vlist:
if v not in l:
@ -54,7 +54,7 @@ class NamespaceIniFiller(CalculateIniParser):
self.change_value(key, ",".join(l))
def remove_value(self, key, value):
l = self.curns[key].getValue().split(",")
l = self.curns[key].get_value().split(",")
vlist = value.split(",")
for v in vlist:
if v in l:
@ -94,7 +94,7 @@ class NamespaceIniFillerStrict(NamespaceIniFiller):
self.canCreate = False
for newns in self.availableSection:
if newns not in ns:
ns.addNamespace(Namespace(newns))
ns.add_namespace(Namespace(newns))
super().fill(ns, data)
def start_section(self, sections):
@ -103,34 +103,34 @@ class NamespaceIniFillerStrict(NamespaceIniFiller):
for section in sections:
if section not in self.curns.childs:
if isinstance(self.curns, TableVariable) or self.canCreate:
self.curns.addNamespace(Namespace(section))
self.curns.add_namespace(Namespace(section))
else:
self.curns = None
self.curns = self.curns[section]
#def clear_section(self, sections):
# curns = self.ns
# self.canCreate = sections[0] in self.availableSection
# for section in sections:
# if section not in curns.childs:
# return
# curns = curns[section]
# curns.clearChilds()
# def clear_section(self, sections):
# curns = self.ns
# self.canCreate = sections[0] in self.availableSection
# for section in sections:
# if section not in curns.childs:
# return
# curns = curns[section]
# curns.clear_childs()
def define_variable(self, key, value):
if not self.canCreate:
pass
var = Variable(key)
var.addProperty(IniCreated(value))
self.curns.addVariable(var)
self.curns.add_variable(var)
def change_value(self, key, value):
var = self.curns[key]
var.setValue(value)
var.set_value(value)
if isinstance(var, HashVariable.HashValue):
var = var.master_variable
value = var.getValue()
value = var.get_value()
prop = var.findProperty(DefaultValue)
if prop:
@ -141,40 +141,34 @@ class NamespaceIniFillerStrict(NamespaceIniFiller):
class VariableLoader:
"""
Объект используемый для загрузки переменных из python модуля
"""
reUpper = re.compile("(.)([A-Z])")
'''Класс, используемый для загрузки переменных из python модуля.'''
re_upper = re.compile("(.)([A-Z])")
def _get_varlike_attrs(self, obj):
"""
Получить список аттрибутов похожих на переменные
"""
'''Метод для получения списка аттрибутов похожих на переменные.'''
for attrname in (x for x in dir(obj) if x[:1].isupper()):
yield self.reUpper.sub(r"\1_\2", attrname).lower(), \
yield self.re_upper.sub(r"\1_\2", attrname).lower(), \
getattr(obj, attrname)
def fill(self, ns, dirpath, package):
"""
Загрузить в namespace переменные из указанных модулей
"""
for fullfn in listDirectory(dirpath, fullpath=True):
'''Загрузить в namespace переменные из указанных модулей.'''
for fullfn in list_directory(dirpath, fullpath=True):
dn, fn = os.path.split(fullfn)
if os.path.isdir(fullfn):
newns = ns.addNamespace(Namespace(fn))
self.fill(newns, fullfn, "%s.%s"%(package,fn))
newns = ns.add_namespace(Namespace(fn))
self.fill(newns, fullfn, "{}.{}".format(package, fn))
elif fn.endswith(".py"):
module = self._load_module_source(package, fn, fullfn)
for varname, cls in self._get_varlike_attrs(module):
if Variable.isImplementation(cls):
ns.addVariable(cls(varname))
elif HashVariable.isImplementation(cls) or \
TableVariable.isImplementation(cls) or \
Namespace.isImplementation(cls):
_newns = ns.addNamespace(cls(varname,ns))
if Variable.is_implementation(cls):
ns.add_variable(cls(varname))
elif HashVariable.is_implementation(cls) or \
TableVariable.is_implementation(cls) or \
Namespace.is_implementation(cls):
_newns = ns.add_namespace(cls(varname, ns))
for _varname, _cls in self._get_varlike_attrs(cls):
if Variable.isImplementation(_cls):
_newns.addVariable(_cls(_varname))
if Variable.is_implementation(_cls):
_newns.add_variable(_cls(_varname))
@classmethod
def default(cls):
@ -207,7 +201,7 @@ class ProfileFiller:
basename = "calculate.ini"
def get_repository_map(self, ns):
return {
x.name.getValue(): x.path.getValue()
x.name.get_value(): x.path.get_value()
for x in ns.os.gentoo.repositories
}

496
tests/vars/test_namespace.py

@ -19,20 +19,20 @@ class TestNamespace:
def test_create_variable(self):
ns = Namespace()
ns.addStringVariable("test", "12345")
assert ns.test.getValue() == "12345"
ns.addStringVariable("zxcv", "23456")
assert ns.zxcv.getValue() == "23456"
ns.add_string_variable("test", "12345")
assert ns.test.get_value() == "12345"
ns.add_string_variable("zxcv", "23456")
assert ns.zxcv.get_value() == "23456"
def test_create_ns_with_vars(self):
ns = Namespace()
ns.addNamespace(Namespace("os"))
ns.os.addStringVariable("test", "123")
ns.os.addNamespace(Namespace("linux"))
ns.os.linux.addStringVariable("shortname", "CLD")
assert ns.os.test.getValue() == "123"
assert ns.os["test"].getValue() == "123"
assert ns.os.linux.shortname.getValue() == "CLD"
ns.add_namespace(Namespace("os"))
ns.os.add_string_variable("test", "123")
ns.os.add_namespace(Namespace("linux"))
ns.os.linux.add_string_variable("shortname", "CLD")
assert ns.os.test.get_value() == "123"
assert ns.os["test"].get_value() == "123"
assert ns.os.linux.shortname.get_value() == "CLD"
assert ns.os.root == ns
def test_fill_namespace_simple(self):
@ -47,9 +47,9 @@ class TestNamespace:
fullname = Calculate Linux Desktop
""")
assert ns.os.test.getValue() == "123"
assert ns.os.linux.shortname.getValue() == "CLD"
assert ns.os.linux.fullname.getValue() == "Calculate Linux Desktop"
assert ns.os.test.get_value() == "123"
assert ns.os.linux.shortname.get_value() == "CLD"
assert ns.os.linux.fullname.get_value() == "Calculate Linux Desktop"
assert ns.os.linux.root == ns
nsif.fill(ns, """
@ -57,8 +57,8 @@ class TestNamespace:
shortname = CLDX
""")
assert ns.os.linux.shortname.getValue() == "CLDX"
assert ns.os.linux.fullname.getValue() == "Calculate Linux Desktop"
assert ns.os.linux.shortname.get_value() == "CLDX"
assert ns.os.linux.fullname.get_value() == "Calculate Linux Desktop"
def test_fill_namespace_append_and_remove(self):
ns = Namespace()
@ -71,28 +71,28 @@ class TestNamespace:
test += 345
""")
assert ns.os.test.getValue() == "123,345"
assert ns.os.test.get_value() == "123,345"
nsif.fill(ns, """
[os]
test -= 123
""")
assert ns.os.test.getValue() == "345"
assert ns.os.test.get_value() == "345"
nsif.fill(ns, """
[os]
test += asdf,qwer,zxcv
""")
assert ns.os.test.getValue() == "345,asdf,qwer,zxcv"
assert ns.os.test.get_value() == "345,asdf,qwer,zxcv"
nsif.fill(ns, """
[os]
test -= asdf,zxcv
""")
assert ns.os.test.getValue() == "345,qwer"
assert ns.os.test.get_value() == "345,qwer"
def test_fill_namespace_clear_namespaces(self):
ns = Namespace()
@ -111,9 +111,9 @@ class TestNamespace:
mount = /var/calculate
""")
assert [x.dev.getValue() for x in ns.test] == ['/dev/sda1',
'/dev/sda2',
'/dev/sda5']
assert [x.dev.get_value() for x in ns.test] == ['/dev/sda1',
'/dev/sda2',
'/dev/sda5']
nsif.fill(ns, """
[test][0]
@ -125,9 +125,9 @@ class TestNamespace:
mount = /
""")
assert [x.dev.getValue() for x in ns.test] == ['/dev/sdb1',
'/dev/sdb2',
'/dev/sda5']
assert [x.dev.get_value() for x in ns.test] == ['/dev/sdb1',
'/dev/sdb2',
'/dev/sda5']
nsif.fill(ns, """
[test][]
@ -141,8 +141,8 @@ class TestNamespace:
mount = /
""")
assert [x.dev.getValue() for x in ns.test] == ['/dev/sdb1',
'/dev/sdb2']
assert [x.dev.get_value() for x in ns.test] == ['/dev/sdb1',
'/dev/sdb2']
def test_fill_namespace_strict_clear(self):
ns = Namespace()
@ -167,8 +167,8 @@ class TestNamespace:
zxcv = 2
""")
assert ns.custom.test.zxcv.getValue() == "1"
assert ns.custom.test2.zxcv.getValue() == "2"
assert ns.custom.test.zxcv.get_value() == "1"
assert ns.custom.test2.zxcv.get_value() == "2"
nsifs = NamespaceIniFillerStrict()
nsifs.fill(ns, """
@ -182,16 +182,16 @@ class TestNamespace:
def test_get_namespace_attrs(self):
ns = Namespace()
os = Namespace("os")
os.addStringVariable("test", "zxcv")
ns.addNamespace(os)
os.add_string_variable("test", "zxcv")
ns.add_namespace(os)
assert ns.os.test.getValue() == "zxcv"
assert ns.os["test"].getValue() == "zxcv"
assert ns.os.test.get_value() == "zxcv"
assert ns.os["test"].get_value() == "zxcv"
assert "test" in ns.os
ns.os.test.setValue("123")
assert ns.os.test.getValue() == "123"
ns.os["test"].setValue("234")
assert ns.os.test.getValue() == "234"
ns.os.test.set_value("123")
assert ns.os.test.get_value() == "123"
ns.os["test"].set_value("234")
assert ns.os.test.get_value() == "234"
def test_variable_get_value(self):
class TestVar(Variable):
@ -200,62 +200,62 @@ class TestNamespace:
var = TestVar("test")
assert var.getValue() == "A"
assert var.get_value() == "A"
def test_namespace_lookup(self):
ns = Namespace()
os = Namespace("os")
device = Namespace("device")
linux = Namespace("linux")
ns.addNamespace(os)
os.addNamespace(linux)
os.addNamespace(device)
device1 = device.addNamespace()
device1.addStringVariable("dev", "/dev/sda")
device2 = device.addNamespace()
device2.addStringVariable("dev", "/dev/sdb")
device3 = device.addNamespace()
device3.addStringVariable("dev", "/dev/sdc")
ns.addStringVariable("first", "first")
os.addStringVariable("second", "second")
linux.addStringVariable("third", "third")
assert ns.first.getValue() == "first"
assert ns.root.os.second.getValue() == "second"
assert ns.os.second.getValue() == "second"
assert os.root.os.second.getValue() == "second"
assert os.second.getValue() == "second"
assert linux.third.getValue() == "third"
assert linux.root.os.second.getValue() == "second"
ns.add_namespace(os)
os.add_namespace(linux)
os.add_namespace(device)
device1 = device.add_namespace()
device1.add_string_variable("dev", "/dev/sda")
device2 = device.add_namespace()
device2.add_string_variable("dev", "/dev/sdb")
device3 = device.add_namespace()
device3.add_string_variable("dev", "/dev/sdc")
ns.add_string_variable("first", "first")
os.add_string_variable("second", "second")
linux.add_string_variable("third", "third")
assert ns.first.get_value() == "first"
assert ns.root.os.second.get_value() == "second"
assert ns.os.second.get_value() == "second"
assert os.root.os.second.get_value() == "second"
assert os.second.get_value() == "second"
assert linux.third.get_value() == "third"
assert linux.root.os.second.get_value() == "second"
with pytest.raises(VariableNotFoundError):
os.third
assert ns.os.device[0].dev.getValue() == "/dev/sda"
assert ns.os.device["0"].dev.getValue() == "/dev/sda"
assert ns.os.device[1].dev.getValue() == "/dev/sdb"
assert ns.os.device[2].dev.getValue() == "/dev/sdc"
assert ns.os.device[0].dev.get_value() == "/dev/sda"
assert ns.os.device["0"].dev.get_value() == "/dev/sda"
assert ns.os.device[1].dev.get_value() == "/dev/sdb"
assert ns.os.device[2].dev.get_value() == "/dev/sdc"
assert ns.os.device.parent.second.getValue() == "second"
assert ns.os.device.parent.parent.os.second.getValue() == "second"
assert ns.os.device.parent.second.get_value() == "second"
assert ns.os.device.parent.parent.os.second.get_value() == "second"
assert ns.os.device.parent.parent.parent.os.second.\
getValue() == "second"
get_value() == "second"
def test_variable_get_value_by_variable(self):
class TestVar1(Variable):
def get(self):
return "%s,B" % self.vars.test2.getValue(self)
return "%s,B" % self.vars.test2.get_value(self)
class TestVar2(Variable):
def get(self):
return "A"
ns = Namespace()
ns.addVariable(TestVar1("test1"))
ns.addVariable(TestVar2("test2"))
ns.add_variable(TestVar1("test1"))
ns.add_variable(TestVar2("test2"))
assert ns.test1.getValue() == "A,B"
assert ns.test1.get_value() == "A,B"
def test_variable_get_value_by_changed_variable(self):
class TestVar1(Variable):
@ -263,59 +263,59 @@ class TestNamespace:
def get(self):
self.counter += 1
return "%s,B" % self.vars.test2.getValue(self)
return "%s,B" % self.vars.test2.get_value(self)
ns = Namespace()
test1 = TestVar1("test1")
ns.addVariable(test1)
ns.addStringVariable("test2", "A")
ns.add_variable(test1)
ns.add_string_variable("test2", "A")
assert ns.test1.getValue() == "A,B"
assert ns.test1.get_value() == "A,B"
assert test1.counter == 1
# test for get cached variable value
assert ns.test1.getValue() == "A,B"
assert ns.test1.get_value() == "A,B"
assert test1.counter == 1
# change value of test2 for recalculate test1
ns.test2.setValue("C")
assert ns.test1.getValue() == "C,B"
ns.test2.set_value("C")
assert ns.test1.get_value() == "C,B"
assert test1.counter == 2
# change value of test2 for recalculate test1
ns.test2.setValue("D")
assert ns.test1.getValue() == "D,B"
ns.test2.set_value("D")
assert ns.test1.get_value() == "D,B"
assert test1.counter == 3
def test_cyclic_variable(self):
class TestVar1(Variable):
def get(self):
return "%s,test1" % self.vars.test2.getValue(self)
return "%s,test1" % self.vars.test2.get_value(self)
class TestVar2(Variable):
def get(self):
return "%s,test2" % self.vars.test3.getValue(self)
return "%s,test2" % self.vars.test3.get_value(self)
class TestVar3(Variable):
def get(self):
return "%s,test3" % self.vars.test1.getValue(self)
return "%s,test3" % self.vars.test1.get_value(self)
test1 = TestVar1("test1")
test2 = TestVar2("test2")
test3 = TestVar3("test3")
ns = Namespace()
ns.addVariable(test1)
ns.addVariable(test2)
ns.addVariable(test3)
ns.add_variable(test1)
ns.add_variable(test2)
ns.add_variable(test3)
with pytest.raises(CyclicVariableError) as e:
ns.test1.getValue()
ns.test1.get_value()
assert e.value.queue[:-1] == ("test1", "test2", "test3")
with pytest.raises(VariableError) as e:
ns.test1.getValue()
ns.test1.get_value()
def test_drop_invalidate_after_set_value(self):
class TestVar1(Variable):
@ -323,7 +323,7 @@ class TestNamespace:
def get(self):
self.counter += 1
return "%s,test1" % self.vars.test2.getValue(self)
return "%s,test1" % self.vars.test2.get_value(self)
class TestVar2(Variable):
def get(self):
@ -332,24 +332,24 @@ class TestNamespace:
test1 = TestVar1("test1")
test2 = TestVar2("test2")
ns = Namespace()
ns.addVariable(test1)
ns.addVariable(test2)
ns.add_variable(test1)
ns.add_variable(test2)
assert test1.getValue() == "ZZZZ,test1"
assert test1.get_value() == "ZZZZ,test1"
test1.setValue("VVVV")
test1.set_value("VVVV")
assert test1.getValue() == "VVVV"
assert test1.get_value() == "VVVV"
assert test1.counter == 1
test2.setValue("XXXX")
test2.set_value("XXXX")
assert test1.getValue() == "VVVV"
assert test1.get_value() == "VVVV"
assert test1.counter == 1
test1.invalidate()
assert test1.getValue() == "XXXX,test1"
assert test1.get_value() == "XXXX,test1"
assert test1.counter == 2
def test_change_invalidator_variable(self):
@ -359,31 +359,31 @@ class TestNamespace:
def get(self):
self.counter += 1
if self.vars.ifvar.getValue(self):
return "%s,test1" % self.vars.vara.getValue(self)
if self.vars.ifvar.get_value(self):
return "%s,test1" % self.vars.vara.get_value(self)
else:
return "%s,test1" % self.vars.varb.getValue(self)
return "%s,test1" % self.vars.varb.get_value(self)
vartest = VarTest("vartest")
ns = Namespace()
ns.addVariable(vartest)
ns.addStringVariable("vara", "vara")
ns.addStringVariable("varb", "varb")
ns.addStringVariable("ifvar", "true")
ns.add_variable(vartest)
ns.add_string_variable("vara", "vara")
ns.add_string_variable("varb", "varb")
ns.add_string_variable("ifvar", "true")
assert vartest.getValue() == "vara,test1"
assert vartest.get_value() == "vara,test1"
assert vartest.counter == 1
ns.vara.setValue("varc")
assert vartest.getValue() == "varc,test1"
ns.vara.set_value("varc")
assert vartest.get_value() == "varc,test1"
assert vartest.counter == 2
ns.ifvar.setValue("")
assert vartest.getValue() == "varb,test1"
ns.ifvar.set_value("")
assert vartest.get_value() == "varb,test1"
assert vartest.counter == 3
ns.vara.setValue("vard")
assert vartest.getValue() == "varb,test1"
ns.vara.set_value("vard")
assert vartest.get_value() == "varb,test1"
assert vartest.counter == 3
def test_readonly_varaible(self):
@ -394,14 +394,14 @@ class TestNamespace:
return "test1"
test1 = TestVar1("test1")
assert test1.getValue() == "test1"
assert test1.get_value() == "test1"
with pytest.raises(VariableError):
test1.setValue("test2")
test1.set_value("test2")
assert test1.getValue() == "test1"
test1.setValue("test2", force=True)
assert test1.getValue() == "test2"
assert test1.get_value() == "test1"
test1.set_value("test2", force=True)
assert test1.get_value() == "test2"
def test_choice_variable(self):
class TestVar1(Variable):
@ -412,9 +412,9 @@ class TestNamespace:
test1 = TestVar1("test1")
with pytest.raises(VariableError):
test1.setValue("test3")
test1.setValue("test2")
assert test1.getValue() == "test2"
test1.set_value("test3")
test1.set_value("test2")
assert test1.get_value() == "test2"
def test_integer_variable(self):
class TestVar1(Variable):
@ -422,11 +422,11 @@ class TestNamespace:
test1 = TestVar1("test1")
with pytest.raises(VariableError):
test1.setValue("test3")
test1.setValue("33")
assert test1.getValue() == 33
test1.setValue("-33")
assert test1.getValue() == -33
test1.set_value("test3")
test1.set_value("33")
assert test1.get_value() == 33
test1.set_value("-33")
assert test1.get_value() == -33
def test_default_value_property(self):
class TestVar1(Variable):
@ -434,14 +434,14 @@ class TestNamespace:
return "123"
test1 = TestVar1("test1")
assert test1.getValue() == "123"
assert test1.get_value() == "123"
test1.setValue("987")
test1.set_value("987")
test1.addProperty(DefaultValue("567"))
assert test1.getValue() == "987"
assert test1.get_value() == "987"
test1.invalidate()
assert test1.getValue() == "567"
assert test1.get_value() == "567"
def test_get_comment(self):
class TestVar1(Variable):
@ -452,30 +452,30 @@ class TestNamespace:
def get(self):
return "234"
def getComment(self):
return "[%s]" % self.getValue()
def get_comment(self):
return "[%s]" % self.get_value()
class TestVar3(Variable):
def get(self):
return "ZXC %s" % self.vars.test2.getCommentValue(self)
return "ZXC %s" % self.vars.test2.get_comment_value(self)
ns = Namespace()
test1 = TestVar1("test1")
assert test1.getValue() == "123"
assert test1.getComment() == "123"
assert test1.get_value() == "123"
assert test1.get_comment() == "123"
test2 = TestVar2("test2")
assert test2.getValue() == "234"
assert test2.getComment() == "[234]"
assert test2.get_value() == "234"
assert test2.get_comment() == "[234]"
test3 = TestVar3("test3")
ns.addVariable(test1)
ns.addVariable(test2)
ns.addVariable(test3)
ns.add_variable(test1)
ns.add_variable(test2)
ns.add_variable(test3)
assert test3.getValue() == "ZXC [234]"
test2.setValue("567")
assert test3.getValue() == "ZXC [567]"
assert test3.get_value() == "ZXC [234]"
test2.set_value("567")
assert test3.get_value() == "ZXC [567]"
def test_wrong_choice_varaible(self):
class TestVar1(Variable):
@ -490,7 +490,7 @@ class TestNamespace:
class TestVar3(Variable):
properties = [ChoiceVariable]
def choiceComment(self):
def choice_comment(self):
return [("test1", "Test1"),
("test2", "Test2")]
@ -502,30 +502,30 @@ class TestNamespace:
test1.choice()
with pytest.raises(VariableError):
test1.choiceComment()
test1.choice_comment()
assert test2.choice() == ["test1", "test2"]
assert test2.choiceComment() == [("test1", "test1"),
("test2", "test2")]
assert test2.choice_comment() == [("test1", "test1"),
("test2", "test2")]
assert test3.choice() == ["test1", "test2"]
assert test3.choiceComment() == [("test1", "Test1"),
("test2", "Test2")]
assert test3.choice_comment() == [("test1", "Test1"),
("test2", "Test2")]
def test_loading_test_variable_module(self):
ns = Namespace()
vl = VariableLoader()
vl.fill(ns, "tests/vars/variables", "testvars")
assert ns.level.simple.getValue() == "simple value"
assert ns.level.uselocalsimple.getValue() == "Using simple value"
assert ns.level.usefullsimple.getValue() == "Using simple value"
assert ns.level.simple.get_value() == "simple value"
assert ns.level.uselocalsimple.get_value() == "Using simple value"
assert ns.level.usefullsimple.get_value() == "Using simple value"
with pytest.raises(VariableError):
ns.level.badchoice.choice()
with pytest.raises(VariableError):
ns.level.badchoice.choiceComment()
ns.level.badchoice.choice_comment()
assert ns.level.simple_choice.choice() == ["/dev/sda1",
"/dev/sda2",
@ -533,23 +533,23 @@ class TestNamespace:
assert ns.level.comment_choice.choice() == ["/dev/sda1",
"/dev/sda2",
"/dev/sda3"]
assert ns.level.comment_choice.choiceComment() == [
assert ns.level.comment_choice.choice_comment() == [
("/dev/sda1", "SWAP"),
("/dev/sda2", "ROOT"),
("/dev/sda3", "DATA")]
ns.level.disks.setValue(["/dev/sda2", "/dev/sda1"])
ns.level.disks.set_value(["/dev/sda2", "/dev/sda1"])
assert ns.level.disks.getValue() == ["/dev/sda2", "/dev/sda1"]
assert ns.level.disks.get_value() == ["/dev/sda2", "/dev/sda1"]
assert ns.level.comment_choice.choice() == ["/dev/sda2", "/dev/sda1"]
assert ns.level.comment_choice.choiceComment() == [
assert ns.level.comment_choice.choice_comment() == [
("/dev/sda2", "ROOT"),
("/dev/sda1", "SWAP")]
assert ns.level is not ns.level.level2.root
assert ns is ns.level.level2.root
assert ns.level.level2.vargetter.getValue() == "/ test"
assert ns.level.level2.vargetter.get_value() == "/ test"
def test_hash_variable(self):
# hash variable
@ -557,43 +557,43 @@ class TestNamespace:
vl = VariableLoader()
vl.fill(ns, "tests/vars/variables", "testvars")
assert ns.level.linux.getFullname() == "level.linux"
assert ns.level.linux.get_fullname() == "level.linux"
assert ns.level.linux.ver.fullname == "level.linux.ver"
assert ns.level.linux.ver.getValue() == "1.0"
assert ns.level.linux.shortname.getValue() == "CLD"
assert ns.level.linux.ver.get_value() == "1.0"
assert ns.level.linux.shortname.get_value() == "CLD"
# проверка обновления значения hash переменной при обновлении
# значения у зависимой перемнной
ns.level.version.setValue("2.0")
assert ns.level.linux.ver.getValue() == "2.0"
ns.level.version.set_value("2.0")
assert ns.level.linux.ver.get_value() == "2.0"
# проверка установки значения hash переменной
ns.level.linux.ver.setValue("3.0")
assert ns.level.linux.ver.getValue() == "3.0"
ns.level.linux.ver.set_value("3.0")
assert ns.level.linux.ver.get_value() == "3.0"
# после установки хотя бы одного значения в hash переменной
# обновление остальных прекращаются до инвалидации (так как
# значения рассматриваются комплексно)
ns.level.myshortname.setValue("CLDG")
assert ns.level.linux.shortname.getValue() == "CLD"
ns.level.myshortname.set_value("CLDG")
assert ns.level.linux.shortname.get_value() == "CLD"
# проверка попытки изменить readonly переменную
with pytest.raises(VariableError):
ns.level.linux.shortname.setValue("CLDX")
ns.level.linux.shortname.set_value("CLDX")
# проверка сбора значения hash перемнной
ns.level.linux.invalidate()
assert ns.level.linux.ver.getValue() == "2.0"
assert ns.level.linux.shortname.getValue() == "CLDG"
assert ns.level.linux.ver.get_value() == "2.0"
assert ns.level.linux.shortname.get_value() == "CLDG"
assert ns.level.linux.test.getValue() == "my test - 2.0"
assert ns.level.linux.test.get_value() == "my test - 2.0"
# проверка обновления значения переменной, используеющей одно