def __init__(self, *pattern_objects, flag_groupable = None, value_immediate = None, value_delimiter = None): # Create graphs (forward and reversed) fgraph = Graph() rgraph = Graph() # Create a flat map of all patterns, and # a flag map (associate all flags with all patterns), and # a graph all patterns, to build context hierarchy self._flags = flags = {} self._patterns = patterns = {} for pattern in pattern_objects: if pattern.name in patterns: raise Scheme.LongFlagIsNotUnique( 'Long flag is used more than once: ' '{!r}'.format(pattern.name)) patterns[pattern.name] = pattern # Set global options if flag_groupable is not None: pattern.flag_groupable = flag_groupable if value_immediate is not None: pattern.value_immediate = value_immediate if value_delimiter is not None: pattern.value_delimiter = value_delimiter # Add pattern to graph fgraph.add_vertex(pattern.name) rgraph.add_vertex(pattern.name) for flag in pattern.flags: if flag in flags: raise Scheme.ShortFlagIsNotUnique( 'Short flag is used more than once: ' '{!r}'.format(flag)) flags[flag] = pattern # Build graph edges for name, pattern in patterns.items(): # If pattern is a context, create edges to its members for member in pattern._members: # If member is an Pattern instance if isinstance(member, Pattern): fgraph.add_edge(name, member.name) rgraph.add_edge(member.name, name) # If member is a string-name reference elif isinstance(member, str): # If member is not a real reference if member not in patterns: raise Scheme.InvalidMemberReference(member) fgraph.add_edge(name, member) rgraph.add_edge(member, name) # If member is not a Pattern nor a string else: raise Scheme.InvalidPatternMember( "Type of members of Pattern {!r} " "should be 'str' or 'Pattern' not " "{.__class__.__qualname__!r}".format(name, member)) # Build context hierarchy self._hierarchy = hierarchy = {} try: for vertex in topo_sort(fgraph, tracking=True): # If vertex doesn't have parent(s) if not rgraph.vertex(vertex.id).vertices(): # Build its branch hierarchy[vertex.id] = Scheme._branch(vertex) # If there are circular references in the graph except DAGCycleError as message: raise Scheme.CircularReferences(message.args) from None
g.add_vertex('B') g.add_vertex('C') g.add_vertex('D') g.add_vertex('E') g.add_vertex('F') g.add_vertex('G') g.add_vertex('H') g.add_vertex('I') g.add_vertex('J') g.add_vertex('K') g.add_vertex('L') g.add_vertex('M') g.add_vertex('N') g.add_vertex('O') g.add_edge('root', 'A') g.add_edge('root', 'B') g.add_edge('A', 'C') g.add_edge('A', 'D') g.add_edge('B', 'E') g.add_edge('B', 'F') g.add_edge('C', 'G') g.add_edge('C', 'H') g.add_edge('D', 'I') g.add_edge('D', 'J') g.add_edge('E', 'K') g.add_edge('F', 'L') g.add_edge('F', 'M') g.add_edge('H', 'N') g.add_edge('L', 'O')
def __init__(self, *pattern_objects, flag_groupable=None, value_immediate=None, value_delimiter=None): # Create graphs (forward and reversed) fgraph = Graph() rgraph = Graph() # Create a flat map of all patterns, and # a flag map (associate all flags with all patterns), and # a graph all patterns, to build context hierarchy self._flags = flags = {} self._patterns = patterns = {} for pattern in pattern_objects: if pattern.name in patterns: raise Scheme.LongFlagIsNotUnique( 'Long flag is used more than once: ' '{!r}'.format(pattern.name)) patterns[pattern.name] = pattern # Set global options if flag_groupable is not None: pattern.flag_groupable = flag_groupable if value_immediate is not None: pattern.value_immediate = value_immediate if value_delimiter is not None: pattern.value_delimiter = value_delimiter # Add pattern to graph fgraph.add_vertex(pattern.name) rgraph.add_vertex(pattern.name) for flag in pattern.flags: if flag in flags: raise Scheme.ShortFlagIsNotUnique( 'Short flag is used more than once: ' '{!r}'.format(flag)) flags[flag] = pattern # Build graph edges for name, pattern in patterns.items(): # If pattern is a context, create edges to its members for member in pattern._members: # If member is an Pattern instance if isinstance(member, Pattern): fgraph.add_edge(name, member.name) rgraph.add_edge(member.name, name) # If member is a string-name reference elif isinstance(member, str): # If member is not a real reference if member not in patterns: raise Scheme.InvalidMemberReference(member) fgraph.add_edge(name, member) rgraph.add_edge(member, name) # If member is not a Pattern nor a string else: raise Scheme.InvalidPatternMember( "Type of members of Pattern {!r} " "should be 'str' or 'Pattern' not " "{.__class__.__qualname__!r}".format(name, member)) # Build context hierarchy self._hierarchy = hierarchy = {} try: for vertex in topo_sort(fgraph, tracking=True): # If vertex doesn't have parent(s) if not rgraph.vertex(vertex.id).vertices(): # Build its branch hierarchy[vertex.id] = Scheme._branch(vertex) # If there are circular references in the graph except DAGCycleError as message: raise Scheme.CircularReferences(message.args) from None