Skip to content

Bug related to importing sequence with PyQt5 and ortools Python #4869

@ThomasMHCheng

Description

@ThomasMHCheng

What version of OR-Tools and what language are you using?
Version: 9.14.6206.
Language: Python

Which solver are you using (e.g. CP-SAT, Routing Solver, GLOP, BOP, Gurobi)
CP-SAT

What operating system (Linux, Windows, ...) and version?
Microsoft Windows 11

What did you do?
Steps to reproduce the behavior:

  1. Produce two python file, A.py and L.py
    A.py:
def a():
    """Simple CP model solving example"""
    print("Starting to solve...")
    
    # Create model
    model = cp_model.CpModel()
    
    # Create variables
    x = model.NewIntVar(0, 10, 'x')
    y = model.NewIntVar(0, 10, 'y')
    
    # Add constraints
    model.Add(x + y == 10)
    model.Add(x - y >= 2)
    
    # Set objective function
    model.Maximize(x + 2 * y)
    
    # Solve
    print("Solver")
    solver = cp_model.CpSolver()
    print("Solving...")
    status = solver.Solve(model)
    
    if status == cp_model.OPTIMAL:
        print(f"Solved successfully: x = {solver.Value(x)}, y = {solver.Value(y)}")
        print(f"Objective value: {solver.ObjectiveValue()}")
    else:
        print("Solving failed")
    
    return status == cp_model.OPTIMAL

if __name__ == "__main__":
    a()

L.py:

# Bug-causing way: import PyQt5 first, then A
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget
import sys

import A # ②This will cause issues - unless A is imported before PyQt5

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Test Window")
        self.setGeometry(100, 100, 300, 200)
        
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        layout = QVBoxLayout()
        
        self.solve_button = QPushButton("Run Solver")
        self.solve_button.clicked.connect(self.run_solver)
        layout.addWidget(self.solve_button)
        
        central_widget.setLayout(layout)
    
    def run_solver(self):
        print("Solver button clicked")
        try:
            # Call function from A file
            success = A.a()
            if success:
                print("Solver completed!")
            else:
                print("Solver failed!")
        except Exception as e:
            print(f"Error during solving: {e}")

if __name__ == '__main__':
    
    # Run solver once
    print("Calling solver function a...")
    try:
        A.a()
    except Exception as e:
        print(f"Automatic solving failed: {e}")

    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    
    sys.exit(app.exec_())
  1. Change the "import A" position at the beginning of L.py, and run L.py once each.
  2. See the result

What did you expect to see
Runing L.py with the proper import sequence

import A # ①Import order that won't cause bugs: import A first, then PyQt5

# Bug-causing way: import PyQt5 first, then A
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget
import sys

# import A # ②This will cause issues - unless A is imported before PyQt5

and click the "Run Solver" PyQt5 UI button once, the terminal will display such result:

Calling solver function a...
Starting to solve...
Solver
Solving...
Solved successfully: x = 6, y = 4
Objective value: 14.0
Solver button clicked
Starting to solve...
Solver
Solver
Solver
Solving...
Solved successfully: x = 6, y = 4
Objective value: 14.0
Solver completed!

What did you see instead?
Runing L.py with the improper import sequence:

# import A # ①Import order that won't cause bugs: import A first, then PyQt5

# Bug-causing way: import PyQt5 first, then A
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget
import sys

import A # ②This will cause issues - unless A is imported before PyQt5

The terminal will print

Calling solver function a...
Starting to solve...
Solver
Solving...

and then just quit without result solved, Qt UI appeared or error raised.

Make sure you include information that can help us debug (full error message, model Proto).

Anything else we should know about your project / environment

PyQt5                     5.15.11
PyQt5-Qt5                 5.15.2
PyQt5_sip                 12.17.1

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions