Uploaded image for project: 'Qt for Python'
  1. Qt for Python
  2. PYSIDE-2672

Ambiguity in Implicit Conversion Overloads for QDeadlineTimer Across Python and C++

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • Not Evaluated
    • None
    • 6.x
    • Type hints
    • None
    • All

    Description

      The generation of implicit conversions at dt2: Union[PySide6.QtCore.QDeadlineTimer, PySide6.QtCore.QDeadlineTimer.ForeverConstant, int] is creating possibly an unnecessary overlapping overload from the Python (type hinting) POV. In the C++ POV, when the compiler performs overload resolution among overloaded functions that accept different types — like `QDeadlineTimer` or `QDeadlineTimer.ForeverConstant` or `qint64` — it will first try to find a match that requires no conversion or the least costly conversion from the arguments type to the parameter type of the functions. If there is a direct match, meaning one of the overloads takes an argument of exactly the same type as what is passed, that overload is selected without considering other potential conversions. Conversions that are marked as `explicit` are not considered by the compiler for automatic implicit conversion during overload resolution. And in the case of a `QDeadlineTimer` argument, `QDeadlineTimer.ForeverConstant` is an allowed implicit conversion, but `qint64` is not because its constructor is marked as `explicit`. So `int` should be removed from the `Union` type in the Python stubs. At least that's my reasoning... This shows up in other places, not just PySide6.QtCore.QDeadlineTimer, in the Python stubs. Perhaps `CppGenerator::signatureParameter` implicit conversions detection in shiboken generator should be refined?

      QtCore.pyi:

      class QDeadlineTimer(Shiboken.Object):
          @overload
          def __sub__(self, msecs: int, /) -> PySide6.QtCore.QDeadlineTimer: ...
          @overload
          def __sub__(self, dt2: Union[PySide6.QtCore.QDeadlineTimer, PySide6.QtCore.QDeadlineTimer.ForeverConstant, int], /) -> int: ...

       

      qdeadlinetimer_wrapper.cpp:

          // Overloaded function decisor
          // 0: QDeadlineTimer::operator-(QDeadlineTimer)->qint64
          // 1: QDeadlineTimer::operator-(qint64)->QDeadlineTimer
          if (!isReverse
              && (pythonToCpp = Shiboken::Conversions::pythonToCppConversion(Shiboken::Conversions::PrimitiveTypeConverter<qint64>(), (pyArg)))) {
              overloadId = 1; // operator-(QDeadlineTimer,qint64)
          } else if (!isReverse
              && (pythonToCpp = Shiboken::Conversions::pythonToCppValueConversion(SbkPySide6_QtCoreTypes[SBK_QDEADLINETIMER_IDX], (pyArg)))) {
              overloadId = 0; // operator-(QDeadlineTimer,QDeadlineTimer)
          }

       

      qdeadlinetimer.h:

      class Q_CORE_EXPORT QDeadlineTimer
      {
      public:
          enum class ForeverConstant { Forever };
          static constexpr ForeverConstant Forever = ForeverConstant::Forever;
          constexpr QDeadlineTimer() noexcept = default;
          constexpr QDeadlineTimer(ForeverConstant, Qt::TimerType type_ = Qt::CoarseTimer) noexcept
              : t1((std::numeric_limits<qint64>::max)()), type(type_) {}
          explicit QDeadlineTimer(qint64 msecs, Qt::TimerType type = Qt::CoarseTimer) noexcept;
          friend QDeadlineTimer operator-(QDeadlineTimer dt, qint64 msecs)
          { return dt + (-msecs); }
          friend qint64 operator-(QDeadlineTimer dt1, QDeadlineTimer dt2)
          { return (dt1.deadlineNSecs() - dt2.deadlineNSecs()) / (1000 * 1000); }
      

       

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            ctismer Christian Tismer
            fboni Francisco Boni Neto
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes