• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Qiskit / qiskit / 15679872734

16 Jun 2025 11:44AM CUT coverage: 87.998%. First build
15679872734

Pull #14585

github

web-flow
Merge 9f77ec64d into 4d7d46ebc
Pull Request #14585: Raising an error when an invalid PauliEvolutionGate is constructed

8 of 8 new or added lines in 1 file covered. (100.0%)

83165 of 94508 relevant lines covered (88.0%)

516555.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/crates/circuit/src/dot_utils.rs
1
// This code is part of Qiskit.
2
//
3
// (C) Copyright IBM 2022
4
//
5
// This code is licensed under the Apache License, Version 2.0. You may
6
// obtain a copy of this license in the LICENSE.txt file in the root directory
7
// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
//
9
// Any modifications or derivative works of this code must retain this
10
// copyright notice, and modified files need to carry a notice indicating
11
// that they have been altered from the originals.
12

13
// This module is forked from rustworkx at:
14
// https://github.com/Qiskit/rustworkx/blob/c4256daf96fc3c08c392450ed33bc0987cdb15ff/src/dot_utils.rs
15
// and has been modified to generate a dot file from a Rust DAGCircuit instead
16
// of a rustworkx PyGraph object
17

18
use std::collections::BTreeMap;
19
use std::io::prelude::*;
20

21
use crate::dag_circuit::{DAGCircuit, Wire};
22
use pyo3::prelude::*;
23
use pyo3::IntoPyObjectExt;
24
use rustworkx_core::petgraph::visit::{
25
    EdgeRef, IntoEdgeReferences, IntoNodeReferences, NodeIndexable, NodeRef,
26
};
27

28
static TYPE: [&str; 2] = ["graph", "digraph"];
29
static EDGE: [&str; 2] = ["--", "->"];
30

31
pub fn build_dot<T>(
×
32
    py: Python,
×
33
    dag: &DAGCircuit,
×
34
    file: &mut T,
×
35
    graph_attrs: Option<BTreeMap<String, String>>,
×
36
    node_attrs: Option<PyObject>,
×
37
    edge_attrs: Option<PyObject>,
×
38
) -> PyResult<()>
×
39
where
×
40
    T: Write,
×
41
{
×
42
    let graph = dag.dag();
×
43
    writeln!(file, "{} {{", TYPE[graph.is_directed() as usize])?;
×
44
    if let Some(graph_attr_map) = graph_attrs {
×
45
        for (key, value) in graph_attr_map.iter() {
×
46
            writeln!(file, "{}={} ;", key, value)?;
×
47
        }
48
    }
×
49

50
    for node in graph.node_references() {
×
51
        let node_weight = dag.get_node(py, node.id())?;
×
52
        writeln!(
×
53
            file,
×
54
            "{} {};",
×
55
            graph.to_index(node.id()),
×
56
            attr_map_to_string(py, node_attrs.as_ref(), node_weight)?
×
57
        )?;
×
58
    }
59
    for edge in graph.edge_references() {
×
60
        let edge_weight = match edge.weight() {
×
61
            Wire::Qubit(qubit) => dag.qubits().get(*qubit).cloned().into_bound_py_any(py)?,
×
62
            Wire::Clbit(clbit) => dag.clbits().get(*clbit).cloned().into_bound_py_any(py)?,
×
63
            Wire::Var(var) => dag.vars().get(*var).cloned().into_bound_py_any(py)?,
×
64
        };
65
        writeln!(
×
66
            file,
×
67
            "{} {} {} {};",
×
68
            graph.to_index(edge.source()),
×
69
            EDGE[graph.is_directed() as usize],
×
70
            graph.to_index(edge.target()),
×
71
            attr_map_to_string(py, edge_attrs.as_ref(), edge_weight)?
×
72
        )?;
×
73
    }
74
    writeln!(file, "}}")?;
×
75
    Ok(())
×
76
}
×
77

78
static ATTRS_TO_ESCAPE: [&str; 2] = ["label", "tooltip"];
79

80
/// Convert an attr map to an output string
81
fn attr_map_to_string<'py, T: IntoPyObject<'py>>(
×
82
    py: Python<'py>,
×
83
    attrs: Option<&'py PyObject>,
×
84
    weight: T,
×
85
) -> PyResult<String>
×
86
where
×
87
    <T as pyo3::IntoPyObject<'py>>::Output: pyo3::IntoPyObject<'py>,
×
88
    <T as pyo3::IntoPyObject<'py>>::Error: std::fmt::Debug,
×
89
{
×
90
    if attrs.is_none() {
×
91
        return Ok("".to_string());
×
92
    }
×
93
    let attr_callable = |node: T| -> PyResult<BTreeMap<String, String>> {
×
94
        let res = attrs
×
95
            .unwrap()
×
96
            .call1(py, (node.into_pyobject(py).unwrap(),))?;
×
97
        res.extract(py)
×
98
    };
×
99

100
    let attrs = attr_callable(weight)?;
×
101
    if attrs.is_empty() {
×
102
        return Ok("".to_string());
×
103
    }
×
104
    let attr_string = attrs
×
105
        .iter()
×
106
        .map(|(key, value)| {
×
107
            if ATTRS_TO_ESCAPE.contains(&key.as_str()) {
×
108
                format!("{}=\"{}\"", key, value)
×
109
            } else {
110
                format!("{}={}", key, value)
×
111
            }
112
        })
×
113
        .collect::<Vec<String>>()
×
114
        .join(", ");
×
115
    Ok(format!("[{}]", attr_string))
×
116
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc