Ban more imports that import twisted.internet.reactor. (#6947)

This commit is contained in:
Andrey Rakhmatullin 2025-07-10 21:19:50 +05:00 committed by GitHub
parent 6b2997af90
commit e225d0dea4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 17 additions and 3 deletions

View File

@ -398,6 +398,10 @@ ignore = [
[tool.ruff.lint.flake8-tidy-imports]
banned-module-level-imports = [
"twisted.internet.reactor",
# indirectly imports twisted.conch.insults.helper which imports twisted.internet.reactor
"twisted.conch.manhole",
# directly imports twisted.internet.reactor
"twisted.protocols.ftp",
]
[tool.ruff.lint.isort]

View File

@ -37,7 +37,6 @@ from typing import TYPE_CHECKING, Any, BinaryIO
from urllib.parse import unquote
from twisted.internet.protocol import ClientCreator, Protocol
from twisted.protocols.ftp import CommandFailed, FTPClient
from scrapy.http import Response
from scrapy.responsetypes import responsetypes
@ -46,6 +45,7 @@ from scrapy.utils.python import to_bytes
if TYPE_CHECKING:
from twisted.internet.defer import Deferred
from twisted.protocols.ftp import FTPClient
from twisted.python.failure import Failure
# typing.Self requires Python 3.11
@ -101,6 +101,7 @@ class FTPDownloadHandler:
def download_request(self, request: Request, spider: Spider) -> Deferred[Response]:
from twisted.internet import reactor
from twisted.protocols.ftp import FTPClient
parsed_url = urlparse_cached(request)
user = request.meta.get("ftp_user", self.default_user)
@ -138,6 +139,8 @@ class FTPDownloadHandler:
return respcls(url=request.url, status=200, body=body, headers=headers) # type: ignore[arg-type]
def _failed(self, result: Failure, request: Request) -> Response:
from twisted.protocols.ftp import CommandFailed
message = result.getErrorMessage()
if result.type == CommandFailed:
m = _CODE_RE.search(message)

View File

@ -12,7 +12,7 @@ import os
import pprint
from typing import TYPE_CHECKING, Any
from twisted.conch import manhole, telnet
from twisted.conch import telnet
from twisted.conch.insults import insults
from twisted.internet import protocol
@ -88,6 +88,8 @@ class TelnetConsole(protocol.ServerFactory):
):
raise ValueError("Invalid credentials")
from twisted.conch import manhole
protocol = telnet.TelnetBootstrapProtocol(
insults.ServerProtocol, manhole.Manhole, self._get_telnet_vars()
)

View File

@ -13,7 +13,6 @@ from unittest import mock
import pytest
from pytest_twisted import async_yield_fixture
from twisted.cred import checkers, credentials, portal
from twisted.protocols.ftp import ConnectionLost, FTPFactory, FTPRealm
from w3lib.url import path_to_file_uri
from scrapy.core.downloader.handlers import DownloadHandlers
@ -324,6 +323,8 @@ class TestFTPBase:
(userdir / filename).write_bytes(content)
def _get_factory(self, root):
from twisted.protocols.ftp import FTPFactory, FTPRealm
realm = FTPRealm(anonymousRoot=str(root), userHome=str(root))
p = portal.Portal(realm)
users_checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()
@ -449,6 +450,8 @@ class TestFTP(TestFTPBase):
"This test produces DirtyReactorAggregateError on Windows with asyncio"
)
from twisted.protocols.ftp import ConnectionLost
meta = dict(self.req_meta)
meta.update({"ftp_password": "invalid"})
request = Request(url=server_url + "file.txt", meta=meta)
@ -465,6 +468,8 @@ class TestAnonymousFTP(TestFTPBase):
(root / filename).write_bytes(content)
def _get_factory(self, tmp_path):
from twisted.protocols.ftp import FTPFactory, FTPRealm
realm = FTPRealm(anonymousRoot=str(tmp_path))
p = portal.Portal(realm)
p.registerChecker(checkers.AllowAnonymousAccess(), credentials.IAnonymous)