Completed
Branch master (6f2cba)
by Gonzalo
01:09
created

test_patched_qcombobox()   F

Complexity

Conditions 21

Size

Total Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
cc 21
c 6
b 0
f 0
dl 0
loc 56
rs 3.4405

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like test_patched_qcombobox() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
from __future__ import absolute_import
2
3
from qtpy import QtGui, QtWidgets
4
5
6
def get_qapp(icon_path=None):
7
    qapp = QtWidgets.QApplication.instance()
8
    if qapp is None:
9
        qapp = QtWidgets.QApplication([''])
10
    return qapp
11
12
13
class Data(object):
14
    """
15
    Test class to store in userData. The __getitem__ is needed in order to
16
    reproduce the segmentation fault.
17
    """
18
    def __getitem__(self, item):
19
        raise ValueError("Failing")
20
21
22
def test_patched_qcombobox():
23
    """
24
    In PySide, using Python objects as userData in QComboBox causes
25
    Segmentation faults under certain conditions. Even in cases where it
26
    doesn't, findData does not work correctly. Likewise, findData also
27
    does not work correctly with Python objects when using PyQt4. On the
28
    other hand, PyQt5 deals with this case correctly. We therefore patch
29
    QComboBox when using PyQt4 and PySide to avoid issues.
30
    """
31
32
    app = get_qapp()
33
34
    data1 = Data()
35
    data2 = Data()
36
    data3 = Data()
37
    data4 = Data()
38
    data5 = Data()
39
    data6 = Data()
40
41
    icon1 = QtGui.QIcon()
42
    icon2 = QtGui.QIcon()
43
44
    widget = QtWidgets.QComboBox()
45
    widget.addItem('a', data1)
46
    widget.insertItem(0, 'b', data2)
47
    widget.addItem('c', data1)
48
    widget.setItemData(2, data3)
49
    widget.addItem(icon1, 'd', data4)
50
    widget.insertItem(3, icon2, 'e', data5)
51
    widget.addItem(icon1, 'f')
52
    widget.insertItem(5, icon2, 'g')
53
54
    widget.show()
55
56
    assert widget.findData(data1) == 1
57
    assert widget.findData(data2) == 0
58
    assert widget.findData(data3) == 2
59
    assert widget.findData(data4) == 4
60
    assert widget.findData(data5) == 3
61
    assert widget.findData(data6) == -1
62
63
    assert widget.itemData(0) == data2
64
    assert widget.itemData(1) == data1
65
    assert widget.itemData(2) == data3
66
    assert widget.itemData(3) == data5
67
    assert widget.itemData(4) == data4
68
    assert widget.itemData(5) is None
69
    assert widget.itemData(6) is None
70
71
    assert widget.itemText(0) == 'b'
72
    assert widget.itemText(1) == 'a'
73
    assert widget.itemText(2) == 'c'
74
    assert widget.itemText(3) == 'e'
75
    assert widget.itemText(4) == 'd'
76
    assert widget.itemText(5) == 'g'
77
    assert widget.itemText(6) == 'f'
78
79
80
def test_model_item():
81
    """
82
    This is a regression test for an issue that caused the call to item(0)
83
    below to trigger segmentation faults in PySide. The issue is
84
    non-deterministic when running the call once, so we include a loop to make
85
    sure that we trigger the fault.
86
    """
87
    app = get_qapp()
88
    combo = QtWidgets.QComboBox()
89
    label_data = [('a', None)]
90
    for iter in range(10000):
91
        combo.clear()
92
        for i, (label, data) in enumerate(label_data):
93
            combo.addItem(label, userData=data)
94
        model = combo.model()
95
        model.item(0)
96