(self, node_or_edge, xml_obj, data, default)
| 443 | graph_element.append(edges_element) |
| 444 | |
| 445 | def add_attributes(self, node_or_edge, xml_obj, data, default): |
| 446 | # Add attrvalues to node or edge |
| 447 | attvalues = Element("attvalues") |
| 448 | if len(data) == 0: |
| 449 | return data |
| 450 | mode = "static" |
| 451 | for k, v in data.items(): |
| 452 | # rename generic multigraph key to avoid any name conflict |
| 453 | if k == "key": |
| 454 | k = "easygraph_key" |
| 455 | val_type = type(v) |
| 456 | if val_type not in self.xml_type: |
| 457 | raise TypeError(f"attribute value type is not allowed: {val_type}") |
| 458 | if isinstance(v, list): |
| 459 | # dynamic data |
| 460 | for val, start, end in v: |
| 461 | val_type = type(val) |
| 462 | if start is not None or end is not None: |
| 463 | mode = "dynamic" |
| 464 | self.alter_graph_mode_timeformat(start) |
| 465 | self.alter_graph_mode_timeformat(end) |
| 466 | break |
| 467 | attr_id = self.get_attr_id( |
| 468 | str(k), self.xml_type[val_type], node_or_edge, default, mode |
| 469 | ) |
| 470 | for val, start, end in v: |
| 471 | e = Element("attvalue") |
| 472 | e.attrib["for"] = attr_id |
| 473 | e.attrib["value"] = str(val) |
| 474 | # Handle nan, inf, -inf differently |
| 475 | if val_type == float: |
| 476 | if e.attrib["value"] == "inf": |
| 477 | e.attrib["value"] = "INF" |
| 478 | elif e.attrib["value"] == "nan": |
| 479 | e.attrib["value"] = "NaN" |
| 480 | elif e.attrib["value"] == "-inf": |
| 481 | e.attrib["value"] = "-INF" |
| 482 | if start is not None: |
| 483 | e.attrib["start"] = str(start) |
| 484 | if end is not None: |
| 485 | e.attrib["end"] = str(end) |
| 486 | attvalues.append(e) |
| 487 | else: |
| 488 | # static data |
| 489 | mode = "static" |
| 490 | attr_id = self.get_attr_id( |
| 491 | str(k), self.xml_type[val_type], node_or_edge, default, mode |
| 492 | ) |
| 493 | e = Element("attvalue") |
| 494 | e.attrib["for"] = attr_id |
| 495 | if isinstance(v, bool): |
| 496 | e.attrib["value"] = str(v).lower() |
| 497 | else: |
| 498 | e.attrib["value"] = str(v) |
| 499 | # Handle float nan, inf, -inf differently |
| 500 | if val_type == float: |
| 501 | if e.attrib["value"] == "inf": |
| 502 | e.attrib["value"] = "INF" |
no test coverage detected