Speed up the spider argument deprecation check (#7842)

This commit is contained in:
Adrian 2026-08-15 18:16:52 +02:00 committed by GitHub
parent e28e56aa61
commit ad43bf0c56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 39 additions and 8 deletions

View File

@ -109,12 +109,23 @@ def _warn_spider_arg(
| Callable[_P, AsyncGenerator[_T]]
):
"""Decorator to warn if a ``spider`` argument is passed to a function."""
parameters = _signature(func).parameters
spider_parameter = parameters.get("spider")
spider_index = (
list(parameters).index("spider")
if spider_parameter is not None
and spider_parameter.kind
in (
inspect.Parameter.POSITIONAL_ONLY,
inspect.Parameter.POSITIONAL_OR_KEYWORD,
)
else None
)
sig = _signature(func)
def check_args(*args: _P.args, **kwargs: _P.kwargs) -> None:
bound = sig.bind(*args, **kwargs)
if "spider" in bound.arguments:
def check_args(args: tuple[Any, ...], kwargs: dict[str, Any]) -> None:
if "spider" in kwargs or (
spider_index is not None and len(args) > spider_index
):
warnings.warn(
f"Passing a 'spider' argument to {func.__qualname__}() is deprecated and "
"the argument will be removed in a future Scrapy version.",
@ -126,7 +137,7 @@ def _warn_spider_arg(
@wraps(func)
async def async_inner(*args: _P.args, **kwargs: _P.kwargs) -> _T:
check_args(*args, **kwargs)
check_args(args, kwargs)
return cast("_T", await func(*args, **kwargs))
return async_inner
@ -137,7 +148,7 @@ def _warn_spider_arg(
async def asyncgen_inner(
*args: _P.args, **kwargs: _P.kwargs
) -> AsyncGenerator[_T]:
check_args(*args, **kwargs)
check_args(args, kwargs)
async for item in func(*args, **kwargs):
yield item
@ -145,7 +156,7 @@ def _warn_spider_arg(
@wraps(func)
def sync_inner(*args: _P.args, **kwargs: _P.kwargs) -> _T:
check_args(*args, **kwargs)
check_args(args, kwargs)
return func(*args, **kwargs)
return sync_inner

View File

@ -103,6 +103,26 @@ class TestWarnSpiderArg:
):
assert parse("response", spider="spider") == "response"
def test_sync_warns_with_positional_spider_arg(self):
@_warn_spider_arg
def parse(response: str, spider: str | None = None) -> str:
return response
with pytest.warns(
ScrapyDeprecationWarning, match=r"Passing a 'spider' argument"
):
assert parse("response", "spider") == "response"
def test_sync_warns_with_keyword_only_spider_arg(self):
@_warn_spider_arg
def parse(response: str, *, spider: str | None = None) -> str:
return response
with pytest.warns(
ScrapyDeprecationWarning, match=r"Passing a 'spider' argument"
):
assert parse("response", spider="spider") == "response"
def test_sync_no_warning_without_spider_arg(self):
@_warn_spider_arg
def parse(response: str, spider: str | None = None) -> str: