Added main Datavars module and its functionality is almost implemented.

packages
Иванов Денис 4 years ago
parent 632b88b79f
commit 2e5946ed6e

@ -159,6 +159,7 @@ class ParametersProcessor:
def check_template_parameter(self, parameter_name, parameter_value,
template_type, lineno):
'''Метод, проверяющий указанный параметр.'''
self.lineno = lineno
self.template_type = template_type
@ -191,6 +192,7 @@ class ParametersProcessor:
{parameter_name: checked_value})
def check_postparse_parameters(self):
'''Метод, запускающий проверку параметров после их разбора.'''
for parameter, parameter_checker in\
self.postparse_checkers_list.items():
if parameter not in self._parameters_container:
@ -200,6 +202,7 @@ class ParametersProcessor:
parameter_checker(parameter_value)
def check_template_parameters(self, parameters, template_type, lineno):
'''Метод, запускающий проверку указанных параметров.'''
self.template_type = template_type
self.lineno = lineno
@ -230,6 +233,8 @@ class ParametersProcessor:
self._parameters_container.set_parameter(
parameter_name=checked_value)
# Методы для проверки параметров во время разбора шаблона.
def check_package_parameter(self, parameter_value):
try:
atom_object = self.package_atom_parser.parse_package_parameter(
@ -774,6 +779,8 @@ class CalculateExtension(Extension):
'''Метод для разбора тега save, сохраняющего значение указанной
переменной datavars.'''
lineno = next(self.stream).lineno
# Целового файла больше не будет.
target_file = nodes.Const('', lineno=lineno)
if self.stream.skip_if('dot'):

@ -1,30 +1,31 @@
import os
import re
import calculate.utils.fs as fs
from calculate.utils.files import read_file_lines
class ProfileWalker:
"""
Объект обходящий все директории профиля через parent файлы
"""
'''Объект обходящий все директории профиля через parent файлы.'''
def __init__(self, filename, repositories):
self.repositories = repositories
self.filename = filename
self.reReppath = re.compile("^({0})+:".format(
self.re_reppath = re.compile("^({0})+:".format(
"|".join(self.repositories.keys())))
def interpolate(self, path):
def subfunc(m):
return "{0}/profiles/".format(self.repositories.get(m.group(1)))
return self.reReppath.sub(subfunc, path)
return self.re_reppath.sub(subfunc, path)
def find(self, directory):
parent = os.path.join(directory, "parent")
for line in (x for x in fs.readFileLines(parent) if x.strip()):
parentdir = os.path.normpath(
'''Метод для поиска по профилю всех файлов с именем, указанным в
self.filename.'''
parent_file_path = os.path.join(directory, "parent")
for line in (parent_line for parent_line in
read_file_lines(parent_file_path) if parent_line.strip()):
parent_directory = os.path.normpath(
os.path.join(directory, self.interpolate(line)))
if fs.exists(parentdir):
yield from self.find(parentdir)
if os.path.exists(parent_directory):
yield from self.find(parent_directory)
findfile = os.path.normpath(os.path.join(directory, self.filename))
if fs.exists(findfile):
if os.path.exists(findfile):
yield findfile

@ -1,6 +1,6 @@
import ast
import dis
from typing import List, Union, Any
from typing import List, Any
from contextlib import contextmanager
from inspect import signature, getsource
from types import FunctionType, LambdaType
@ -36,9 +36,14 @@ class VariableType:
name = 'undefined'
@classmethod
def process_value(self, value, variable):
def process_value(cls, value, variable):
return value
@classmethod
def readonly(cls, variable_object) -> None:
variable_object.variable_type = cls
variable_object.readonly = True
class IniType(VariableType):
'''Класс, соответствующий типу переменных созданных в calculate.ini файлах.
@ -46,7 +51,7 @@ class IniType(VariableType):
name = 'ini'
@classmethod
def process_value(self, value, variable):
def process_value(cls, value, variable):
return value
@ -55,7 +60,7 @@ class StringType(VariableType):
name = 'string'
@classmethod
def process_value(self, value, variable) -> str:
def process_value(cls, value, variable) -> str:
if isinstance(value, str):
return value
else:
@ -73,7 +78,7 @@ class IntegerType(VariableType):
name = 'integer'
@classmethod
def process_value(self, value, variable) -> int:
def process_value(cls, value, variable) -> int:
if isinstance(value, int):
return value
else:
@ -91,7 +96,7 @@ class FloatType(VariableType):
name = 'float'
@classmethod
def process_value(self, value, variable) -> float:
def process_value(cls, value, variable) -> float:
if isinstance(value, float):
return value
else:
@ -111,13 +116,13 @@ class BooleanType(VariableType):
false_values = {'False', 'false'}
@classmethod
def process_value(self, value, variable) -> bool:
def process_value(cls, value, variable) -> bool:
if isinstance(value, bool):
return value
elif isinstance(value, str):
if value in self.true_values:
if value in cls.true_values:
return True
if value in self.false_values:
if value in cls.false_values:
return False
try:
return bool(value)
@ -132,7 +137,7 @@ class ListType(VariableType):
name = 'list'
@classmethod
def process_value(self, value, variable) -> list:
def process_value(cls, value, variable) -> list:
# TODO нормально все сделать.
if isinstance(value, list):
return value
@ -181,6 +186,7 @@ class Hash:
'''Класс реализующий контейнер для хранения хэша в переменной
соответствующего типа.'''
def __init__(self, values: dict, master_variable, parent=None):
self.fixed = master_variable.fixed
self._values = dict()
for key, value in values.items():
self._values.update({key: HashValue(key, value, master_variable,
@ -189,11 +195,27 @@ class Hash:
self.row_index = None
def get_hash(self) -> dict:
'''Метод для получения словаря из значений хэша.'''
dict_value = {}
for key in self._values.keys():
dict_value.update({key: self._values[key].get_value()})
return dict_value
def update_hash(self, values: dict) -> None:
'''Метод для обновления значения хэша.'''
print('UPDATE HASH')
for key, value in values.items():
if key in self._values:
self._values[key].value = value
elif self.fixed:
raise VariableError("key '{}' is unavailable for fixed"
" hash, available keys: '{}'".
format(key, ', '.join(self._fields)))
else:
self._values[key] = HashValue(key, value, self.master_variable,
self)
return self
def __getattr__(self, key: str):
'''Метод возвращает ноду пространства имен или значение переменной.'''
if key in self._values:
@ -226,12 +248,21 @@ class HashType(VariableType):
name = 'hash'
@classmethod
def process_value(self, value, variable) -> Hash:
if not isinstance(value, dict):
def process_value(cls, values, variable) -> Hash:
if not isinstance(values, dict):
raise VariableTypeError("can not set value with type '{_type}' to"
" hash variable: value must be 'dict' type"
.format(_type=type(value)))
return Hash(value, variable)
.format(_type=type(values)))
if variable.value is not None:
updated_hash = variable.value.update_hash(values)
else:
updated_hash = Hash(values, variable)
return updated_hash
@classmethod
def fixed(cls, variable_object) -> None:
variable_object.variable_type = cls
variable_object.fixed = True
class Table:
@ -487,8 +518,8 @@ class VariableNode:
# динамическом связывании.
self._subscriptions = set()
# Если значение переменной None -- значит она обнулена.
self.value = None
self._invalidated = True
# Источник значения переменной, может быть значением, а может быть
# зависимостью.
@ -501,6 +532,10 @@ class VariableNode:
self.set_by_user = False
self._readonly = False
# Флаг имеющий значение только для переменных типа HashType.
# Предназначен для включения проверки соответствия полей хэша при
# установке значения.
self._fixed = False
def update_value(self) -> None:
'''Метод для обновления значения переменной с помощью указанного
@ -537,6 +572,25 @@ class VariableNode:
value = self._source
self.value = self.variable_type.process_value(value, self)
self._invalidated = False
def set_variable_type(self, variable_type, readonly=None, fixed=None):
'''Метод для установки типа переменной.'''
if readonly is not None and isinstance(readonly, bool):
self._readonly = readonly
elif fixed is not None and isinstance(fixed, bool):
self._fixed = fixed
if self.variable_type is VariableType:
if isinstance(variable_type, type):
if issubclass(variable_type, VariableType):
self.variable_type = variable_type
else:
raise VariableError('variable type object must be'
' VariableType or its class method,'
' not {}'.format(type(variable_type)))
elif callable(variable_type):
variable_type(self)
def set(self, value):
self._invalidate()
@ -550,7 +604,8 @@ class VariableNode:
@source.setter
def source(self, source) -> None:
if self._readonly:
raise VariableError("can not change the variable '{}': read only")
raise VariableError("can not change the variable '{}': read only".
format(self.get_fullname()))
# Если источники не совпадают или текущее значение переменной было
# установлено пользователем, то инвалидируем переменную и меняем
@ -572,12 +627,22 @@ class VariableNode:
# self.update_value()
self._readonly = value
@property
def fixed(self) -> bool:
return self._fixed
@fixed.setter
def fixed(self, value) -> bool:
self._fixed = value
def _invalidate(self) -> None:
'''Метод для инвалидации данной переменной и всех зависящих от нее
переменных.'''
# print('{} is invalidated'.format(self.get_fullname()))
if self.value is not None and not self.set_by_user:
if not self._invalidated and not self.set_by_user:
if self.variable_type is not HashType:
self.value = None
self._invalidated = True
for subscriber in self.subscribers:
subscriber._invalidate()
@ -593,7 +658,7 @@ class VariableNode:
def get_value(self) -> Any:
'''Метод для получения значения переменной.'''
if self.value is None and not self.set_by_user:
if self._invalidated and not self.set_by_user:
self.update_value()
return self.value
@ -641,8 +706,8 @@ class NamespaceNode:
def clear(self):
'''Метод для очистки пространства имен. Очищает и пространства имен
и переменные. Предназначен только для использования в calculate.ini.'''
for namespace in self.namespaces:
namespace.clear()
for namespace_name in self.namespaces.keys():
self.namespaces[namespace_name].clear()
self.variables.clear()
self.namespaces.clear()
@ -653,7 +718,7 @@ class NamespaceNode:
else:
return self.name
def __getattr__(self, name: str) -> None:
def __getattr__(self, name: str):
'''Метод возвращает ноду пространства имен или значение переменной.'''
if name in self.namespaces:
return self.namespaces[name]
@ -747,14 +812,13 @@ class VariableAPI:
self.errors = []
def __call__(self, name: str, source=None, type=VariableType,
readonly=False, force=False):
readonly=False, fixed=False, force=False):
'''Метод для создания переменных внутри with Namespace('name').'''
if name not in self.current_namespace.variables:
print('CREATE VARIABLE: {}'.format('{}.{}'.format(
self.current_namespace.get_fullname(),
name)))
variable = VariableNode(name, self.current_namespace,
variable_type=type)
variable = VariableNode(name, self.current_namespace)
else:
print('MODIFY VARIABLE: {}'.format(name))
variable = self.current_namespace[name]
@ -770,7 +834,12 @@ class VariableAPI:
else:
variable.source = source
variable.readonly = readonly
if readonly:
variable.set_variable_type(type, readonly=True)
elif fixed:
variable.set_variable_type(type, fixed=True)
else:
variable.set_variable_type(type)
return variable
@ -798,15 +867,18 @@ class NamespaceAPI:
можно получить доступ к переменным.'''
return self._datavars
def set_root(self, datavars_root: NamespaceNode):
def set_datavars(self, datavars):
'''Метод для установки корневого пространства имен, которое пока что
будет использоваться для предоставления доступа к переменным.'''
self._datavars = datavars_root
self._datavars = datavars
self._variables_fabric.current_namespace = self._datavars
def reset(self):
'''Метод для сброса корневого пространства имен.'''
if isinstance(self._datavars, NamespaceNode):
self._datavars = NamespaceNode('<root>')
else:
self._datavars.reset()
self.current_namespace = self._datavars
self._variables_fabric.current_namespace = self._datavars

@ -4,11 +4,12 @@ import os
import importlib
import importlib.util
import site
from calculate.vars.datavars import Variable, HashVariable, TableVariable
from calculate.vars.alt_datavars import NamespaceNode, VariableNode,\
from calculate.variables.old_vars.datavars import Variable, HashVariable,\
TableVariable
from calculate.variables.datavars import NamespaceNode, VariableNode,\
ListType, IntegerType,\
FloatType, IniType, TableType,\
Namespace
Namespace, VariableError
from calculate.utils.gentoo import ProfileWalker
from calculate.utils.files import list_directory, read_file, FilesError
from pyparsing import Literal, Word, ZeroOrMore, Group, Optional, restOfLine,\
@ -182,10 +183,17 @@ class NamespaceIniFiller:
def start_section(self, sections: str) -> None:
'''Метод для получения доступа и создания пространств имен.'''
print('SECTIONS: {}'.format(sections))
if self.restricted:
self.modify_only = sections[0] not in self.available_sections
self.current_namespace = self.namespace
for section in sections:
print('START SECTION: {}'.format(section))
if isinstance(self.current_namespace, Datavars):
if section not in self.current_namespace:
raise VariableError("variables package '{}' is not found".
format(section))
elif isinstance(self.current_namespace, NamespaceNode):
if section not in self.current_namespace.namespaces:
if not self.modify_only:
self.current_namespace.add_namespace(
@ -202,8 +210,12 @@ class NamespaceIniFiller:
current_namespace = self.namespace
for section in sections:
if (isinstance(current_namespace, Datavars) and
section in current_namespace):
current_namespace = current_namespace[section]
elif isinstance(current_namespace, NamespaceNode):
if section in current_namespace.namespaces:
current_namespace = current_namespace.namespaces[section]
current_namespace = current_namespace[section]
elif (section in current_namespace.variables and
current_namespace.variables[section].variable_type
is TableType):
@ -249,6 +261,8 @@ class NamespaceIniFiller:
table_variable.source = table
def define_key(self, key: str, value: str, optype) -> None:
print('DEFINE KEY: {} -> {} TO {}'.format(key, value,
self.current_namespace))
if self.current_namespace is None:
return
@ -345,17 +359,35 @@ class NamespaceIniFiller:
class VariableLoader:
basename = "calculate.ini"
def load_variables(self, directory_path) -> NamespaceNode:
root = Namespace.datavars
package = '.'.join(directory_path.split('/'))
self._fill_from_package(root, directory_path, package)
return root
'''Класс загрузчика переменных из python-файлов и из ini-файлов.'''
ini_basename = "calculate.ini"
def __init__(self, datavars, variables_path, repository_map=None):
self.datavars = datavars
self.ini_filler = NamespaceIniFiller()
self.variables_path = variables_path
self.variables_package = '.'.join(variables_path.split('/'))
self.repository_map = repository_map
def load_variables_package(self, package_name: str) -> None:
'''Метод для загрузки пакетов с переменными.'''
directory_path = os.path.join(self.variables_path, package_name)
package = '{}.{}'.format(self.variables_package, package_name)
package_namespace = NamespaceNode(package_name)
self.datavars.root.add_namespace(package_namespace)
self._fill_from_package(package_namespace, directory_path, package)
def load_from_profile(self):
if self.repository_map != {}:
self.repository_map = (self.repository_map or
self._get_repository_map(self.datavars))
profile_path = self.datavars.os.gentoo.profile.path
self._fill_from_ini(profile_path)
def _fill_from_package(self, current_namespace: NamespaceNode,
directory_path: str, package: str) -> None:
print('FILL -> {}'.format(current_namespace))
'''Метод для зaполнения переменных из python-файла.'''
file_nodes = []
directory_nodes = []
# Просматриваем директорию
@ -385,21 +417,31 @@ class VariableLoader:
'{}.{}'.format(package,
directory_node.name))
def _fill_from_ini(self, datavars, profile_path):
ini_filler = NamespaceIniFiller()
profile_walker = ProfileWalker(self.basename,
self.get_repository_map(datavars))
def _fill_from_ini(self, profile_path):
'''Метод для зaполнения переменных из ini-файла.'''
print('PROCESSING INI FROM PROFILE')
profile_walker = ProfileWalker(self.ini_basename,
self.repository_map)
for file_path in profile_walker.find(profile_path):
try:
print('PROCESS FILE: {}'.format(file_path))
ini_file_text = read_file(file_path)
ini_filler.fill(datavars, ini_file_text)
self.ini_filler.fill(self.datavars, ini_file_text)
except FilesError:
# TODO продумать обработку ошибок.
pass
def get_repository_map(self, datavars):
def _get_repository_map(self, datavars):
return {repo['name']: repo['path']
for repo in datavars.os.gentoo.repositories}
def fill_from_custom_ini(self, file_path: str):
'''Метод для заполнения переменных из конкретного указанного файла.'''
print('LOAD FROM INI: {}'.format(file_path))
if os.path.exists(file_path):
ini_file_text = read_file(file_path)
self.ini_filler.fill(self.datavars, ini_file_text)
@contextmanager
def test(self, file_name, namespace):
print('IMPORT: {}.{}'.format(namespace.get_fullname(), file_name))
@ -410,6 +452,80 @@ class VariableLoader:
file_name))
class Datavars:
'''Класс для хранения переменных и управления ими.'''
def __init__(self, variables_path='calculate/vars', repository_map=None):
self._variables_path = variables_path
self._available_packages = self._get_available_packages()
self.root = NamespaceNode('<root>')
self._loader = VariableLoader(self, self._variables_path,
repository_map=repository_map)
Namespace.reset()
Namespace.set_datavars(self)
self._loader.load_from_profile()
def reset(self):
'''Метод для сброса модуля переменных.'''
self.root.clear()
self.root = NamespaceNode('<root>')
self._available_packages.clear()
self._available_packages = self._get_available_packages()
Namespace.set_datavars(self)
def _get_available_packages(self) -> dict:
'''Метод для получения словаря с имеющимися пакетами переменных
и путями к ним.'''
available_packages = dict()
for file_name in os.listdir(self._variables_path):
if file_name.startswith('__'):
continue
file_path = os.path.join(self._variables_path, file_name)
if os.path.isdir(file_path):
available_packages.update({file_name: file_path})
return available_packages
def __getattr__(self, package_name: str):
'''Метод возвращает ноду пространства имен, соответствующего искомому
пакету.'''
print('getattr: {}'.format(package_name))
if package_name in self.root.namespaces:
return self.root[package_name]
elif package_name not in self._available_packages:
raise VariableError("variables package '{}' is not found".
format(package_name))
else:
self._loader.load_variables_package(package_name)
return self.root[package_name]
def __getitem__(self, package_name: str) -> None:
'''Метод возвращает ноду пространства имен, соответствующего искомому
пакету.'''
print('getitem: {}'.format(package_name))
if package_name in self.root:
return self.root[package_name]
elif package_name not in self._available_packages:
raise VariableError("variables package '{}' is not found".
format(package_name))
else:
self._loader.load_variables_package(package_name)
return self.root[package_name]
def __contains__(self, package_name):
if package_name in self.root.namespaces:
return True
elif package_name not in self._available_packages:
return False
else:
self._loader.load_variables_package(package_name)
return True
@property
def namespaces(self):
return self.root.namespaces
class OldVariableLoader:
'''Класс, используемый для загрузки переменных из python модуля.'''
re_upper = re.compile("(.)([A-Z])")

@ -0,0 +1,5 @@
from calculate.vars.datavars import Variable, ReadonlyVariable
class Chroot(Variable):
properties = [ReadonlyVariable]
value = "/"

@ -0,0 +1,88 @@
from calculate.vars.datavars import Variable, ChoiceVariable, HashVariable, TableVariable, Namespace
from calculate.utils.files import stderr_devnull
import calculate.utils.fs as fs
import os
"""
gentoo
make_profile
profile.path
profile.name
repositories[*].name
repositories[*].path
config
"""
class MakeProfile(Variable):
"""
Путь до файла, указывающего на активный профиль
"""
value = '/etc/portage/make.profile'
class Profile(Namespace):
"""
Параметры текущего профиля
"""
class Path(Variable):
"""
Абсолютный путь до профиля
"""
def get(self):
make_profile = self.vars.parent.make_profile.getValue(self)
make_profile_dir = os.path.dirname(make_profile)
profileLink = fs.readlink(make_profile)
if profileLink:
profileLink = os.path.normpath(
os.path.join(make_profile_dir,profileLink))
return profileLink
else:
return ""
class Name(Variable):
"""
Название профиля
"""
def get(self):
profile_path = self.vars.path.getValue(self)
if not profile_path:
return ""
repositories = self.vars.parent.repositories
for rep in repositories:
reppath = rep.path.getValue(self)
repname = rep.name.getValue(self)
removepart = os.path.normpath(os.path.join(reppath,"profiles"))
if profile_path.startswith(removepart):
return "%s:%s"%(
repname,
profile_path[len(removepart)+1:])
return profile_path
class Repositories(TableVariable):
"""
Информация о репозиториях
name: имя репозитория
path: полный путь до репозитория
"""
class Data(TableVariable.Data):
def get(self):
config = self.vars.config.getValue(self)
return [
{
'name': name,
'path': path
}
for path, name in config.repositories.location_map.items()
]
hash_vars = ["name", "path"]
class Config(Variable):
"""
Объект текущей конфигурации Portage
"""
def get(self):
from portage.package.ebuild.config import config
chroot_path = self.vars.root.main.chroot.getValue(self)
if chroot_path == '/':
with stderr_devnull():
return config()

@ -4,8 +4,9 @@ import os
import importlib
import importlib.util
import site
from calculate.vars.datavars import Variable, Namespace, HashVariable,\
TableVariable, IniCreated, DefaultValue
from calculate.variables.old_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 list_directory

@ -1,5 +1,7 @@
from calculate.vars.datavars import Variable, ReadonlyVariable
from calculate.variables.datavars import Variable, StringType
'''
main:
chroot -> string
'''
class Chroot(Variable):
properties = [ReadonlyVariable]
value = "/"
Variable('chroot', type=StringType.readonly, source='/')

@ -1,88 +1,79 @@
from calculate.vars.datavars import Variable, ChoiceVariable, HashVariable, TableVariable, Namespace
from calculate.utils.files import stderr_devnull
import calculate.utils.fs as fs
import os
from calculate.utils.files import stderr_devnull
from calculate.utils.files import read_link, FilesError
from calculate.variables.datavars import Variable, Namespace, Dependence,\
StringType, TableType
'''
gentoo:
make_profile -> string
profile:
path -> string
name -> string
repositories[*]{name, path} -> table
config -> undefined
'''
"""
gentoo
make_profile
profile.path
profile.name
repositories[*].name
repositories[*].path
config
"""
# Путь до файла, указывающего на активный профиль
Variable('make_profile', type=StringType, source='/etc/portage/make.profile')
class MakeProfile(Variable):
"""
Путь до файла, указывающего на активный профиль
"""
value = '/etc/portage/make.profile'
# Параметры текущего профиля.
with Namespace('profile'):
def get_profile_link(make_profile):
make_profile_dir = os.path.dirname(make_profile.value)
try:
profile_link = read_link(make_profile)
except FilesError:
return ""
class Profile(Namespace):
"""
Параметры текущего профиля
"""
class Path(Variable):
"""
Абсолютный путь до профиля
"""
def get(self):
make_profile = self.vars.parent.make_profile.getValue(self)
make_profile_dir = os.path.dirname(make_profile)
profileLink = fs.readlink(make_profile)
if profileLink:
profileLink = os.path.normpath(
os.path.join(make_profile_dir,profileLink))
return profileLink
if profile_link:
profile_link = os.path.normpath(
os.path.join(make_profile_dir, profile_link))
return profile_link
else:
return ""
# Абсолютный путь до профиля
Variable('path', type=StringType,
source=Dependence('..make_profile', depend=get_profile_link))
class Name(Variable):
"""
Название профиля
"""
def get(self):
profile_path = self.vars.path.getValue(self)
def get_profile_name(path, repositories):
profile_path = path.value
if not profile_path:
return ""
repositories = self.vars.parent.repositories
for rep in repositories:
reppath = rep.path.getValue(self)
repname = rep.name.getValue(self)
removepart = os.path.normpath(os.path.join(reppath,"profiles"))
if profile_path.startswith(removepart):
return "%s:%s"%(
repname,
profile_path[len(removepart)+1:])
for repository in repositories.value:
repository_path = repository['path']
repository_name = repository['name']
remove_part = os.path.normpath(os.path.join(repository_path,
"profiles"))
if profile_path.startswith(remove_part):
return "{}:{}".format(repository_name,
profile_path[len(remove_part) + 1:])
return profile_path
# Название профиля
Variable('name', type=StringType,
source=Dependence('.path', '..repositories',
depend=get_profile_link))
class Repositories(TableVariable):
"""
Информация о репозиториях
def get_repository_table(config):
return [{'name': name,
'path': path}
for path, name in config.value.repositories.location_map.items()]
name: имя репозитория
path: полный путь до репозитория
"""
class Data(TableVariable.Data):
def get(self):
config = self.vars.config.getValue(self)
return [
{
'name': name,
'path': path
}
for path, name in config.repositories.location_map.items()
]
hash_vars = ["name", "path"]
class Config(Variable):
"""
Объект текущей конфигурации Portage
"""
def get(self):
# Информация о репозиториях
# name: имя репозитория
# path: полный путь до репозитория
Variable('repositories', type=TableType,
source=Dependence('.config', depend=get_repository_table))
def get_config_object(chroot_path):
from portage.package.ebuild.config import config
chroot_path = self.vars.root.main.chroot.getValue(self)
if chroot_path == '/':
if chroot_path.value == '/':
with stderr_devnull():
return config()
# Объект текущей конфигурации Portage
Variable('config', source=Dependence('main.chroot', depend=get_config_object))

@ -0,0 +1,13 @@
from calculate.variables.datavars import Variable, ListType, HashType
'''
system:
env_order -> list
env_path -> hash
'''
# Список мест, где есть calculate.ini файлы.
Variable('env_order', type=ListType.readonly,
source=['grp', 'system', 'etc', 'local', 'remote'])
# Отображение множества мест, где есть calculate.ini файлы, на пути к ним.
Variable('env_path', type=HashType, source=dict())

@ -24,8 +24,8 @@ markers =
files_utils: marker for running tests for calculate.utils.files module.
package_utils: marker for running tests for calculate.utils.contents module.
vars: marker for running tests for datavars
alt_vars: marker for testing alternative version of the datavars module.
old_vars: marker for running tests for datavars
vars: marker for testing alternative version of the datavars module.
gentoo: marker for running tests for utils.gentoo
calculateini: marker for running tests for utils.calculateini
template_engine: marker for running tests for TemplateEngine.

@ -1,16 +1,22 @@
import pytest
import os
from calculate.vars.datavars import Namespace, Variable, CyclicVariableError,\
VariableError, ReadonlyVariable,\
ChoiceVariable, IntegerVariable,\
StringVariable, DefaultValue,\
from calculate.variables.old_vars.datavars import Namespace, Variable,\
CyclicVariableError,\
VariableError,\
ReadonlyVariable,\
ChoiceVariable,\
IntegerVariable,\
StringVariable,\
DefaultValue,\
TableVariable, HashVariable,\
VariableNotFoundError
from calculate.vars.vars_loader import NamespaceIniFiller, VariableLoader,\
ProfileFiller, NamespaceIniFillerStrict
from calculate.variables.old_vars.vars_loader import NamespaceIniFiller,\
VariableLoader,\
ProfileFiller,\
NamespaceIniFillerStrict
@pytest.mark.vars
@pytest.mark.old_vars
class TestNamespace:
def test_init_empty_namespace(self):
ns = Namespace()

@ -1,9 +1,8 @@
import pytest
from calculate.vars.vars_loader import CalculateIniParser, Define
from calculate.variables.loader import CalculateIniParser, Define
@pytest.mark.vars
@pytest.mark.calculateini
class TestCalculateIni:
def test_empty_calculate_ini(self):
pass
@ -17,8 +16,7 @@ class TestCalculateIni:
"varval1 = value1\n")
parsed_lines = [{'start_section': (['section'],)},
{'define_key': (['section'], 'varval1',
'value1', Define.assign)},
{'define_key': ('varval1', 'value1', Define.assign)},
]
parse_result = list(ini_parser.parse(input_text))
@ -35,12 +33,9 @@ class TestCalculateIni:
"varval3 -= value3\n")
parsed_lines = [{'start_section': (['section'],)},
{'define_key': (['section'], 'varval1',
'value1', Define.assign)},
{'define_key': (['section'], 'varval2',
'value2', Define.append)},
{'define_key': (['section'], 'varval3',
'value3', Define.remove)},
{'define_key': ('varval1', 'value1', Define.assign)},
{'define_key': ('varval2', 'value2', Define.append)},
{'define_key': ('varval3', 'value3', Define.remove)},
]
parse_result = list(ini_parser.parse(input_text))
@ -60,16 +55,12 @@ class TestCalculateIni:
"varval1 = value1\n")
parsed_lines = [{'start_section': (['section', 'sub'],)},
{'define_key': (['section', 'sub'],
'varval1', 'value1', Define.assign)},
{'define_key': (['section', 'sub'],
'varval2', 'value2', Define.assign)},
{'define_key': ('varval1', 'value1', Define.assign)},
{'define_key': ('varval2', 'value2', Define.assign)},
{'start_section': (['section', 'sub2'],)},
{'define_key': (['section', 'sub2'],
'varval1', 'value1', Define.assign)},
{'define_key': ('varval1', 'value1', Define.assign)},
{'start_section': (['section2'],)},
{'define_key': (['section2'], 'varval1',
'value1', Define.assign)}]
{'define_key': ('varval1', 'value1', Define.assign)}]
parse_result = list(ini_parser.parse(input_text))
for parsed_line, result_line in zip(parsed_lines, parse_result):
@ -92,10 +83,8 @@ class TestCalculateIni:
"[section][][sub][]\n")
parsed_lines = [{'start_section': (['section', 'sub2'],)},
{'define_key': (['section', 'sub2'],
'varval1', 'value1', Define.assign)},
{'define_key': (['section', 'sub2'],
'varval4', 'value4', Define.assign)},
{'define_key': ('varval1', 'value1', Define.assign)},
{'define_key': ('varval4', 'value4', Define.assign)},
{'clear_section': (['section'],)}
]

@ -1,15 +1,22 @@
import os
import shutil
import pytest
from calculate.vars.alt_datavars import NamespaceNode, VariableNode,\
from calculate.variables.datavars import NamespaceNode, VariableNode,\
Namespace, Variable, Dependence,\
CyclicVariableError, HashType,\
StringType, IntegerType, VariableType,\
VariableError, TableType, BooleanType,\
VariableTypeError, FloatType, ListType
from calculate.vars.alt_vars_loader import NamespaceIniFiller, VariableLoader
StringType, IntegerType,\
VariableType, VariableError,\
TableType, BooleanType,\
VariableTypeError, FloatType,\
ListType
from calculate.variables.loader import NamespaceIniFiller, Datavars
from calculate.utils.files import stderr_devnull
@pytest.mark.alt_vars
TESTFILES_PATH = os.path.join(os.getcwd(), 'tests/variables/testfiles')
@pytest.mark.vars
class TestNamespace:
# Сначала тестируем классы и методы необходимые для построения дерева
# переменных и пространств имен.
@ -364,7 +371,7 @@ class TestNamespace:
Namespace.reset()
with Namespace('namespace_1'):
Variable('var_1', source='value_1', type=StringType, readonly=True)
Variable('var_1', source='value_1', type=StringType.readonly)
with Namespace('namespace_1'):
with pytest.raises(VariableError):
@ -520,6 +527,47 @@ class TestNamespace:
assert datavars.namespace_1.var_4.key_2 == 'other_value'
assert datavars.namespace_1.var_4.key_3 == 'another_value'
def test_if_hash_variable_is_created_as_not_fixed_and_then_changed_using_dictionary_with_a_new_key__the_hash_adds_a_new_key_to_the_first_hash(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', type=HashType, source={'key_1': 'value_1',
'key_2': 'value_2'})
assert datavars.namespace_1.var_1.key_1 == 'value_1'
assert datavars.namespace_1.var_1.key_2 == 'value_2'
with Namespace('namespace_1'):
Variable('var_1', source={'key_1': 'another_value',
'key_2': 'other_value',
'key_3': 'new_value'})
assert datavars.namespace_1.var_1.key_1 == 'another_value'
assert datavars.namespace_1.var_1.key_2 == 'other_value'
assert datavars.namespace_1.var_1.key_3 == 'new_value'
def test_if_hash_variable_is_created_as_fixed_and_then_changed_using_dictionary_with_a_new_key__the_hash_raises_the_VariableError_exception(self):
Namespace.reset()
datavars = Namespace.datavars
with Namespace('namespace_1'):
Variable('var_1', type=HashType.fixed, source={'key_1': 'value_1',
'key_2': 'value_2'})
assert datavars.namespace_1.var_1.key_1 == 'value_1'
assert datavars.namespace_1.var_1.key_2 == 'value_2'
with Namespace('namespace_1'):
Variable('var_1', source={'key_1': 'another_value',
'key_2': 'other_value',
'key_3': 'new_value'})
assert datavars.namespace_1['var_1'].fixed
with pytest.raises(VariableError):
datavars.namespace_1.var_1.key_1
def test_if_variable_is_created_with_dependence_and_one_of_arguments_of_a_depend_function_is_whole_hash__the_variable_will_set_this_argument_as_dictionary_of_the_whole_hash_in_a_depend_function(self):
Namespace.reset()
datavars = Namespace.datavars
@ -568,7 +616,7 @@ class TestNamespace:
datavars = Namespace.datavars
with Namespace('main'):
Variable('chroot', source='/', type=StringType, readonly=True)
Variable('chroot', source='/', type=StringType.readonly)
with Namespace('os'):
def source_function(chroot_path):
@ -901,22 +949,33 @@ value = another_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')
def test_if_a_Datavars_object_is_created_with_path_to_the_variables_without_any_Dependencies_and_then_used_to_get_access_to_the_some_variables_from__the_datavars_object_dynamically_loads_variables_and_retruns_necessary_variables(self):
datavars = Datavars(
variables_path='tests/variables/testfiles/variables_0',
repository_map={})
assert datavars.os.ns.var_1 == 'value_1'
assert datavars.os.ns.var_2 == 2
assert 'main' not in datavars.root
assert datavars.main.strange_variable == 'weird_value'
assert datavars.main.plain_variable is True
assert 'main' in datavars.root
def test_loader_2(self):
Namespace.reset()
loader = VariableLoader()
datavars = loader.load_variables('tests/vars/testfiles/variables_1')
def test_if_a_Datavars_object_is_created_with_path_to_the_variables_with_some_Dependencies_and_then_used_to_get_access_to_the_some_variables_from__the_datavars_object_dynamically_loads_variables_and_retruns_necessary_variables(self):
datavars = Datavars(
variables_path='tests/variables/testfiles/variables_1',
repository_map={})
assert datavars.main.chroot == '/'
assert 'os' not in datavars.root
assert datavars.os.calculate == 'test1 test2'
assert 'os' in datavars.root
assert datavars.level.level_2.vargetter == '/ test'
assert 'main' in datavars.root
assert datavars.level.simple == "simple value"
assert datavars.level.use_local_simple == "Using simple value"
assert datavars.level.use_full_simple == "Using simple value"
@ -927,3 +986,52 @@ value = another_value
{"dev": "/dev/sdb",
"type": "flash",
"name": "Transcend 64GB"}]
def test_if_a_Datavars_object_is_created_with_path_to_the_variables_with_Dependencies_and_then_the_variables_are_changed_using_calculate_ini_files_and_the_datavars_object_used_to_get_access_to_the_some_variables_from__the_datavars_object_dynamically_loads_variables_and_retruns_necessary_variables(self):
datavars = Datavars(
variables_path='tests/variables/testfiles/variables_4',
repository_map={})
assert datavars.main.chroot == '/'
assert 'os' not in datavars.root
assert datavars.level.level_2.vargetter == '/ test'
assert 'main' in datavars.root
assert datavars.level.simple == "simple value"
datavars._loader.fill_from_custom_ini(os.path.join(TESTFILES_PATH,
'calculate_0.ini'))
assert 'os' in datavars.root
assert datavars.level.simple == 'weird value'
assert datavars.main.chroot == '/any/other/path'
assert datavars.level.level_2.vargetter == '/any/other/path test'
def test_to_make_testfiles(self):
shutil.copytree(os.path.join(TESTFILES_PATH, 'gentoo.backup'),
os.path.join(TESTFILES_PATH, 'gentoo'),
symlinks=True)
def test_ini_loader(self):
repository_map = {'distros': os.path.join(TESTFILES_PATH,
"gentoo/repos/distros"),
'calculate': os.path.join(TESTFILES_PATH,
"gentoo/repos/calculate"),
'gentoo': os.path.join(TESTFILES_PATH,
"gentoo/portage")}
datavars = Datavars(
variables_path=os.path.join(TESTFILES_PATH, 'variables_2'),
repository_map=repository_map)
def test_get_repository_map(self):
datavars = Datavars(
variables_path=os.path.join(TESTFILES_PATH, 'variables_3'))
print('LOADING IS DONE')
print('hashvar.value1 = {}'.format(datavars.os.hashvar.value1))
print('hashvar.value2 = {}'.format(datavars.os.hashvar.value2))
assert False
def test_for_removing_testfile(self):
shutil.rmtree(os.path.join(TESTFILES_PATH, 'gentoo'))

@ -0,0 +1,9 @@
[main]
chroot = /any/other/path
[level]
simple = weird value
[os][linux]
fullname = full_name
shortname = SN

@ -0,0 +1,21 @@
[os][linux]
ver = 20
shortname = CLD
fullname = Calculate Linux Desktop
subname = KDE
[os][hashvar]
value1 = 20
value2 = 30
[os][tablevar][0]
dev = /dev/sda1
mount = swap
[os][tablevar][1]
dev = /dev/sda2
mount = /
[os][tablevar][2]
dev = /dev/sda5
mount = /var/calculate

@ -0,0 +1,3 @@
[os][linux]
shortname = Calculate
test = test

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

@ -1,4 +1,4 @@
from calculate.vars.alt_datavars import Namespace, Variable, StringType,\
from calculate.variables.datavars import Namespace, Variable, StringType,\
IntegerType
with Namespace('ns'):

@ -1,4 +1,4 @@
from calculate.vars.alt_datavars import Namespace, Variable, Dependence,\
from calculate.variables.datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType,\
ListType, FloatType

@ -1,4 +1,4 @@
from calculate.vars.alt_datavars import Variable, StringType, Dependence
from calculate.variables.datavars import Variable, StringType, Dependence
Variable('vargetter', type=StringType,

@ -0,0 +1,4 @@
from calculate.variables.datavars import Variable, StringType
Variable('chroot', type=StringType.readonly, source='/')

@ -1,4 +1,4 @@
from calculate.vars.alt_datavars import Namespace, Variable, Dependence,\
from calculate.variables.datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType
with Namespace('linux'):
@ -27,8 +27,10 @@ Variable('hashvar', source={'value1': 'test1',
'value2': 'test2'}, type=HashType)
Variable('calculate', type=StringType,
source=lambda hashvar: "{} {}".format(hashvar.value['value1'],
hashvar.value['value2']))
source=Dependence('.hashvar',
depend=lambda hashvar: "{} {}".format(
hashvar.value['value1'],
hashvar.value['value2'])))
Variable('tablevar', type=TableType, source=[{"dev": "/dev/sdb1",
"mount": "/"},

@ -0,0 +1,4 @@
from calculate.variables.datavars import Variable, StringType
Variable('chroot', type=StringType, source='/')

@ -0,0 +1,38 @@
from calculate.variables.datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType
with Namespace('linux'):
Variable('shortname', source='', type=StringType)
Variable('ver', source='', type=StringType)
Variable('fullname', source='', type=StringType)
Variable('subname', source='', type=StringType)
Variable('arch', source='', type=StringType)
Variable('test', source='', type=StringType)
def get_title(subname, fullname, ver):
if subname.value:
return '{} {} {}'.format(fullname.value, subname.value, ver.value)
else:
return '{} {}'.format(fullname.value, ver.value)
Variable('title', type=StringType,
source=Dependence('.subname', '.fullname', '.ver',
depend=get_title))
Variable('hashvar', source={'value1': 'test1',
'value2': 'test2'}, type=HashType)
Variable('calculate', type=StringType,
source=Dependence('.hashvar',
depend=lambda hashvar: "{} {}".format(
hashvar.value['value1'],
hashvar.value['value2'])))
Variable('tablevar', type=TableType, source=[{"dev": "/dev/sdb1",
"mount": "/"},
{"dev": "/dev/sdb2",
"mount": "/var/calculate"}])

@ -0,0 +1,57 @@
import os
from calculate.variables.datavars import Variable, Namespace, Dependence,\
StringType, TableType
'''
gentoo:
make_profile -> string
profile:
path -> string
name -> string
repositories[*]{name, path} -> table
config -> undefined
'''
TESTFILES_PATH = os.path.join(os.getcwd(), 'tests/variables/testfiles')
# Путь до файла, указывающего на активный профиль
Variable('make_profile', type=StringType, source='/etc/portage/make.profile')
# Параметры текущего профиля.
with Namespace('profile'):
# Абсолютный путь до профиля
Variable('path', type=StringType,
source=os.path.join(TESTFILES_PATH,
"gentoo/repos/distros/profiles/CLD/amd64"))
def get_profile_name(path, repositories):
profile_path = path.value
if not profile_path:
return ""
for repository in repositories.value:
repository_path = repository['path']
repository_name = repository['name']
remove_part = os.path.normpath(os.path.join(repository_path,
"profiles"))
if profile_path.startswith(remove_part):
return "{}:{}".format(repository_name,
profile_path[len(remove_part) + 1:])
return profile_path
# Название профиля
Variable('name', type=StringType,
source=Dependence('.path', '..repositories',
depend=get_profile_name))
# Информация о репозиториях
# name: имя репозитория
# path: полный путь до репозитория
Variable('repositories', type=TableType,
source=[{'name': 'distros',
'path': os.path.join(TESTFILES_PATH,
"gentoo/repos/distros")},
{'name': 'calculate',
'path': os.path.join(TESTFILES_PATH,
"gentoo/repos/calculate")},
{'name': 'gentoo',
'path': os.path.join(TESTFILES_PATH,
"gentoo/portage")}])

@ -0,0 +1,4 @@
from calculate.variables.datavars import Variable, StringType
Variable('chroot', type=StringType, source='/')

@ -0,0 +1,38 @@
from calculate.variables.datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType
with Namespace('linux'):
Variable('shortname', source='', type=StringType)
Variable('ver', source='', type=StringType)
Variable('fullname', source='', type=StringType)
Variable('subname', source='', type=StringType)
Variable('arch', source='', type=StringType)
Variable('test', source='', type=StringType)
def get_title(subname, fullname, ver):
if subname.value:
return '{} {} {}'.format(fullname.value, subname.value, ver.value)
else:
return '{} {}'.format(fullname.value, ver.value)
Variable('title', type=StringType,
source=Dependence('.subname', '.fullname', '.ver',
depend=get_title))
Variable('hashvar', source={'value1': 'test1',
'value2': 'test2'}, type=HashType)
Variable('calculate', type=StringType,
source=Dependence('.hashvar',
depend=lambda hashvar: "{} {}".format(
hashvar.value['value1'],
hashvar.value['value2'])))
Variable('tablevar', type=TableType, source=[{"dev": "/dev/sdb1",
"mount": "/"},
{"dev": "/dev/sdb2",
"mount": "/var/calculate"}])

@ -0,0 +1,57 @@
import os
from calculate.variables.datavars import Variable, Namespace, Dependence,\
StringType, TableType
'''
gentoo:
make_profile -> string
profile:
path -> string
name -> string
repositories[*]{name, path} -> table
config -> undefined
'''
TESTFILES_PATH = os.path.join(os.getcwd(), 'tests/variables/testfiles')
# Путь до файла, указывающего на активный профиль
Variable('make_profile', type=StringType, source='/etc/portage/make.profile')
# Параметры текущего профиля.
with Namespace('profile'):
# Абсолютный путь до профиля
Variable('path', type=StringType,
source=os.path.join(TESTFILES_PATH,
"gentoo/repos/distros/profiles/CLD/amd64"))
def get_profile_name(path, repositories):
profile_path = path.value
if not profile_path:
return ""
for repository in repositories.value:
repository_path = repository['path']
repository_name = repository['name']
remove_part = os.path.normpath(os.path.join(repository_path,
"profiles"))
if profile_path.startswith(remove_part):
return "{}:{}".format(repository_name,
profile_path[len(remove_part) + 1:])
return profile_path
# Название профиля
Variable('name', type=StringType,
source=Dependence('.path', '..repositories',
depend=get_profile_name))
# Информация о репозиториях
# name: имя репозитория
# path: полный путь до репозитория
Variable('repositories', type=TableType,
source=[{'name': 'distros',
'path': os.path.join(TESTFILES_PATH,
"gentoo/repos/distros")},
{'name': 'calculate',
'path': os.path.join(TESTFILES_PATH,
"gentoo/repos/calculate")},
{'name': 'gentoo',
'path': os.path.join(TESTFILES_PATH,
"gentoo/portage")}])

@ -0,0 +1,62 @@
from calculate.variables.datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType,\
ListType, FloatType
Variable('simple', type=StringType, source='simple value')
Variable('use_local_simple', type=StringType,
source=Dependence('.simple',
depend=lambda simple: 'Using {}'.format(
simple.value)))
Variable('use_full_simple', type=StringType,
source=Dependence('level.simple',
depend=lambda simple: 'Using {}'.format(
simple.value)))
Variable('disks', type=ListType,
source=["/dev/sda1", "/dev/sda2", "/dev/sda3"])
Variable('version', type=FloatType, source='1.0')
Variable('my_shortname', type=StringType, source='CLD')
Variable('linux', type=HashType,
source=Dependence('.version', '.my_shortname',
depend=lambda version, my_shortname:
{'version': version.value,
'shortname': my_shortname.value}))
Variable('shortname_test', type=StringType,
source=Dependence('.linux.shortname',
depend=lambda shortname: '{} test'.format(
shortname.value)))
Variable('device_list', type=ListType,
source=["/dev/sda", "/dev/sdb"])
def get_device_table(device_list):
map_data = {'/dev/sda': ["hdd", "Samsung SSD"],
'/dev/sdb': ["flash", "Transcend 64GB"],
'/dev/sdc': ["usbhdd", "WD 1TB"]}
default_value = ["hdd", "Unknown"]
print('device_list = {}'.format(device_list.value))
return [{"dev": device,
"type": map_data.get(device, default_value)[0],
"name": map_data.get(device, default_value)[1]}
for device in device_list.value]
Variable('device', type=TableType, source=Dependence('.device_list',
depend=get_device_table))
Variable('device_child', type=StringType,
source=Dependence('.device',
depend=lambda device: device.value[0]['type']))
with Namespace('level_3'):
Variable('my_var_1', type=StringType, source='testing')
Variable('my_var_2', type=StringType, source='testing_2')

@ -0,0 +1,7 @@
from calculate.variables.datavars import Variable, StringType, Dependence
Variable('vargetter', type=StringType,
source=Dependence('main.chroot',
depend=lambda chroot:
'{} test'.format(chroot.value)))

@ -0,0 +1,4 @@
from calculate.variables.datavars import Variable, StringType
Variable('chroot', type=StringType, source='/')

@ -0,0 +1,38 @@
from calculate.variables.datavars import Namespace, Variable, Dependence,\
StringType, HashType, TableType
with Namespace('linux'):
Variable('shortname', source='', type=StringType)
Variable('ver', source='', type=StringType)
Variable('fullname', source='', type=StringType)
Variable('subname', source='', type=StringType)
Variable('arch', source='', type=StringType)
Variable('test', source='', type=StringType)
def get_title(subname, fullname, ver):
if subname.value:
return '{} {} {}'.format(fullname.value, subname.value, ver.value)
else:
return '{} {}'.format(fullname.value, ver.value)
Variable('title', type=StringType,
source=Dependence('.subname', '.fullname', '.ver',
depend=get_title))
Variable('hashvar', source={'value1': 'test1',
'value2': 'test2'}, type=HashType)
Variable('calculate', type=StringType,
source=Dependence('.hashvar',
depend=lambda hashvar: "{} {}".format(
hashvar.value['value1'],
hashvar.value['value2'])))
Variable('tablevar', type=TableType, source=[{"dev": "/dev/sdb1",
"mount": "/"},
{"dev": "/dev/sdb2",
"mount": "/var/calculate"}])

@ -1,6 +0,0 @@
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)

@ -1,5 +0,0 @@
from calculate.vars.alt_datavars import Variable, StringType
Variable('chroot', type=StringType, source='/', readonly=True)
print('chroot really created')
Loading…
Cancel
Save