Added the new VariablesLoader for new version of the variables API.

packages
Иванов Денис 4 years ago
parent a5b710666d
commit 6bfd4c046b

@ -506,7 +506,7 @@ class ParametersProcessor:
return {'uid': uid, 'gid': gid}
else:
raise IncorrectParameter("'chown' value '{0}' is not correct".
format(chown, self.template_path))
format(chown))
def get_uid_from_passwd(self, user_name: str):
"""Функция для получения uid из chroot passwd файла."""
@ -572,7 +572,8 @@ class ParametersProcessor:
'format')
for module_name in os.listdir(format_directory_path):
if (os.path.isdir(os.path.join('format', module_name)) or
if (os.path.isdir(os.path.join(format_directory_path,
module_name)) or
module_name == '__init__.py'):
continue

@ -93,7 +93,7 @@ class FloatType(VariableType):
@classmethod
def process_value(self, value, variable) -> float:
if isinstance(value, float):
return True
return value
else:
try:
return float(value)
@ -620,11 +620,15 @@ class NamespaceNode:
namespace.parent = self
def clear(self):
'''Метод для очистки пространства имен. Очищает и пространства имен
и переменные. Предназначен только для использования в calculate.ini.'''
for namespace in self.namespaces:
namespace.clear()
self.variables.clear()
self.namespaces.clear()
def get_fullname(self) -> str:
'''Метод для получения полного имени пространства имен.'''
if self.parent is not None:
return '{}.{}'.format(self.parent.get_fullname(), self.name)
else:
@ -772,6 +776,11 @@ class NamespaceAPI:
self._variables_fabric.current_namespace = self._datavars
self._dependence_fabric.current_namespace = self._datavars
def set_current_namespace(self, namespace: NamespaceNode):
self.current_namespace = namespace
self._variables_fabric.current_namespace = namespace
self._dependence_fabric.current_namespace = namespace
@contextmanager
def __call__(self, namespace_name):
'''Метод для создания пространств имен с помощью with.'''

@ -8,7 +8,8 @@ from calculate.vars.datavars import Variable, Namespace, HashVariable,\
TableVariable, IniCreated, DefaultValue
from calculate.vars.alt_datavars import NamespaceNode, VariableNode,\
ListType, IntegerType,\
FloatType, IniType, TableType
FloatType, IniType, TableType,\
Namespace
from calculate.utils.gentoo import ProfileWalker
from calculate.utils.fs import readFile
from calculate.utils.files import list_directory
@ -97,7 +98,6 @@ class CalculateIniParser:
section, defkeys = tokens
print('section type: {}'.format(section.getName()))
if section.getName() == 'namespace':
section_list = section.asList()
if section_list[-1] == []:
@ -198,6 +198,8 @@ class NamespaceIniFiller:
def clear_section(self, sections: list) -> None:
'''Метод для очистки пространства имен.'''
if self.restricted:
self.modify_only = sections[0] not in self.available_sections
current_namespace = self.namespace
for section in sections:
@ -210,16 +212,18 @@ class NamespaceIniFiller:
table_to_clear = table_variable.get_value()
table_to_clear.clear()
table_variable.source = table_to_clear
return
else:
return
current_namespace.clear()
if not self.modify_only:
current_namespace.clear()
def start_table(self, sections: str, row) -> None:
'''Метод для создания и модификации таблиц.'''
if self.restricted:
self.modify_only = sections[0] not in self.available_sections
self.current_namespace = self.namespace
row_number = int(sections.pop())
row_index = int(sections.pop())
table_name = sections.pop()
for section in sections:
if section not in self.current_namespace.namespaces:
@ -239,8 +243,8 @@ class NamespaceIniFiller:
else:
table_variable = self.current_namespace.variables[table_name]
table = table_variable.get_value()
if len(table) < row_number:
table.change_row(row, row_number)
if row_index < len(table):
table.change_row(row, row_index)
else:
table.add_row(row)
table_variable.source = table
@ -341,64 +345,29 @@ class NamespaceIniFiller:
self.error(lineno, "Syntax error: {}".format(line))
class NamespaceIniFillerStrict(NamespaceIniFiller):
"""Объект используемый для наполнения Namespace объекта переменными
из calculate.ini файла, с возможность определять только
"""
availableSection = ["custom"]
def fill(self, namespace, data):
self.canCreate = False
for newns in self.availableSection:
if newns not in namespace:
namespace.add_namespace(Namespace(newns))
super().fill(namespace, data)
def start_section(self, sections):
self.current_namespace = self.namespace
self.canCreate = sections[0] in self.availableSection
for section in sections:
if section not in self.current_namespace.childs:
if isinstance(self.current_namespace,
TableVariable) or self.canCreate:
self.current_namespace.add_namespace(Namespace(section))
else:
self.current_namespace = None
self.current_namespace = self.current_namespace[section]
# def clear_section(self, sections):
# current_namespace = self.namespace
# self.canCreate = sections[0] in self.availableSection
# for section in sections:
# if section not in current_namespace.childs:
# return
# current_namespace = current_namespace[section]
# current_namespace.clear_childs()
def define_variable(self, key, value):
if not self.canCreate:
pass
var = Variable(key)
var.add_property(IniCreated(value))
self.current_namespace.add_variable(var)
def change_value(self, key, value):
var = self.current_namespace[key]
var.set_value(value)
if isinstance(var, HashVariable.HashValue):
var = var.master_variable
value = var.get_value()
prop = var.find_property(DefaultValue)
if prop:
prop.value = value
else:
var.add_property(DefaultValue(value))
var.invalidate()
class VariableLoader:
def load_variables(self, directory_path) -> NamespaceNode:
root = Namespace.datavars
package = '.'.join(directory_path.split('/'))
self._fill(root, directory_path, package)
return root
def _fill(self, current_namespace: NamespaceNode,
directory_path: str, package: str) -> None:
for file_name in list_directory(directory_path):
file_path = os.path.join(directory_path, file_name)
if os.path.isdir(file_path):
namespace = NamespaceNode(file_name)
current_namespace.add_namespace(namespace)
self._fill(namespace, file_path, "{}.{}".format(package,
file_name))
elif file_name.endswith('.py'):
file_name = file_name[:-3]
Namespace.set_current_namespace(current_namespace)
importlib.import_module('{}.{}'.format(package, file_name))
class OldVariableLoader:
'''Класс, используемый для загрузки переменных из python модуля.'''
re_upper = re.compile("(.)([A-Z])")

@ -3,8 +3,9 @@ from calculate.vars.alt_datavars import NamespaceNode, VariableNode,\
Namespace, Variable, Dependence,\
CyclicVariableError, HashType,\
StringType, IntegerType, VariableType,\
VariableError, TableType
from calculate.vars.alt_vars_loader import NamespaceIniFiller
VariableError, TableType, BooleanType,\
VariableTypeError, FloatType, ListType
from calculate.vars.alt_vars_loader import NamespaceIniFiller, VariableLoader
from calculate.utils.files import stderr_devnull
@ -55,7 +56,7 @@ class TestNamespace:
assert namespace_1['var_1'].get_fullname() == 'namespace_1.var_1'
assert namespace_1['var_2'].get_fullname() == 'namespace_1.var_2'
def test_compare_two_dependencies_equal(self):
def test_if_two_dependencies_is_created_with_the_same_variables_and_their_depend_functions_are_equivalent_lambdas__the_dependencies_are_equal(self):
namespace_1 = NamespaceNode('namespace_1')
variable_1 = VariableNode('var_1', namespace_1, source=2,
variable_type=IntegerType)
@ -71,7 +72,7 @@ class TestNamespace:
'greater' if var_1.value > var_2.value else 'less')
assert dependence_1 == dependence_2
def test_compare_two_dependencies_equal_but_one_is_function_and_other_is_lambda(self):
def test_if_two_dependencies_is_created_with_the_same_variables_and_their_depend_functions_are_equivalent_lambda_and_function__the_dependencies_are_equal(self):
namespace_1 = NamespaceNode('namespace_1')
variable_1 = VariableNode('var_1', namespace_1, source=2,
variable_type=IntegerType)
@ -90,7 +91,7 @@ class TestNamespace:
dependence_2 = Dependence(variable_1, variable_2, depend=comparator)
assert dependence_1 == dependence_2
def test_compare_two_dependencies_not_equal(self):
def test_if_two_dependencies_is_created_with_the_same_variables_and_their_depend_functions_are_not_equivalent_lambdas__the_dependencies_are_equal(self):
namespace_1 = NamespaceNode('namespace_1')
variable_1 = VariableNode('var_1', namespace_1, source=2,
variable_type=IntegerType)
@ -106,7 +107,7 @@ class TestNamespace:
'greater' if var_1.value > var_2.value else 'less')
assert dependence_1 != dependence_2
def test_compare_two_dependencies_not_equal_but_one_is_function_and_other_is_lambda(self):
def test_if_two_dependencies_is_created_with_the_same_variables_and_their_depend_functions_are_not_equivalent_lambda_and_function__the_dependencies_are_equal(self):
namespace_1 = NamespaceNode('namespace_1')
variable_1 = VariableNode('var_1', namespace_1, source=2,
variable_type=IntegerType)
@ -163,6 +164,18 @@ class TestNamespace:
assert datavars.namespace_1.var_3 == 4
assert datavars.namespace_1.namespace_1_1.var_1 == 'val_1'
def test_if_variables_creation_api_is_used_for_creating_of_a_namespace_and_of_a_number_of_variables_and_there_is_attempt_to_get_value_of_an_unexistent_variable_from_a_created_namespace__the_namespace_raises_the_VariableError_exception(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', source='val_1')
Variable('var_2', source=2, type=IntegerType)
Variable('var_3', source=4, type=IntegerType)
with pytest.raises(VariableError):
datavars.namespace_1.var_4
def test_if_dependence_interface_object_is_used_for_finding_an_existing_variable_from_an_other_namespace_using_absolute_variable_name__the_find_variable_method_returns_the_desired_variable(self):
Namespace.reset()
datavars = Namespace.datavars
@ -357,6 +370,107 @@ class TestNamespace:
with pytest.raises(VariableError):
Variable('var_1', source='value_2', type=StringType)
def test_if_variables_with_string_type_is_created_with_correct_source__the_variable_api_creates_this_variables_and_the_variables_contains_strings(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', source='value', type=StringType)
Variable('var_2', source=2, type=StringType)
Variable('var_3', source=False, type=StringType)
assert datavars.namespace_1.var_1 == 'value'
assert datavars.namespace_1.var_2 == '2'
assert datavars.namespace_1.var_3 == 'False'
def test_if_variables_with_integer_type_is_created_with_correct_source__the_variable_api_creates_this_variables_and_the_variables_contains_integers(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', source=1, type=IntegerType)
Variable('var_2', source='2', type=IntegerType)
Variable('var_3', source=3.1, type=IntegerType)
Variable('var_4', source='-4', type=IntegerType)
assert datavars.namespace_1.var_1 == 1
assert datavars.namespace_1.var_2 == 2
assert datavars.namespace_1.var_3 == 3
assert datavars.namespace_1.var_4 == -4
def test_if_variable_with_integer_type_is_created_with_source_that_can_not_be_converted_to_an_integer_value__the_variable_api_raises_the_VariableTypeError_exception(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', source='a', type=IntegerType)
with pytest.raises(VariableTypeError):
datavars.namespace_1.var_1
def test_if_variables_with_float_type_is_created_with_correct_source__the_variable_api_creates_this_variables_and_the_variables_contains_floats(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', source=1.1, type=FloatType)
Variable('var_2', source='2.2', type=FloatType)
Variable('var_3', source=3, type=FloatType)
Variable('var_4', source='-4.4', type=FloatType)
assert datavars.namespace_1.var_1 == 1.1
assert datavars.namespace_1.var_2 == 2.2
assert datavars.namespace_1.var_3 == 3.0
assert datavars.namespace_1.var_4 == -4.4
def test_if_variable_with_float_type_is_created_with_source_that_can_not_be_converted_to_an_float_value__the_variable_api_raises_the_VariableTypeError_exception(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', source='a', type=FloatType)
with pytest.raises(VariableTypeError):
datavars.namespace_1.var_1
def test_if_variables_with_bool_type_is_created_with_correct_source__the_variable_api_creates_this_variables_and_the_variables_contains_bool(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', source=True, type=BooleanType)
Variable('var_2', source='false', type=BooleanType)
Variable('var_3', source='True', type=BooleanType)
Variable('var_4', source='0', type=BooleanType)
assert datavars.namespace_1.var_1 is True
assert datavars.namespace_1.var_2 is False
assert datavars.namespace_1.var_3 is True
assert datavars.namespace_1.var_4 is True
def test_if_variables_with_list_type_is_created_with_correct_source__the_variable_api_creates_this_variables_and_the_variables_contains_lists(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', source=['a', 'b', 'c'], type=ListType)
Variable('var_2', source='a, b, c', type=ListType)
Variable('var_3', source={'a', 'b', 'c'}, type=ListType)
assert datavars.namespace_1.var_1 == ['a', 'b', 'c']
assert datavars.namespace_1.var_2 == ['a', 'b', 'c']
assert datavars.namespace_1.var_3 == list({'a', 'b', 'c'})
def test_if_variable_with_list_type_is_created_with_source_that_can_not_be_converted_to_an_list_value__the_variable_api_raises_the_VariableTypeError_exception(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', source=1, type=ListType)
with pytest.raises(VariableTypeError):
datavars.namespace_1.var_1
def test_if_hash_variable_is_created_with_Hash_type_and_with_a_dictionary_in_its_source__the_variable_is_created_with_Hash_value_in_it(self):
Namespace.reset()
datavars = Namespace.datavars
@ -567,7 +681,7 @@ test -= asdf,zxcv
namespace_filler.fill(datavars, third_ini_text)
assert datavars.os.test == "123,qwer"
def test_custom_and_not_custom_creation(self):
def test_if_calculate_ini_file_is_used_for_creation_variables_in_the_custom_and_some_other_namespaces_and_for_changing_of_a_variable_from_not_custom_namespaces__the_NamespaceIniFiller_object_just_creates_variables_in_the_custom_namespace_and_modifies_variables_from_other_namespaces(self):
Namespace.reset()
datavars = Namespace.datavars
namespace_filler = NamespaceIniFiller()
@ -594,7 +708,38 @@ var_1 = value_1
assert datavars.custom.test_1.var_1 == "value_1"
assert datavars.custom.test_2.var_1 == "value_1"
def test_table_from_ini(self):
def test_if_calculate_ini_file_is_used_for_clearing_namespaces_in_the_custom_and_some_other_namespaces__the_NamespaceIniFiller_object_clears_namespaces_only_from_the_custom_namespace(self):
Namespace.reset()
datavars = Namespace.datavars
namespace_filler = NamespaceIniFiller()
with Namespace('os'):
Variable('var_1', type=StringType, source='value_1')
Variable('var_2', type=StringType, source='value_2')
first_ini_text = """
[custom][test]
var_1 = value_1
var_2 = value_2
"""
namespace_filler.fill(datavars, first_ini_text)
assert datavars.custom.test.var_1 == 'value_1'
assert datavars.custom.test.var_2 == 'value_2'
second_ini_text = """
[custom][test][]
[os][]
"""
namespace_filler.fill(datavars, second_ini_text)
assert datavars.os.var_1 == 'value_1'
assert datavars.os.var_2 == 'value_2'
assert 'var_1' not in datavars.custom.test.variables
assert 'var_2' not in datavars.custom.test.variables
def test_if_calculate_ini_file_is_used_for_creation_of_the_table_variable_in_the_custom_namespace__the_NamespaceIniFiller_object_creates_table_in_the_custom_namespace(self):
Namespace.reset()
datavars = Namespace.datavars
namespace_filler = NamespaceIniFiller()
@ -623,14 +768,145 @@ value = value_2
{'name': 'name_1', 'value': 'value_1'},
{'name': 'name_2', 'value': 'value_2'}]
second_ini_text = """
def test_if_calculate_ini_file_is_used_for_creation_of_the_table_variable_in_not_custom_namespaces__the_NamespaceIniFiller_object_does_not_create_anything(self):
Namespace.reset()
datavars = Namespace.datavars
namespace_filler = NamespaceIniFiller()
with Namespace('os'):
Variable('var_1', type=StringType, source='value_1')
Variable('var_2', type=StringType, source='value_2')
first_ini_text = """
[os][test][0]
name = name_0
value = value_0
[os][test][1]
name = name_1
value = value_1
[os][test][2]
name = name_2
value = value_2
"""
namespace_filler.fill(datavars, first_ini_text)
assert 'test' not in datavars.os
def test_if_two_tables_are_created_using_calculate_ini_file_and_variables_api_and_then_calculate_ini_file_is_used_for_clearing_and_add_rows_in_the_both_tables__the_NamespaceIniFiller_object_clears_tables_and_adds_rows(self):
Namespace.reset()
datavars = Namespace.datavars
namespace_filler = NamespaceIniFiller()
with Namespace('os'):
Variable('test', type=TableType, source=[{'name': 'name_1',
'value': 'value_1'},
{'name': 'name_2',
'value': 'value_2'},
{'name': 'name_3',
'value': 'value_3'}])
first_ini_text = """
# Создаем таблицу.
[custom][test][0]
name = name_0
value = value_0
[custom][test][1]
name = name_1
value = value_1
# Очищаем таблицу.
[custom][test][]
# Добавляем в таблицу строку.
[custom][test][0]
name = name_0
value = value_0
# Очищаем таблицу созданную интерфейсом.
[os][test][]
# Добавляем в эту таблицу строку.
[os][test][0]
name = strange_name
value = weird_value
"""
namespace_filler.fill(datavars, second_ini_text)
namespace_filler.fill(datavars, first_ini_text)
assert datavars.custom.test.get_table() ==\
[{'name': 'name_0', 'value': 'value_0'}]
assert datavars.os.test.get_table() ==\
[{'name': 'strange_name', 'value': 'weird_value'}]
def test_if_calculate_ini_file_is_used_for_modifying_of_the_table_from_calculate_ini_file__the_NamespaceIniFiller_object_modifies_the_table(self):
Namespace.reset()
datavars = Namespace.datavars
namespace_filler = NamespaceIniFiller()
first_ini_text = """
# Создаем таблицу.
[custom][test][0]
name = name_0
value = value_0
[custom][test][1]
name = name_1
value = value_1
"""
namespace_filler.fill(datavars, first_ini_text)
assert datavars.custom.test.get_table() ==\
[{'name': 'name_0', 'value': 'value_0'},
{'name': 'name_1', 'value': 'value_1'}]
second_ini_text = """
[custom][test][1]
name = other_name
value = another_value
"""
namespace_filler.fill(datavars, second_ini_text)
assert datavars.custom.test.get_table() ==\
[{'name': 'name_0', 'value': 'value_0'},
{'name': 'other_name', 'value': 'another_value'}]
def test_if_calculate_ini_file_is_used_for_modifying_of_the_table_created_using_variables_api__the_NamespaceIniFiller_object_modifies_the_table(self):
Namespace.reset()
datavars = Namespace.datavars
namespace_filler = NamespaceIniFiller()
with Namespace('namespace_1'):
Variable('test', type=TableType, source=[{'name': 'name_1',
'value': 'value_1'},
{'name': 'name_2',
'value': 'value_2'},
{'name': 'name_3',
'value': 'value_3'}])
first_ini_text = """
[namespace_1][test][0]
name = new_name
value = other_value
[namespace_1][test][1]
name = common_name
value = another_value
"""
namespace_filler.fill(datavars, first_ini_text)
assert datavars.namespace_1.test.get_table() ==\
[{'name': 'new_name', 'value': 'other_value'},
{'name': 'common_name', 'value': 'another_value'},
{'name': 'name_3', 'value': 'value_3'}]
def test_loader(self):
Namespace.reset()
loader = VariableLoader()
datavars = loader.load_variables('tests/vars/testfiles/variables_0')
assert datavars.os.ns.var_1 == 'value_1'
assert datavars.os.ns.var_2 == 2
assert datavars.main.strange_variable == 'weird_value'
assert datavars.main.plain_variable is True

@ -0,0 +1,6 @@
from calculate.vars.alt_datavars import Namespace, Variable, StringType,\
IntegerType, BooleanType
Variable('strange_variable', source='weird_value', type=StringType)
Variable('plain_variable', source=True, type=BooleanType)

@ -0,0 +1,6 @@
from calculate.vars.alt_datavars import Namespace, Variable, StringType,\
IntegerType
with Namespace('ns'):
Variable('var_1', source='value_1', type=StringType)
Variable('var_2', source=2, type=IntegerType)
Loading…
Cancel
Save