Details
-
Bug
-
Resolution: Unresolved
-
P3: Somewhat important
-
None
-
6.2.0, 6.3.2
-
None
-
Linux
Python 3.10
PySide6 6.3.2
PySide6 6.3.1
PySide6 6.2.0
Description
I've been using a table model with a sort/filter model in PySide6 and ran into a problem where integers are sorted incorrectly, and somewhat unpredictably.
It looks like the sorting problem occurs on the C++ side, in the following function:
... bool QAbstractItemModelPrivate::isVariantLessThan(const QVariant &left, const QVariant &right, ... switch (left.userType()) { case QMetaType::Int: return left.toInt() < right.toInt(); case QMetaType::UInt: return left.toUInt() < right.toUInt(); case QMetaType::LongLong: return left.toLongLong() < right.toLongLong(); case QMetaType::ULongLong: return left.toULongLong() < right.toULongLong(); ...
Adding some print debugging to the Python side, it first looked like an obvious case of everything being compared as signed 32-bit integers:
left: 690636980 0x292a48b4 c_int(690636980) c_long(690636980) right: 2885968800 0xac0463a0 c_int(-1408998496) c_long(2885968800) l < r: False left: 15471165 0xec123d c_int(15471165) c_long(15471165) right: 2346638763 0x8bdeddab c_int(-1948328533) c_long(2346638763) l < r: False
However, as I mentioned the sorting being unpredictable, other values seemed to be compared correctly:
left: 2754875217 0xa4340f51 c_int(-1540092079) c_long(2754875217) right: 1983291963 0x7636a23b c_int(1983291963) c_long(1983291963) l < r: False left: 2346638763 0x8bdeddab c_int(-1948328533) c_long(2346638763) right: 11220746 0xab370a c_int(11220746) c_long(11220746) l < r: False
Looking back at the C++ code, I realized the switch only checks "left.userType()", so the issue seems to be that when the left value is small enough to fit into a signed 32-bit integer, the larger value accidentally gets converted to one as well.
I haven't used Qt in C++ and don't know how QVariants behave there, but I'm guessing you'll be more aware of your integer types and there's no implicit conversion like this, so I'm reporting this as a PySide/Shiboken bug.
I've attached a small example which should demonstrate the issue in a table view. I commented out the print statements (lines 44-53) since the output is somewhat verbose, but they're there just in case.
I originally spotted the issue with PySide 6.3.1 and confirmed it with 6.3.2. I also downgraded to 6.2.0 and the same thing occurs, so it doesn't seem to be a recent regression.
I realize there's an easy workaround by just doing your own sorting in lessThan() and avoiding the C++ calls altogether, but it feels like a "gotcha" for integers which aren't anywhere near breaking 64-bit limits.
Attachments
Issue Links
- relates to
-
PYSIDE-1250 Default QItemEditorFactory doesn't create QSpinBox when creating editor for a integer, creates QLineEdit instead
- Closed
-
PYSIDE-1904 Missing QVariant/QMetaType API to specify type of QDBusArgument
- Reported