Skip to content
Snippets Groups Projects
Commit f4eabec8 authored by Tsegelnik Nikita's avatar Tsegelnik Nikita
Browse files

renaming to more logical names

parent 2dc74d38
No related branches found
No related tags found
1 merge request!19New version
Pipeline #16935 failed
......@@ -25,75 +25,75 @@ class GDMeta:
@attr.s(repr=False)
class GDNode:
class GDGraph:
"""
The data class for the ``GDGraph`` nodes
The data class for the ``GDGraphHelper`` graphs
:param name: The name of the node
:param data: The data of the node
:param inputs: The list of the inputs
:param name: The name of the graph
:param data: The data of the graph
:param children: The list of the children
"""
name: str = attr.ib(validator=attr.validators.instance_of(str))
data: Any = attr.ib()
inputs: List[GDNode] = attr.ib(
children: List[GDGraph] = attr.ib(
validator=attr.validators.instance_of(list), default=[]
)
meta: GDMeta = GDMeta()
@classmethod
def from_gdata(
cls, data: GData, inputs: Optional[Sequence[GDNode]] = None
) -> GDNode:
cls, data: GData, children: Optional[Sequence[GDGraph]] = None
) -> GDGraph:
"""
Build the class from ``GData``
"""
if not inputs:
inputs = []
elif not isinstance(inputs, List):
inputs = list(inputs)
return cls(data.uname(), data, inputs)
if not children:
children = []
elif not isinstance(children, List):
children = list(children)
return cls(data.uname(), data, children)
def __copy__(self) -> GDNode:
def __copy__(self) -> GDGraph:
obj = type(self).__new__(self.__class__)
obj.__dict__.update(self.__dict__)
return obj
def copy(self) -> GDNode:
def copy(self) -> GDGraph:
return self.__copy__()
def __repr__(self) -> str:
return f"GDNode(name={self.name}, inputs={self.inputs})"
return f"GDGraph(name={self.name}, children={self.children})"
def __str__(self) -> str:
return self.__repr__()
def asdict(self, include_data: bool = False) -> dict:
"""
Returns the dict representation of the node
Returns the dict representation of the graph
:param include_data: If `True`, includes `data` field,
else uses only `name` and `inputs` fields
else uses only `name` and `children` fields
"""
if not include_data:
return {
"name": self.name,
"inputs": [obj.asdict(include_data) for obj in self.inputs],
"children": [obj.asdict(include_data) for obj in self.children],
}
else:
return {
"name": self.name,
"data": self.data,
"inputs": [obj.asdict(include_data) for obj in self.inputs],
"children": [obj.asdict(include_data) for obj in self.children],
}
def print(self, include_data: bool = False) -> None:
"""
Pretty print of the node.
The dict representation (see `GDNode.asdict`) is used
Pretty print of the graph.
The dict representation (see `GDGraph.asdict`) is used
:param include_data: If `True`, includes `data` field,
else uses only `name` and `inputs` fields
else uses only `name` and `children` fields
"""
pprint(self.asdict(include_data))
......@@ -101,7 +101,7 @@ class GDNode:
self, force: bool = False, strict: bool = True, debug: bool = False
) -> bool:
"""
Check for equivalence of the `inputs` with the `data["arguments"]`
Check for equivalence of the `children` with the `data["arguments"]`
If `strict=True` an exception will be raised on the validation failure,
else if `debug=True` a message will be printed instead of the exception
......@@ -117,18 +117,18 @@ class GDNode:
return self.meta.validity
self.meta.is_validated = True
self.meta.validity = False
if len(self.inputs) != len(self.data["arguments"]):
msg = "The lenghts of inputs and data['arguments'] are not equal!"
"Seems like the binding of inputs is not called!"
if len(self.children) != len(self.data["arguments"]):
msg = "The lenghts of children and data['arguments'] are not equal!"
"Seems like the binding of children is not called!"
if strict:
raise ValueError(msg)
elif debug:
print(f"DebugInfo: {msg}")
self.meta.validity = False
return self.meta.validity
for node in self.inputs:
if node.name not in self.data["arguments"]:
msg = f"The node '{node.name}' not in the arguments "
for graph in self.children:
if graph.name not in self.data["arguments"]:
msg = f"The graph '{graph.name}' not in the arguments "
f"{self.data['arguments']}!"
if strict:
raise ValueError(msg)
......@@ -143,37 +143,37 @@ class GDNode:
self, force: bool = False, strict: bool = True, debug: bool = False
) -> bool:
"""
Recursive validation of all the nodes. See (`GDNode.validate`)
Recursive validation of all the graphs. See (`GDGraph.validate`)
:param force: If `False` uses the last cached validation result
"""
statuslist = [self.validate(force, strict, debug)]
statuslist.extend(
node.validate(force, strict, debug) for node in self.inputs
graph.validate(force, strict, debug) for graph in self.children
)
return all(statuslist)
def shape(self) -> tuple:
"""
Returns the shape of the node
Returns the shape of the graph
"""
leninp = len(self.inputs)
leninp = len(self.children)
self.meta.shape = (
(0,)
if leninp == 0
else (leninp, tuple(node.shape() for node in self.inputs))
else (leninp, tuple(graph.shape() for graph in self.children))
)
return self.meta.shape
def objectscount(self) -> int:
"""
Returns the number of the inner nodes, including itself
Returns the number of the inner graphs, including itself
"""
return 1 + sum(node.objectscount() for node in self.inputs)
return 1 + sum(graph.objectscount() for graph in self.children)
def depth(self) -> int:
if len(self.inputs) != 0:
return 1 + max(tuple(node.depth() for node in self.inputs))
if len(self.children) != 0:
return 1 + max(tuple(graph.depth() for graph in self.children))
else:
return 1
......@@ -197,74 +197,74 @@ class GDNode:
def todatalist(self) -> list:
"""
Returns all the `GData` objects: the parent `data` and
all the `data` from the `inputs`
all the `data` from the `children`
"""
return [self.data, *[node.data for node in self.inputs]]
return [self.data, *[graph.data for graph in self.children]]
class GDGraph:
class GDGraphHelper:
"""
The simple directed graph, containing the list of nodes and
the dict with the same nodes as values and the names as keys.
It is possible to modify nodes by the list or by the dict,
but it is important to update the dict after adding new node to the graph:
using the argument `bind` of the `add_node` and `add_nodes` methods
(by default) or by the direct calling the `bind_nodes` method.
There is no edges, but every node has inputs. The method `add_nodes`,
if `bind=True`, collecting inputs by the iteration of the
`data["arguments"]` of the every node. If a single node is added using
the method `add_node`, and it is necessary to iterate through
all the nodes and update the inputs, then a direct call of the
`bind_inputs` method is necessary.
The simple directed graph, containing the list of graphs and
the dict with the same graphs as values and the names as keys.
It is possible to modify graphs by the list or by the dict,
but it is important to update the dict after adding new graph to the graph:
using the argument `bind` of the `add_graph` and `add_graphs` methods
(by default) or by the direct calling the `bind_graphs` method.
There is no edges, but every graph has children. The method `add_graphs`,
if `bind=True`, collecting children by the iteration of the
`data["arguments"]` of the every graph. If a single graph is added using
the method `add_graph`, and it is necessary to iterate through
all the graphs and update the children, then a direct call of the
`bind_children` method is necessary.
"""
def __init__(
self,
nodes: Union[Sequence[Any], Any] = None,
graphs: Union[Sequence[Any], Any] = None,
strict: bool = True,
debug: bool = False,
**kwargs,
) -> None:
self.debug = debug
self.strict = strict
self.nodesdict = {}
self.nodes = []
self.nodescount = self.__len__
self.graphsdict = {}
self.graphs = []
self.graphscount = self.__len__
self.name = kwargs.pop("name", type(self).__name__)
if isinstance(nodes, (List, Tuple)):
self.add_nodes(nodes, kwargs.pop("bind", True))
if isinstance(graphs, (List, Tuple)):
self.add_graphs(graphs, kwargs.pop("bind", True))
else:
raise ValueError(
"The nodes must be `List` or `Tuple`, "
f"but given '{type(nodes)}'!"
"The graphs must be `List` or `Tuple`, "
f"but given '{type(graphs)}'!"
)
def __len__(self) -> int:
return len(self.nodes)
return len(self.graphs)
def __copy__(self) -> GDGraph:
def __copy__(self) -> GDGraphHelper:
obj = type(self).__new__(self.__class__)
obj.__dict__.update(self.__dict__)
return obj
def copy(self) -> GDGraph:
def copy(self) -> GDGraphHelper:
return self.__copy__()
def __repr__(self) -> str:
return f"GDGraph(name={self.name}, nodes={self.nodes})"
return f"GDGraphHelper(name={self.name}, graphs={self.graphs})"
def __str__(self) -> str:
return self.__repr__()
def __iter__(self) -> Iterator[GDNode]:
return self.nodes.__iter__()
def __iter__(self) -> Iterator[GDGraph]:
return self.graphs.__iter__()
def __eq__(self, other: Any) -> bool:
try:
return (
self.nodes == other.nodes and self.nodesdict == other.nodesdict
self.graphs == other.graphs and self.graphsdict == other.graphsdict
)
except AttributeError:
return False
......@@ -274,151 +274,151 @@ class GDGraph:
Returns the dict representation of the graph
:param include_data: If `True`, includes `data` field,
else uses only `name` and `inputs` fields of a node
else uses only `name` and `children` fields of a graph
"""
return {
"name": self.name,
"nodes": [node.asdict(include_data) for node in self.nodes],
"graphs": [graph.asdict(include_data) for graph in self.graphs],
}
def print(self, include_data: bool = False) -> None:
"""
Pretty print of the graph.
The dict representation (see `GDGraph.asdict`) is used
The dict representation (see `GDGraphHelper.asdict`) is used
:param include_data: If `True`, includes `data` field,
else uses only `name` and `inputs` fields of a node
else uses only `name` and `children` fields of a graph
"""
pprint(self.asdict(include_data))
def add_nodes(self, nodes: Sequence[Any], bind: bool = True) -> None:
def add_graphs(self, graphs: Sequence[Any], bind: bool = True) -> None:
"""
Adding the list of the nodes
Adding the list of the graphs
:param nodes: The nodes sequence
:param bind: If `True`, filling also the dict of the nodes
`GDGraph.nodesdict` and binding inputs
:param graphs: The graphs sequence
:param bind: If `True`, filling also the dict of the graphs
`GDGraphHelper.graphsdict` and binding children
"""
self._add_nodes(nodes)
self._add_graphs(graphs)
if bind:
self.bind_nodes()
self.bind_inputs()
def _add_nodes(self, nodes: Sequence[Any]) -> None:
for node in nodes:
if isinstance(node, GData):
self.nodes.append(GDNode.from_gdata(node))
elif isinstance(node, GDNode):
self.nodes.append(node)
elif isinstance(node, (List, Tuple)):
self._add_nodes(node)
self.bind_graphs()
self.bind_children()
def _add_graphs(self, graphs: Sequence[Any]) -> None:
for graph in graphs:
if isinstance(graph, GData):
self.graphs.append(GDGraph.from_gdata(graph))
elif isinstance(graph, GDGraph):
self.graphs.append(graph)
elif isinstance(graph, (List, Tuple)):
self._add_graphs(graph)
else:
if self.strict:
raise ValueError(
"In the strict mode the allowed types for nodes are "
f"`GData` and `GDNode`, but given '{type(node)}'!"
"In the strict mode the allowed types for graphs are "
f"`GData` and `GDGraph`, but given '{type(graph)}'!"
)
elif self.debug:
warn(
"The name of the node cannot be determined, "
"so the string representation of the node is used "
"The name of the graph cannot be determined, "
"so the string representation of the graph is used "
"as the name.",
RuntimeWarning,
)
self.add_node(node)
self.add_graph(graph)
def add_node(
def add_graph(
self,
data: Any,
name: Optional[str] = None,
inputs: Optional[Sequence[GDNode]] = None,
children: Optional[Sequence[GDGraph]] = None,
bind: bool = True,
) -> GDNode:
) -> GDGraph:
"""
Adding the node to the graph
Adding the graph to the graph
:param data: The data of the node
:param name: The name of the node
:param inputs: The list of the inputs
:param bind: If `True`, adding the node to the `GDGraph.nodesdict`
:param data: The data of the graph
:param name: The name of the graph
:param children: The list of the children
:param bind: If `True`, adding the graph to the `GDGraphHelper.graphsdict`
"""
if isinstance(data, GData):
node = GDNode.from_gdata(data, inputs)
elif isinstance(data, GDNode):
node = data
graph = GDGraph.from_gdata(data, children)
elif isinstance(data, GDGraph):
graph = data
else:
if self.strict:
raise ValueError(
"In the strict mode the allowed types for nodes are "
f"`GData` and `GDNode`, but given '{type(data)}'!"
"In the strict mode the allowed types for graphs are "
f"`GData` and `GDGraph`, but given '{type(data)}'!"
)
elif not inputs:
inputs = []
elif not isinstance(inputs, List):
elif not children:
children = []
elif not isinstance(children, List):
try:
inputs = list(inputs)
children = list(children)
except Exception as exc:
raise TypeError(
"The *inputs* must be `list`, but given "
f"'{type(inputs)}!'"
"The *children* must be `list`, but given "
f"'{type(children)}!'"
) from exc
node = GDNode(name or str(data), data, inputs)
self.nodes.append(node)
graph = GDGraph(name or str(data), data, children)
self.graphs.append(graph)
if bind:
self.nodesdict[node.name] = node
return node
self.graphsdict[graph.name] = graph
return graph
def bind_nodes(self) -> dict:
def bind_graphs(self) -> dict:
"""
Filling the dict of the nodes `nodesdict`
Filling the dict of the graphs `graphsdict`
"""
self.nodesdict = {node.name: node for node in self.nodes}
return self.nodesdict
self.graphsdict = {graph.name: graph for graph in self.graphs}
return self.graphsdict
def bind_inputs(self) -> None:
def bind_children(self) -> None:
"""
Collecting and adding inputs to all the nodes from
the `node.data["arguments"]`
Collecting and adding children to all the graphs from
the `graph.data["arguments"]`
"""
for node in self.nodes:
for arg in node.data["arguments"]:
if arg in self.nodesdict:
node.inputs.append(self.nodesdict[arg])
for graph in self.graphs:
for arg in graph.data["arguments"]:
if arg in self.graphsdict:
graph.children.append(self.graphsdict[arg])
def validate(self, force: bool = False) -> bool:
"""
Validates all the nodes by running `GDNode.validate`
Validates all the graphs by running `GDGraph.validate`
:param force: If `False` uses the last cached validation result
"""
statuslist = tuple(
node.validate(force=force, strict=self.strict, debug=self.debug)
for node in self.nodes
graph.validate(force=force, strict=self.strict, debug=self.debug)
for graph in self.graphs
)
return all(statuslist)
def shapes(self) -> tuple:
"""
Returns the tuple of the shapes of the `GDGraph.nodes`
(see `GDNode.shape`)
Returns the tuple of the shapes of the `GDGraphHelper.graphs`
(see `GDGraph.shape`)
"""
return tuple(node.shape() for node in self.nodes)
return tuple(graph.shape() for graph in self.graphs)
def main_node(self) -> Optional[GDNode]:
def main_graph(self) -> Optional[GDGraph]:
"""
Returns the deepest node (see `GDNode.depth`)
Returns the deepest graph (see `GDGraph.depth`)
"""
ind = -1
maxdepth = 0
for i, node in enumerate(self.nodes):
depth = node.depth()
for i, graph in enumerate(self.graphs):
depth = graph.depth()
if maxdepth < depth:
maxdepth = depth
ind = i
return self.nodes[ind] if ind != -1 else None
return self.graphs[ind] if ind != -1 else None
def todatalist(self) -> List[GData]:
"""
Returns the list of the `GData` objects
"""
return [node.data for node in self.nodes]
return [graph.data for graph in self.graphs]
......@@ -11,14 +11,14 @@ if __package__ is None or __package__ == "":
from gagraph import GAGraph
from gdata import GData
from gdatabuilder import GDataBuilder
from gdgraph import GDGraph
from gdgraph import GDGraphHelper
from gtree import GTree
else:
# uses current package visibility
from .gagraph import GAGraph
from .gdata import GData
from .gdatabuilder import GDataBuilder
from .gdgraph import GDGraph
from .gdgraph import GDGraphHelper
from .gtree import GTree
......@@ -26,19 +26,19 @@ class GGraphBuilder:
"""
The ``GGraphBuilder`` class
Designed for the building of ``GDGraph`` or ``GAGraph``
Designed for the building of ``GDGraphHelper`` or ``GAGraph``
from ``GTree``, ``GData`` or ``Sequence[GData]``
:param databuilder: The GData builder class. If ``None``,
use a new instance of ``GDataBuilder``. **Default:** ``None``
:param graphtype: The type of the graph: ``GDGraph`` or ``GAGraph``
:param graphtype: The type of the graph: ``GDGraphHelper`` or ``GAGraph``
:param debug: The debug option
"""
def __init__(
self,
databuilder: Optional[GDataBuilder] = None,
graphtype: Literal["GDGraph", "GAGraph"] = "GDGraph",
graphtype: Literal["GDGraphHelper", "GAGraph"] = "GDGraphHelper",
debug: bool = False,
) -> None:
if not databuilder:
......@@ -79,14 +79,14 @@ class GGraphBuilder:
@graphtype.setter
def graphtype(self, value: str) -> None:
if value not in ("GDGraph", "GAGraph"):
if value not in ("GDGraphHelper", "GAGraph"):
raise TypeError(
"The *graphtype* option must be 'GDGraph' or 'GAGraph', "
"The *graphtype* option must be 'GDGraphHelper' or 'GAGraph', "
f"but given: '{value}'"
)
self._graphtype = value
self.build = (
self.dbuild if self.graphtype == "GDGraph" else self.abuild
self.dbuild if self.graphtype == "GDGraphHelper" else self.abuild
)
@property
......@@ -109,18 +109,18 @@ class GGraphBuilder:
def dbuild(
self,
_data: Union[GTree, GData, Sequence],
orig: Optional[GDGraph] = None,
orig: Optional[GDGraphHelper] = None,
**kwargs,
) -> GDGraph:
) -> GDGraphHelper:
"""
Builds ``GDGraph`` from ``GTree`` or ``GData``
Builds ``GDGraphHelper`` from ``GTree`` or ``GData``
:param data: The data from which the ``GDGraph`` will be collected.
:param data: The data from which the ``GDGraphHelper`` will be collected.
May be ``GTree``, ``GData`` or ``Sequence``.
:param orig: If ``orig`` is ``GDGraph``,
:param orig: If ``orig`` is ``GDGraphHelper``,
starting from the graph and modifying it while
the building graph from ``data``.
Else create a new instance of ``GDGraph``. **Default:** ``None``
Else create a new instance of ``GDGraphHelper``. **Default:** ``None``
"""
data = (
_data
......@@ -131,13 +131,13 @@ class GGraphBuilder:
data = list(data)
if not orig:
graph = GDGraph(nodes=data, debug=self.debug, **kwargs)
elif isinstance(orig, GDGraph):
graph = GDGraphHelper(nodes=data, debug=self.debug, **kwargs)
elif isinstance(orig, GDGraphHelper):
graph = orig.copy()
graph.add_nodes(nodes=data, bind=kwargs.pop("bind", True))
else:
raise TypeError(
f"The *graph* must be 'GDGraph', but given '({orig},"
f"The *graph* must be 'GDGraphHelper', but given '({orig},"
f" {type(orig)})'"
)
return graph
......@@ -228,10 +228,10 @@ class GGraphBuilder:
graph.add_edge(data2[2], data1[2])
return graph
def togagraph(self, gdgraph: GDGraph, **kwargs) -> GAGraph:
def togagraph(self, gdgraph: GDGraphHelper, **kwargs) -> GAGraph:
"""
Converts `GDGraph` to `GAGraph`
Converts `GDGraphHelper` to `GAGraph`
"""
if not isinstance(gdgraph, GDGraph):
if not isinstance(gdgraph, GDGraphHelper):
raise TypeError(f"Cannot convert '{type(gdgraph)} to `GAGraph`'!")
return self.abuild(gdgraph.todatalist(), **kwargs)
......@@ -26,7 +26,7 @@ if __package__ is None or __package__ == "":
from gagraph import GAGraph
from gdata import GData
from gdatabuilder import GDataBuilder
from gdgraph import GDGraph
from gdgraph import GDGraphHelper
from ggraphbuilder import GGraphBuilder
from gpatternmatcher import GPatternMatcher
from gtree import GToken, GTree
......@@ -35,7 +35,7 @@ else:
from .gagraph import GAGraph
from .gdata import GData
from .gdatabuilder import GDataBuilder
from .gdgraph import GDGraph
from .gdgraph import GDGraphHelper
from .ggraphbuilder import GGraphBuilder
from .gpatternmatcher import GPatternMatcher
from .gtree import GToken, GTree
......@@ -69,7 +69,7 @@ class GParser(Lark):
lib: Optional[str] = None,
patternmatcher: Optional[GPatternMatcher] = None,
graphbuilder: Optional[GGraphBuilder] = None,
graphtype: Literal["GDGraph", "GAGraph"] = "GDGraph",
graphtype: Literal["GDGraphHelper", "GAGraph"] = "GDGraphHelper",
databuilder: Optional[GDataBuilder] = None,
grammar: Optional[Union[Grammar, str, IO[str]]] = None,
parser: Literal["earley", "lalr", "cyk", "auto"] = "lalr",
......@@ -284,10 +284,10 @@ class GParser(Lark):
def pattern_matching(
self,
data: Union[Sequence, GDGraph],
data: Union[Sequence, GDGraphHelper],
lib: Optional[str] = None,
**kwargs,
) -> Union[Sequence, GDGraph]:
) -> Union[Sequence, GDGraphHelper]:
"""
Makes ``Pattern Matching`` for the ``data`` and returns the result
......@@ -303,7 +303,7 @@ class GParser(Lark):
try:
if isinstance(data, Sequence):
return [self.patternmatcher.match(elem) for elem in data]
if not isinstance(data, GDGraph):
if not isinstance(data, GDGraphHelper):
data = self.build_graph(data, pattern_matching=False, **kwargs)
if lib:
self.patternmatcher.lib = lib
......@@ -326,9 +326,9 @@ class GParser(Lark):
data: Union[Sequence, GTree],
pattern_matching: bool = False,
**kwargs,
) -> Union[List, GAGraph, GDGraph]:
) -> Union[List, GAGraph, GDGraphHelper]:
"""
Builds ``GAGraph`` or ``GDGraph`` from the ``data``
Builds ``GAGraph`` or ``GDGraphHelper`` from the ``data``
and returns the result
:param data: The data to the graph building.
......@@ -339,7 +339,7 @@ class GParser(Lark):
(is setted and ``lib`` arg is ``None``).
**Default:** ``False``
:return: The builded ``GAGraph`` or ``GDGraph``
:return: The builded ``GAGraph`` or ``GDGraphHelper``
"""
if isinstance(data, Sequence):
return [
......
......@@ -5,7 +5,6 @@ from typing import (
Callable,
List,
Optional,
Sequence,
Tuple,
)
from yaml import safe_load, YAMLError
......@@ -14,13 +13,11 @@ from yaml import safe_load, YAMLError
if __package__ is None or __package__ == "":
# uses current directory visibility
# fixed import error when building documentation
from gtree import GToken, GTree
from gdgraph import GDGraph
from gdgraph import GDGraphHelper
from gdata import GData
else:
# uses current package visibility
from .gtree import GToken, GTree
from .gdgraph import GDGraph
from .gdgraph import GDGraphHelper
from .gdata import GData
......@@ -174,10 +171,10 @@ class GPatternMatcher:
f"key: {key}!"
)
data[key] = pattern[key]
self.pgraphs.append(GDGraph(nodes=datalist, strict=True))
self.pgraphs.append(GDGraphHelper(graphs=datalist, strict=True))
return self.pgraphs
def match(self, graph: GDGraph) -> GDGraph:
def match(self, graph: GDGraphHelper) -> GDGraphHelper:
"""
Find patterns in the `lib` and match corresponding object in
the `tree`
......@@ -197,9 +194,9 @@ class GPatternMatcher:
"arguments",
"type",
)
for node in graph.nodes:
for node in graph.graphs:
for pgraph in self.pgraphs:
mainnode = pgraph.main_node()
mainnode = pgraph.main_graph()
if not mainnode.isliketo(node):
continue
for key in mainnode.data:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment