|
|
|
@ -6,13 +6,6 @@ from inspect import signature, getsource
|
|
|
|
|
from types import FunctionType, LambdaType
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableType:
|
|
|
|
|
'''Базовый класс для типов.'''
|
|
|
|
|
@classmethod
|
|
|
|
|
def check(self, value: str) -> bool:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DependenceError(Exception):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
@ -38,6 +31,13 @@ class CyclicVariableError(VariableError):
|
|
|
|
|
self.queue[:-1]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableType:
|
|
|
|
|
'''Базовый класс для типов.'''
|
|
|
|
|
@classmethod
|
|
|
|
|
def check(self, value: str) -> bool:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class StringType(VariableType):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
@ -78,6 +78,14 @@ class ReadonlyType(VariableType):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HashType(VariableType):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TableType(VariableType):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DependenceSource:
|
|
|
|
|
current_namespace = None
|
|
|
|
|
datavars_root = None
|
|
|
|
@ -182,6 +190,11 @@ class DependenceSource:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HashSource:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableNode:
|
|
|
|
|
'''Класс ноды соответствующей переменной в дереве переменных.'''
|
|
|
|
|
def __init__(self, name, namespace, variable_type=StringType, source=None):
|
|
|
|
@ -239,6 +252,9 @@ class VariableNode:
|
|
|
|
|
subscription.subscribers.add(self)
|
|
|
|
|
|
|
|
|
|
def _invalidate(self):
|
|
|
|
|
'''Метод для инвалидации данной переменной и всех зависящих от нее
|
|
|
|
|
переменных.'''
|
|
|
|
|
print('{} is invalidated'.format(self.fullname))
|
|
|
|
|
if self.value is not None:
|
|
|
|
|
self.value = None
|
|
|
|
|
for subscriber in self.subscribers:
|
|
|
|
@ -329,6 +345,35 @@ class NamespaceNode:
|
|
|
|
|
return '<Namespace: {}>'.format(self.fullname)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HashNode:
|
|
|
|
|
def __init__(self, name, namespace, sources, types=dict()):
|
|
|
|
|
self.name = name
|
|
|
|
|
self.namespace = namespace
|
|
|
|
|
self.calculating = False
|
|
|
|
|
|
|
|
|
|
self.namespace.add_variable(self)
|
|
|
|
|
|
|
|
|
|
self.sources = sources
|
|
|
|
|
self.subscribers = dict()
|
|
|
|
|
self.values = dict()
|
|
|
|
|
self.types = dict()
|
|
|
|
|
for key, source in sources:
|
|
|
|
|
self.values.update({key: None})
|
|
|
|
|
if key in types:
|
|
|
|
|
if issubclass(types[key], VariableType):
|
|
|
|
|
self.types.update({key: types[key]})
|
|
|
|
|
else:
|
|
|
|
|
raise VariableTypeError('variable_type must be'
|
|
|
|
|
' VariableType, but not {}'.format(
|
|
|
|
|
type(types[key])))
|
|
|
|
|
else:
|
|
|
|
|
self.types.update({key: StringType})
|
|
|
|
|
|
|
|
|
|
# Источник значения переменной, может быть значением, а может быть
|
|
|
|
|
# зависимостью.
|
|
|
|
|
self.update_values()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DependenceAPI:
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self.current_namespace = None
|
|
|
|
@ -351,24 +396,22 @@ class DependenceAPI:
|
|
|
|
|
|
|
|
|
|
def _find_variable(self, variable_name):
|
|
|
|
|
'''Метод для поиска переменной в пространстве'''
|
|
|
|
|
variable = None
|
|
|
|
|
name_parts = variable_name.split('.')
|
|
|
|
|
|
|
|
|
|
if not name_parts[0]:
|
|
|
|
|
namespace = self.current_namespace
|
|
|
|
|
index = 1
|
|
|
|
|
while not name_parts[index]:
|
|
|
|
|
namespace = namespace.parent
|
|
|
|
|
index += 1
|
|
|
|
|
name_parts = name_parts[index:]
|
|
|
|
|
for index in range(1, len(name_parts)):
|
|
|
|
|
if not name_parts[index]:
|
|
|
|
|
namespace = namespace.parent
|
|
|
|
|
else:
|
|
|
|
|
name_parts = name_parts[index:]
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
namespace = self.datavars_root
|
|
|
|
|
|
|
|
|
|
variable = namespace
|
|
|
|
|
search_result = namespace
|
|
|
|
|
for part in name_parts:
|
|
|
|
|
variable = variable[part]
|
|
|
|
|
|
|
|
|
|
return variable
|
|
|
|
|
search_result = search_result[part]
|
|
|
|
|
return search_result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VariableAPI:
|
|
|
|
@ -454,6 +497,7 @@ class NamespaceAPI:
|
|
|
|
|
|
|
|
|
|
# Устанавливаем текущее пространство имен фабрике зависимостей.
|
|
|
|
|
self._dependence_fabric.current_namespace = namespace
|
|
|
|
|
self._dependence_fabric.datavars_root = self._datavars
|
|
|
|
|
print('current_namespace in DependenceAPI: {}'.format(
|
|
|
|
|
namespace.fullname))
|
|
|
|
|
try:
|
|
|
|
|