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

Qiskit / qiskit / 13113828581

03 Feb 2025 12:47PM UTC coverage: 88.976% (+0.1%) from 88.827%
13113828581

Pull #13769

github

web-flow
Merge 26516179c into d03a61e09
Pull Request #13769: Remove dependance of `BooleanExpression` on `tweedledum`

180 of 184 new or added lines in 5 files covered. (97.83%)

12 existing lines in 3 files now uncovered.

80025 of 89940 relevant lines covered (88.98%)

347268.97 hits per line

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

97.5
/qiskit/circuit/classicalfunction/boolean_expression_visitor.py
1
# This code is part of Qiskit.
2
#
3
# (C) Copyright IBM 2025.
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
"""Node visitor as defined in https://docs.python.org/3/library/ast.html#ast.NodeVisitor
14
This module is used internally by ``qiskit.transpiler.classicalfunction.BooleanExpression``.
15
"""
16

17
import ast
1✔
18
import _ast
1✔
19

20
from .exceptions import BooleanExpressionParseError
1✔
21

22

23
class BooleanExpressionEvalVisitor(ast.NodeVisitor):
1✔
24
    """Node visitor to compute the value of the expression, given the boolean values of the args
25
    as defined in https://docs.python.org/3/library/ast.html#ast.NodeVisitor"""
26

27
    # pylint: disable=invalid-name
28
    bitops = {
1✔
29
        _ast.BitAnd: lambda values: values[0] and values[1],
30
        _ast.And: lambda values: values[0] and values[1],
31
        _ast.BitOr: lambda values: values[0] or values[1],
32
        _ast.Or: lambda values: values[0] or values[1],
33
        _ast.BitXor: lambda values: values[0] ^ values[1],
34
        _ast.Not: lambda values: not values[0],
35
        _ast.Invert: lambda values: not values[0],
36
    }
37

38
    def __init__(self):
1✔
39
        self.arg_values = {}
1✔
40
        super().__init__()
1✔
41

42
    def bit_binop(self, op, values):
1✔
43
        """Performs the operation, if it is recognized"""
44
        op_type = type(op)
1✔
45
        if op_type not in self.bitops:
1✔
46
            raise BooleanExpressionParseError(f"Unknown op: {op_type}")
1✔
47
        return self.bitops[op_type](values)
1✔
48

49
    def visit_BinOp(self, node):
1✔
50
        """Handles ``&``, ``^``, and ``|``."""
51
        return self.bit_binop(node.op, [self.visit(node.left), self.visit(node.right)])
1✔
52

53
    def visit_UnaryOp(self, node):
1✔
54
        """Handles ``~``."""
55
        return self.bit_binop(node.op, [self.visit(node.operand)])
1✔
56

57
    def visit_Name(self, node):
1✔
58
        """Reduce variable names."""
59
        if node.id not in self.arg_values:
1✔
60
            raise BooleanExpressionParseError(f"Undefined value for {node.id}")
1✔
61
        return self.arg_values[node.id]
1✔
62

63
    def visit_Module(self, node):
1✔
64
        """Returns the value of the single expression comprising the boolean expression"""
65
        if len(node.body) != 1 or not isinstance(node.body[0], ast.Expr):
1✔
66
            raise BooleanExpressionParseError("Incorrectly formatted boolean expression")
1✔
67
        return self.visit(node.body[0])
1✔
68

69
    def visit_Expr(self, node):
1✔
70
        """Returns the value of the expression"""
71
        return self.visit(node.value)
1✔
72

73
    def generic_visit(self, node):
1✔
74
        """Catch all for the unhandled nodes."""
NEW
75
        raise BooleanExpressionParseError(f"Unknown node: {type(node)}")
×
76

77

78
class BooleanExpressionArgsCollectorVisitor(ast.NodeVisitor):
1✔
79
    """Node visitor to collect the name of the args of the expression
80
    as defined in https://docs.python.org/3/library/ast.html#ast.NodeVisitor"""
81

82
    # pylint: disable=invalid-name
83
    def __init__(self):
1✔
84
        self.args = set()
1✔
85
        self.args_pos = {}
1✔
86
        super().__init__()
1✔
87

88
    def visit_Name(self, node):
1✔
89
        """Collect arg name."""
90
        self.args.add(node.id)
1✔
91
        if node.id not in self.args_pos or (
1✔
92
            self.args_pos[node.id] > (node.lineno, node.col_offset)
93
        ):
94
            self.args_pos[node.id] = (node.lineno, node.col_offset)
1✔
95

96
    def get_sorted_args(self):
1✔
97
        """Returns a list of the args, sorted by their appearance locations"""
98
        return sorted(self.args, key=lambda arg: self.args_pos[arg])
1✔
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

© 2026 Coveralls, Inc