Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Infinite loop] Failed to Converge After 100 Iterations When Fixing Imports (e.g., I001, F401, F811) #15182

Open
brupelo opened this issue Dec 29, 2024 · 5 comments
Labels
fixes Related to suggested fixes for violations

Comments

@brupelo
Copy link

brupelo commented Dec 29, 2024

Consider this snippet:

mcve.py
from PySide6 import __version__ as QT_VERSION_STR

from PySide6.QtCore import (
    ClassInfo,
    MetaFunction,
    MetaSignal,
    Property,
    PyClassProperty,
    QAbstractAnimation,
    QAbstractAnimation,
    QAbstractEventDispatcher,
    QAbstractEventDispatcher,
    QAbstractItemModel,
    QAbstractItemModel,
    QAbstractListModel,
    QAbstractListModel,
    QAbstractNativeEventFilter,
    QAbstractNativeEventFilter,
    QAbstractProxyModel,
    QAbstractProxyModel,
    QAbstractTableModel,
    QAbstractTableModel,
    QAnimationGroup,
    QAnimationGroup,
    QBasicMutex,
    QBasicMutex,
    QBasicTimer,
    QBasicTimer,
    QBitArray,
    QBitArray,
    QBluetoothPermission,
    QBluetoothPermission,
    QBuffer,
    QBuffer,
    QByteArray,
    QByteArray,
    QByteArrayMatcher,
    QByteArrayMatcher,
    QCalendar,
    QCalendar,
    QCalendarPermission,
    QCalendarPermission,
    QCameraPermission,
    QCameraPermission,
    QCborArray,
    QCborArray,
    QCborError,
    QCborError,
    QCborKnownTags,
    QCborMap,
    QCborMap,
    QCborParserError,
    QCborParserError,
    QCborSimpleType,
    QCborStreamReader,
    QCborStreamReader,
    QCborStreamWriter,
    QCborStreamWriter,
    QCborStringResultByteArray,
    QCborStringResultByteArray,
    QCborStringResultString,
    QCborStringResultString,
    QCborTag,
    QCborValue,
    QCborValue,
    QChildEvent,
    QChildEvent,
    QCollator,
    QCollator,
    QCollatorSortKey,
    QCollatorSortKey,
    QCommandLineOption,
    QCommandLineOption,
    QCommandLineParser,
    QCommandLineParser,
    QConcatenateTablesProxyModel,
    QConcatenateTablesProxyModel,
    QContactsPermission,
    QContactsPermission,
    QCoreApplication,
    QCoreApplication,
    QCryptographicHash,
    QCryptographicHash,
    QDataStream,
    QDataStream,
    QDate,
    QDate,
    QDateTime,
    QDateTime,
    QDeadlineTimer,
    QDeadlineTimer,
    QDir,
    QDir,
    QDirIterator,
    QDirIterator,
    QDynamicPropertyChangeEvent,
    QDynamicPropertyChangeEvent,
    QEasingCurve,
    QEasingCurve,
    QElapsedTimer,
    QElapsedTimer,
    QEnum,
    QEvent,
    QEvent,
    QEventLoop,
    QEventLoop,
    QFactoryInterface,
    QFactoryInterface,
    QFile,
    QFile,
    QFileDevice,
    QFileDevice,
    QFileInfo,
    QFileInfo,
    QFileSelector,
    QFileSelector,
    QFileSystemWatcher,
    QFileSystemWatcher,
    QFlag,
    QFutureInterfaceBase,
    QFutureInterfaceBase,
    QGenericArgument,
    QGenericArgument,
    QGenericArgumentHolder,
    QGenericArgumentHolder,
    QGenericReturnArgument,
    QGenericReturnArgument,
    QGenericReturnArgumentHolder,
    QGenericReturnArgumentHolder,
    QHashSeed,
    QHashSeed,
    QIODevice,
    QIODevice,
    QIODeviceBase,
    QIODeviceBase,
    QIOPipe,
    QIOPipe,
    QIdentityProxyModel,
    QIdentityProxyModel,
    QIntList,
    QItemSelection,
    QItemSelection,
    QItemSelectionModel,
    QItemSelectionModel,
    QItemSelectionRange,
    QItemSelectionRange,
    QJsonArray,
    QJsonArray,
    QJsonDocument,
    QJsonDocument,
    QJsonParseError,
    QJsonParseError,
    QJsonValue,
    QJsonValue,
    QKeyCombination,
    QKeyCombination,
    QLibrary,
    QLibrary,
    QLibraryInfo,
    QLibraryInfo,
    QLine,
    QLine,
    QLineF,
    QLineF,
    QLocale,
    QLocale,
    QLocationPermission,
    QLocationPermission,
    QLockFile,
    QLockFile,
    QLoggingCategory,
    QLoggingCategory,
    QMargins,
    QMargins,
    QMarginsF,
    QMarginsF,
    QMessageAuthenticationCode,
    QMessageAuthenticationCode,
    QMessageLogContext,
    QMessageLogContext,
    QMetaClassInfo,
    QMetaClassInfo,
    QMetaEnum,
    QMetaEnum,
    QMetaMethod,
    QMetaMethod,
    QMetaObject,
    QMetaObject,
    QMetaProperty,
    QMetaProperty,
    QMetaType,
    QMetaType,
    QMicrophonePermission,
    QMicrophonePermission,
    QMimeData,
    QMimeData,
    QMimeDatabase,
    QMimeDatabase,
    QMimeType,
    QMimeType,
    QModelIndex,
    QModelIndex,
    QModelRoleData,
    QModelRoleData,
    QMutex,
    QMutex,
    QMutexLocker,
    QMutexLocker,
    QNativeIpcKey,
    QNativeIpcKey,
    QObject,
    QObject,
    QOperatingSystemVersion,
    QOperatingSystemVersion,
    QOperatingSystemVersionBase,
    QOperatingSystemVersionBase,
    QParallelAnimationGroup,
    QParallelAnimationGroup,
    QPauseAnimation,
    QPauseAnimation,
    QPermission,
    QPermission,
    QPersistentModelIndex,
    QPersistentModelIndex,
    QPluginLoader,
    QPluginLoader,
    QPoint,
    QPoint,
    QPointF,
    QPointF,
    QPointFList,
    QPointList,
    QProcess,
    QProcess,
    QProcessEnvironment,
    QProcessEnvironment,
    QPropertyAnimation,
    QPropertyAnimation,
    QRandomGenerator,
    QRandomGenerator,
    QRandomGenerator64,
    QRandomGenerator64,
    QReadLocker,
    QReadLocker,
    QReadWriteLock,
    QReadWriteLock,
    QRect,
    QRect,
    QRectF,
    QRectF,
    QRecursiveMutex,
    QRecursiveMutex,
    QRegularExpression,
    QRegularExpression,
    QRegularExpressionMatch,
    QRegularExpressionMatch,
    QRegularExpressionMatchIterator,
    QRegularExpressionMatchIterator,
    QResource,
    QResource,
    QRunnable,
    QRunnable,
    QSaveFile,
    QSaveFile,
    QSemaphore,
    QSemaphore,
    QSemaphoreReleaser,
    QSemaphoreReleaser,
    QSequentialAnimationGroup,
    QSequentialAnimationGroup,
    QSettings,
    QSettings,
    QSharedMemory,
    QSharedMemory,
    QSignalBlocker,
    QSignalBlocker,
    QSignalMapper,
    QSignalMapper,
    QSize,
    QSize,
    QSizeF,
    QSizeF,
    QSocketDescriptor,
    QSocketDescriptor,
    QSocketNotifier,
    QSocketNotifier,
    QSortFilterProxyModel,
    QSortFilterProxyModel,
    QStandardPaths,
    QStandardPaths,
    QStorageInfo,
    QStorageInfo,
    QStringConverter,
    QStringConverter,
    QStringConverterBase,
    QStringConverterBase,
    QStringDecoder,
    QStringDecoder,
    QStringEncoder,
    QStringEncoder,
    QStringListModel,
    QStringListModel,
    QSysInfo,
    QSysInfo,
    QSystemSemaphore,
    QSystemSemaphore,
    QT_TRANSLATE_NOOP,
    QT_TRANSLATE_NOOP3,
    QT_TRANSLATE_NOOP_UTF8,
    QT_TR_NOOP,
    QT_TR_NOOP_UTF8,
    QTemporaryDir,
    QTemporaryDir,
    QTemporaryFile,
    QTemporaryFile,
    QTextBoundaryFinder,
    QTextBoundaryFinder,
    QTextStream,
    QTextStream,
    QTextStreamManipulator,
    QTextStreamManipulator,
    QThread,
    QThread,
    QThreadPool,
    QThreadPool,
    QTime,
    QTime,
    QTimeLine,
    QTimeLine,
    QTimeZone,
    QTimeZone,
    QTimer,
    QTimer,
    QTimerEvent,
    QTimerEvent,
    QTranslator,
    QTranslator,
    QTransposeProxyModel,
    QTransposeProxyModel,
    QUrl,
    QUrl,
    QUrlQuery,
    QUrlQuery,
    QUuid,
    QUuid,
    QVariantAnimation,
    QVariantAnimation,
    QVersionNumber,
    QVersionNumber,
    QWaitCondition,
    QWaitCondition,
    QWinEventNotifier,
    QWinEventNotifier,
    QWriteLocker,
    QWriteLocker,
    QXmlStreamAttribute,
    QXmlStreamAttribute,
    QXmlStreamAttributes,
    QXmlStreamAttributes,
    QXmlStreamEntityDeclaration,
    QXmlStreamEntityDeclaration,
    QXmlStreamEntityResolver,
    QXmlStreamEntityResolver,
    QXmlStreamNamespaceDeclaration,
    QXmlStreamNamespaceDeclaration,
    QXmlStreamNotationDeclaration,
    QXmlStreamNotationDeclaration,
    QXmlStreamReader,
    QXmlStreamReader,
    QXmlStreamWriter,
    QXmlStreamWriter,
    Q_ARG,
    Q_RETURN_ARG,
    Qt,
    Qt,
    QtMsgType,
    SIGNAL,
    SLOT,
    Signal,
    SignalInstance,
    Slot,
    qAbs,
    qAddPostRoutine,
    qCCritical,
    qCDebug,
    qCInfo,
    qCWarning,
    qCompress,
    qCritical,
    qDebug,
    qFastCos,
    qFastSin,
    qFatal,
    qFormatLogMessage,
    qFuzzyCompare,
    qFuzzyIsNull,
    qInstallMessageHandler,
    qIsFinite,
    qIsInf,
    qIsNaN,
    qIsNull,
    qRegisterResourceData,
    qSetMessagePattern,
    qUncompress,
    qUnregisterResourceData,
    qVersion,
    qWarning,
    qtTrId,
)

from PySide6.QtGui import (
    QAbstractFileIconProvider,
    QAbstractTextDocumentLayout,
    QAccessible,
    QAccessibleActionInterface,
    QAccessibleEditableTextInterface,
    QAccessibleEvent,
    QAccessibleInterface,
    QAccessibleObject,
    QAccessibleStateChangeEvent,
    QAccessibleTableCellInterface,
    QAccessibleTableModelChangeEvent,
    QAccessibleTextCursorEvent,
    QAccessibleTextInsertEvent,
    QAccessibleTextInterface,
    QAccessibleTextRemoveEvent,
    QAccessibleTextSelectionEvent,
    QAccessibleTextUpdateEvent,
    QAccessibleValueChangeEvent,
    QAccessibleValueInterface,
    QAction,
    QActionEvent,
    QActionGroup,
    qAlpha,
    QBackingStore,
    QBitmap,
    qBlue,
    QBrush,
    QChildWindowEvent,
    QClipboard,
    QCloseEvent,
    QColor,
    QColorConstants,
    QColorSpace,
    QColorTransform,
    QConicalGradient,
    QContextMenuEvent,
    QCursor,
    QDesktopServices,
    QDoubleValidator,
    QDrag,
    QDragEnterEvent,
    QDragLeaveEvent,
    QDragMoveEvent,
    QDropEvent,
    QEnterEvent,
    QEventPoint,
    QExposeEvent,
    QFileOpenEvent,
    QFocusEvent,
    QFont,
    QFontDatabase,
    QFontInfo,
    QFontMetrics,
    QFontMetricsF,
    qFuzzyCompare,
    QGlyphRun,
    QGradient,
    qGray,
    qGreen,
    QGuiApplication,
    QHelpEvent,
    QHideEvent,
    QHoverEvent,
    QIcon,
    QIconDragEvent,
    QIconEngine,
    QImage,
    QImageIOHandler,
    QImageReader,
    QImageWriter,
    QInputDevice,
    QInputEvent,
    QInputMethod,
    QInputMethodEvent,
    QInputMethodQueryEvent,
    QIntList,
    QIntValidator,
    qIsGray,
    QKeyEvent,
    QKeySequence,
    QLinearGradient,
    QMatrix2x2,
    QMatrix2x3,
    QMatrix2x4,
    QMatrix3x2,
    QMatrix3x3,
    QMatrix3x4,
    QMatrix4x2,
    QMatrix4x3,
    QMatrix4x4,
    QMouseEvent,
    QMoveEvent,
    QMovie,
    QNativeGestureEvent,
    QNativeInterface,
    QOffscreenSurface,
    QOpenGLContext,
    QOpenGLContextGroup,
    QOpenGLExtraFunctions,
    QOpenGLFunctions,
    QOverrideCursorGuard,
    QPagedPaintDevice,
    QPageLayout,
    QPageRanges,
    QPageSize,
    QPaintDevice,
    QPaintDeviceWindow,
    QPaintEngine,
    QPaintEngineState,
    QPainter,
    QPainterPath,
    QPainterPathStroker,
    QPaintEvent,
    QPalette,
    QPdfWriter,
    QPen,
    QPicture,
    QPixelFormat,
    qPixelFormatAlpha,
    qPixelFormatCmyk,
    qPixelFormatGrayscale,
    qPixelFormatHsl,
    qPixelFormatHsv,
    qPixelFormatRgba,
    qPixelFormatYuv,
    QPixmap,
    QPixmapCache,
    QPlatformSurfaceEvent,
    QPointerEvent,
    QPointFList,
    QPointingDevice,
    QPointingDeviceUniqueId,
    QPointList,
    QPolygon,
    QPolygonF,
    QPyTextObject,
    QQuaternion,
    QRadialGradient,
    QRasterWindow,
    QRawFont,
    qRed,
    QRegion,
    QRegularExpressionValidator,
    QResizeEvent,
    qRgb,
    qRgba,
    QRgba64,
    QRhi,
    QRhiBuffer,
    QRhiColorAttachment,
    QRhiCommandBuffer,
    QRhiComputePipeline,
    QRhiD3D11InitParams,
    QRhiD3D11NativeHandles,
    QRhiD3D12InitParams,
    QRhiD3D12NativeHandles,
    QRhiDepthStencilClearValue,
    QRhiDriverInfo,
    QRhiGles2InitParams,
    QRhiGles2NativeHandles,
    QRhiGraphicsPipeline,
    QRhiInitParams,
    QRhiNativeHandles,
    QRhiNullInitParams,
    QRhiReadbackDescription,
    QRhiReadbackResult,
    QRhiRenderBuffer,
    QRhiRenderPassDescriptor,
    QRhiRenderTarget,
    QRhiResource,
    QRhiResourceUpdateBatch,
    QRhiSampler,
    QRhiScissor,
    QRhiShaderResourceBinding,
    QRhiShaderResourceBindings,
    QRhiShaderStage,
    QRhiStats,
    QRhiSwapChain,
    QRhiSwapChainRenderTarget,
    QRhiTexture,
    QRhiTextureCopyDescription,
    QRhiTextureRenderTarget,
    QRhiTextureRenderTargetDescription,
    QRhiTextureSubresourceUploadDescription,
    QRhiTextureUploadDescription,
    QRhiTextureUploadEntry,
    QRhiVertexInputAttribute,
    QRhiVertexInputBinding,
    QRhiVertexInputLayout,
    QRhiViewport,
    QScreen,
    QScrollEvent,
    QScrollPrepareEvent,
    QSessionManager,
    QShader,
    QShaderCode,
    QShaderKey,
    QShaderVersion,
    QShortcut,
    QShortcutEvent,
    QShowEvent,
    QSinglePointEvent,
    QStandardItem,
    QStandardItemModel,
    QStaticText,
    QStatusTipEvent,
    QStyleHints,
    QSurface,
    QSurfaceFormat,
    QSyntaxHighlighter,
    qt_set_sequence_auto_mnemonic,
    QTabletEvent,
    QTextBlock,
    QTextBlockFormat,
    QTextBlockGroup,
    QTextBlockUserData,
    QTextCharFormat,
    QTextCursor,
    QTextDocument,
    QTextDocumentFragment,
    QTextDocumentWriter,
    QTextFormat,
    QTextFragment,
    QTextFrame,
    QTextFrameFormat,
    QTextImageFormat,
    QTextInlineObject,
    QTextItem,
    QTextLayout,
    QTextLength,
    QTextLine,
    QTextList,
    QTextListFormat,
    QTextObject,
    QTextObjectInterface,
    QTextOption,
    QTextTable,
    QTextTableCell,
    QTextTableCellFormat,
    QTextTableFormat,
    QToolBarChangeEvent,
    QTouchEvent,
    QTransform,
    QUndoCommand,
    QUndoGroup,
    QUndoStack,
    QValidator,
    QVector2D,
    QVector2DList,
    QVector3D,
    QVector3DList,
    QVector4D,
    QVector4DList,
    QWhatsThisClickedEvent,
    QWheelEvent,
    QWindow,
    QWindowStateChangeEvent,
)

from PySide6.QtNetwork import (
    QAbstractNetworkCache,
    QAbstractSocket,
    QAuthenticator,
    QDnsDomainNameRecord,
    QDnsHostAddressRecord,
    QDnsLookup,
    QDnsMailExchangeRecord,
    QDnsServiceRecord,
    QDnsTextRecord,
    QDtls,
    QDtlsClientVerifier,
    QDtlsError,
    QHostAddress,
    QHostInfo,
    QHstsPolicy,
    QHttp1Configuration,
    QHttp2Configuration,
    QHttpHeaders,
    QHttpMultiPart,
    QHttpPart,
    QIntList,
    QIPv6Address,
    QLocalServer,
    QLocalSocket,
    QNetworkAccessManager,
    QNetworkAddressEntry,
    QNetworkCacheMetaData,
    QNetworkCookie,
    QNetworkCookieJar,
    QNetworkDatagram,
    QNetworkDiskCache,
    QNetworkInformation,
    QNetworkInterface,
    QNetworkProxy,
    QNetworkProxyFactory,
    QNetworkProxyQuery,
    QNetworkReply,
    QNetworkRequest,
    QNetworkRequestFactory,
    QOcspCertificateStatus,
    QOcspResponse,
    QOcspRevocationReason,
    QPasswordDigestor,
    QRestAccessManager,
    QRestReply,
    QSsl,
    QSslCertificate,
    QSslCertificateExtension,
    QSslCipher,
    QSslConfiguration,
    QSslDiffieHellmanParameters,
    QSslEllipticCurve,
    QSslError,
    QSslKey,
    QSslPreSharedKeyAuthenticator,
    QSslServer,
    QSslSocket,
    QTcpServer,
    QTcpSocket,
    QUdpSocket,
)

from PySide6.QtOpenGLWidgets import (
    QIntList,
    QOpenGLWidget
)

from PySide6.QtWidgets import (
    QAbstractButton,
    QAbstractGraphicsShapeItem,
    QAbstractItemDelegate,
    QAbstractItemView,
    QAbstractScrollArea,
    QAbstractSlider,
    QAbstractSpinBox,
    QAccessibleWidget,
    QApplication,
    QBoxLayout,
    QButtonGroup,
    QCalendarWidget,
    QCheckBox,
    QColorDialog,
    QColormap,
    QColumnView,
    QComboBox,
    QCommandLinkButton,
    QCommonStyle,
    QCompleter,
    QDataWidgetMapper,
    QDateEdit,
    QDateTimeEdit,
    QDial,
    QDialog,
    QDialogButtonBox,
    QDockWidget,
    QDoubleSpinBox,
    qDrawPlainRect,
    qDrawPlainRoundedRect,
    qDrawShadeLine,
    qDrawShadePanel,
    qDrawShadeRect,
    qDrawWinButton,
    qDrawWinPanel,
    QErrorMessage,
    QFileDialog,
    QFileIconProvider,
    QFileSystemModel,
    QFocusFrame,
    QFontComboBox,
    QFontDialog,
    QFormLayout,
    QFrame,
    QGesture,
    QGestureEvent,
    QGestureRecognizer,
    QGraphicsAnchor,
    QGraphicsAnchorLayout,
    QGraphicsBlurEffect,
    QGraphicsColorizeEffect,
    QGraphicsDropShadowEffect,
    QGraphicsEffect,
    QGraphicsEllipseItem,
    QGraphicsGridLayout,
    QGraphicsItem,
    QGraphicsItemAnimation,
    QGraphicsItemGroup,
    QGraphicsLayout,
    QGraphicsLayoutItem,
    QGraphicsLinearLayout,
    QGraphicsLineItem,
    QGraphicsObject,
    QGraphicsOpacityEffect,
    QGraphicsPathItem,
    QGraphicsPixmapItem,
    QGraphicsPolygonItem,
    QGraphicsProxyWidget,
    QGraphicsRectItem,
    QGraphicsRotation,
    QGraphicsScale,
    QGraphicsScene,
    QGraphicsSceneContextMenuEvent,
    QGraphicsSceneDragDropEvent,
    QGraphicsSceneEvent,
    QGraphicsSceneHelpEvent,
    QGraphicsSceneHoverEvent,
    QGraphicsSceneMouseEvent,
    QGraphicsSceneMoveEvent,
    QGraphicsSceneResizeEvent,
    QGraphicsSceneWheelEvent,
    QGraphicsSimpleTextItem,
    QGraphicsTextItem,
    QGraphicsTransform,
    QGraphicsView,
    QGraphicsWidget,
    QGridLayout,
    QGroupBox,
    QHBoxLayout,
    QHeaderView,
    QInputDialog,
    QIntList,
    QItemDelegate,
    QItemEditorCreatorBase,
    QItemEditorFactory,
    QKeySequenceEdit,
    QLabel,
    QLayout,
    QLayoutItem,
    QLCDNumber,
    QLineEdit,
    QListView,
    QListWidget,
    QListWidgetItem,
    QMainWindow,
    QMdiArea,
    QMdiSubWindow,
    QMenu,
    QMenuBar,
    QMessageBox,
    QPanGesture,
    QPinchGesture,
    QPlainTextDocumentLayout,
    QPlainTextEdit,
    QPointFList,
    QPointList,
    QProgressBar,
    QProgressDialog,
    QProxyStyle,
    QPushButton,
    QRadioButton,
    QRhiWidget,
    QRubberBand,
    QScrollArea,
    QScrollBar,
    QScroller,
    QScrollerProperties,
    QSizeGrip,
    QSizePolicy,
    QSlider,
    QSpacerItem,
    QSpinBox,
    QSplashScreen,
    QSplitter,
    QSplitterHandle,
    QStackedLayout,
    QStackedWidget,
    QStatusBar,
    QStyle,
    QStyledItemDelegate,
    QStyleFactory,
    QStyleHintReturn,
    QStyleHintReturnMask,
    QStyleHintReturnVariant,
    QStyleOption,
    QStyleOptionButton,
    QStyleOptionComboBox,
    QStyleOptionComplex,
    QStyleOptionDockWidget,
    QStyleOptionFocusRect,
    QStyleOptionFrame,
    QStyleOptionGraphicsItem,
    QStyleOptionGroupBox,
    QStyleOptionHeader,
    QStyleOptionHeaderV2,
    QStyleOptionMenuItem,
    QStyleOptionProgressBar,
    QStyleOptionRubberBand,
    QStyleOptionSizeGrip,
    QStyleOptionSlider,
    QStyleOptionSpinBox,
    QStyleOptionTab,
    QStyleOptionTabBarBase,
    QStyleOptionTabWidgetFrame,
    QStyleOptionTitleBar,
    QStyleOptionToolBar,
    QStyleOptionToolBox,
    QStyleOptionToolButton,
    QStyleOptionViewItem,
    QStylePainter,
    QSwipeGesture,
    QSystemTrayIcon,
    QTabBar,
    QTableView,
    QTableWidget,
    QTableWidgetItem,
    QTableWidgetSelectionRange,
    QTabWidget,
    QTapAndHoldGesture,
    QTapGesture,
    QTextBrowser,
    QTextEdit,
    QTileRules,
    QTimeEdit,
    QToolBar,
    QToolBox,
    QToolButton,
    QToolTip,
    QTreeView,
    QTreeWidget,
    QTreeWidgetItem,
    QTreeWidgetItemIterator,
    QUndoView,
    QVBoxLayout,
    QWhatsThis,
    QWidget,
    QWidgetAction,
    QWidgetItem,
    QWizard,
    QWizardPage,
)

When I try to fix the script for the first time with ruff:

> ptime ruff check --fix mcve.py | head -n 30  

error: Failed to converge after 100 iterations.  

This indicates a bug in Ruff. If you could open an issue at:  

    https://github.com/astral-sh/ruff/issues/new?title=%5BInfinite%20loop%5D  

...quoting the contents of `mcve.py`, the rule codes F401, F811, I001, along with the `pyproject.toml` settings and executed command, we'd be very appreciative!  

mcve.py:2:1: I001 Import block is un-sorted or un-formatted  

As you can see, not only it doesn’t converge quickly enough but it doesn't provide the optimal output in the first pass. For example:
Execution time: 5.506 s.

I've tested with more complex scripts having these type of imports and I’ve observed execution times around ~30s without proper convergence.

Interestingly, if I run the command a second time, it converges properly and successfully fixes the file, leaving an empty output as expected.

Previously, I used isort to handle similar import sorting tasks, and it worked flawlessly. Isort was quick and effective no matter how heavy the imports were, formatting files without breaking a sweat. It’s quite surprising to see ruff struggling with this particular case.

I’ve also tested this against the latest version of origin/main.

Btw, this is kind of offtopic but I noticed that uv --version command provides really helpful information, such as:

uv --version  
uv 0.5.13 (0bc33e87b 2024-12-27)  

I was wondering, would it be possible to include similar version information with the commit hash in Ruff? This would be incredibly helpful for tasks like bisecting or checking out specific hashes for testing purposes or opening issues.

Thanks in advance!

@brupelo brupelo changed the title [Bug] Infinite Loop: Failed to Converge After 100 Iterations When Fixing Imports (e.g., I001, F401, F811) [Infinite loop] Failed to Converge After 100 Iterations When Fixing Imports (e.g., I001, F401, F811) Dec 29, 2024
@charliermarsh
Copy link
Member

That's not quite what's happening here. Ruff can sort the imports without any issue:

❯ time ruff check foo.py --fix --select I001
Found 1 error (1 fixed, 0 remaining).
ruff check foo.py --fix --select I001  0.01s user 0.01s system 87% cpu 0.019 total

It can also remove the unused imports without issue:

❯ time ruff check foo.py --fix --select F401
Found 925 errors (925 fixed, 0 remaining).
ruff check foo.py --fix --select F401  0.02s user 0.01s system 96% cpu 0.029 tota

The problem is in F811, which only allows for one fix to be applied per iteration, so each import requires its own iteration.

@charliermarsh
Copy link
Member

I think this is sort of the cause: #11173

@dhruvmanila dhruvmanila added the fixes Related to suggested fixes for violations label Dec 30, 2024
@brupelo
Copy link
Author

brupelo commented Dec 30, 2024

Hey @charliermarsh , thanks for looking to this one! I can confirm like you said on latest origin/main both I001, F401 work ok

>ptime ruff check mcve.py --fix --select I001
Found 1 error (1 fixed, 0 remaining).

Execution time: 0.036 s

>ptime ruff check mcve.py --fix --select F401
Found 749 errors (749 fixed, 0 remaining).

Execution time: 0.051 s

but when trying just F811 the execution suddenly becomes very slow, ie:

>ptime ruff check mcve.py --fix --select F811

error: Failed to converge after 100 iterations.

This indicates a bug in Ruff. If you could open an issue at:

    https://github.com/astral-sh/ruff/issues/new?title=%5BInfinite%20loop%5D

...quoting the contents of `mcve.py`, the rule codes F811, along with the `pyproject.toml` settings and executed command, we'd be very appreciative!

...

Found 185 errors (100 fixed, 85 remaining).
[*] 76 fixable with the `--fix` option.

Execution time: 4.693 s

As I mentioned earlier, when I tried similar code listings with heavy imports in the past using isort, the execution was quite fast.

I also just realized that I forgot to share the pyproject.toml. Apologies for that! However, it seems this issue is fairly easy to reproduce with a simple Ruff one-liner.

@MichaReiser
Copy link
Member

This sounds related to #14563

@brupelo
Copy link
Author

brupelo commented Dec 30, 2024

Yeah, it's highly related.

In the past, I used to prioritize isort over other linters because it would produce really clean Python code. Here's an example of the commands I typically used:

commands = [
    "isort -q -rc -sp config/.isort.cfg",
    "autoflake --remove-all-unused-imports --ignore-init-module-imports --in-place",
    "black --config config/.black",
    "flake8 --config=config/.flake8",
]

You mentioned something about the order in the other thread. Now I'm wondering—ideally, the order of the rules shouldn't affect the overall execution time, right?

Anyway, I'm glad you all are aware of this one. It's a nasty issue, especially when refactoring large codebases after applying automatic patching or similar tasks. You'd expect ruff to clean it up as usual—blazingly fast."

Ps. Btw, I probably shouldn't have included the 'feature wish' of making ruff --version behave similarly to its counterpart uv --version, though that would definitely be a nice feature to have. But I guess is not good practice mixing different topics in 1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixes Related to suggested fixes for violations
Projects
None yet
Development

No branches or pull requests

4 participants