devstate.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. from .pystate import PyState
  2. class DevState(PyState):
  3. """
  4. Version of PyState that allows dumping to .dot files
  5. + node id's are generated sequentially to make writing tests easier
  6. """
  7. free_id = 0
  8. def __init__(self):
  9. super().__init__()
  10. @staticmethod
  11. def new_id() -> str:
  12. DevState.free_id += 1
  13. return str(DevState.free_id - 1)
  14. def dump(self, path: str, png_path: str = None):
  15. """Dumps the whole MV graph to a graphviz .dot-file
  16. Args:
  17. path (str): path for .dot-file
  18. png_path (str, optional): path for .png image generated from the .dot-file. Defaults to None.
  19. """
  20. with open(path, "w") as f:
  21. f.write("digraph main {\n")
  22. for n in sorted(self.nodes):
  23. if n in self.values:
  24. x = self.values[n]
  25. if isinstance(x, dict):
  26. x = f"{x.get('type')}"
  27. f.write("\"a_%s\" [label=\"%s\"];\n" % (
  28. n, str(x).replace('"', '\\"')))
  29. else:
  30. f.write("\"a_%s\" [label=\"\"];\n" % n)
  31. for i, e in sorted(list(self.edges.items())):
  32. f.write("\"a_%s\" [label=\"e_%s\" shape=point];\n" % (i, i))
  33. f.write("\"a_%s\" -> \"a_%s\" [arrowhead=none];\n" % (e[0], i))
  34. f.write("\"a_%s\" -> \"a_%s\";\n" % (i, e[1]))
  35. f.write("}")
  36. if png_path is not None:
  37. # generate png from dot-file
  38. bashCommand = f"dot -Tpng {path} -o {png_path}"
  39. import subprocess
  40. process = subprocess.Popen(
  41. bashCommand.split(), stdout=subprocess.PIPE)
  42. output, error = process.communicate()