diff --git a/scrapy/core/engine.py b/scrapy/core/engine.py index f577b481b..973ae3258 100644 --- a/scrapy/core/engine.py +++ b/scrapy/core/engine.py @@ -641,6 +641,7 @@ class ExecutionEngine: extra={"spider": self.spider}, ) + # pylint: disable=too-many-statements async def close_spider_async( # noqa: PLR0912, PLR0915 self, *, diff --git a/scrapy/utils/_stopmode.py b/scrapy/utils/_stopmode.py index afb7b4768..05b64ec9a 100644 --- a/scrapy/utils/_stopmode.py +++ b/scrapy/utils/_stopmode.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Literal, cast +from typing import Literal StopMode = Literal["graceful", "fast", "force"] @@ -18,10 +18,9 @@ def normalize_stop_mode(mode: StopMode | None, *, allow_force: bool = True) -> S raise ValueError( f"Unknown stop mode {mode!r}. Expected one of: graceful, fast, force" ) - normalized = cast("StopMode", mode) - if normalized == "force" and not allow_force: + if mode == "force" and not allow_force: raise ValueError("The force stop mode is not supported in this context") - return normalized + return mode def max_stop_mode(mode1: StopMode, mode2: StopMode) -> StopMode: diff --git a/tests/test_core_downloader.py b/tests/test_core_downloader.py index c3ba4125c..aba1541e0 100644 --- a/tests/test_core_downloader.py +++ b/tests/test_core_downloader.py @@ -31,6 +31,7 @@ from tests.utils.decorators import coroutine_test if TYPE_CHECKING: from twisted.internet.ssl import ContextFactory + from twisted.python.failure import Failure from twisted.web.iweb import IBodyProducer @@ -220,7 +221,7 @@ async def test_stop_async_drops_queued_requests() -> None: request = Request("https://example.com") queue_dfd: Deferred = Deferred() - failures = [] + failures: list[Failure] = [] queue_dfd.addErrback(failures.append) slot.queue.append((request, queue_dfd)) diff --git a/tests/test_crawler.py b/tests/test_crawler.py index 6ae097664..c4c28114c 100644 --- a/tests/test_crawler.py +++ b/tests/test_crawler.py @@ -794,7 +794,7 @@ async def test_deprecated_crawler_stop() -> None: async def test_crawler_stop_async_invalid_mode() -> None: crawler = get_crawler(DefaultSpider) with pytest.raises(ValueError, match=r"Unknown stop mode"): - await crawler.stop_async(mode="invalid") + await crawler.stop_async(mode="invalid") # type: ignore[arg-type] @coroutine_test @@ -809,12 +809,13 @@ async def test_crawler_force_stop_falls_back_to_fast( async def stop_async(self, *, mode: str = "graceful") -> None: self.called_mode = mode - crawler.engine = DummyEngine() # type: ignore[assignment] + dummy_engine = DummyEngine() + crawler.engine = dummy_engine # type: ignore[assignment] with caplog.at_level(logging.WARNING): await crawler.stop_async(mode="force") - assert crawler.engine.called_mode == "fast" + assert dummy_engine.called_mode == "fast" assert "Falling back to fast stop" in caplog.text diff --git a/tests/test_engine.py b/tests/test_engine.py index 78e52d7db..5900695af 100644 --- a/tests/test_engine.py +++ b/tests/test_engine.py @@ -8,7 +8,7 @@ from collections import defaultdict from dataclasses import dataclass from logging import DEBUG from typing import TYPE_CHECKING, Any, cast -from unittest.mock import Mock, call +from unittest.mock import Mock, call, patch from urllib.parse import urlparse import attr @@ -784,9 +784,8 @@ class TestEngineCloseSpider: calls += 1 return 3 - engine.downloader.stop_async = fast_stop_downloader - - await engine.close_spider_async(mode="fast") + with patch.object(engine.downloader, "stop_async", fast_stop_downloader): + await engine.close_spider_async(mode="fast") assert calls == 1 assert crawler.stats