diff --git a/pyproject.toml b/pyproject.toml index d0c0ecf09..53a1221fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -359,6 +359,7 @@ markers = [ "requires_internet: marks tests that need real Internet access", ] filterwarnings = [ + # Envs with pinned old dependencies opt out of this, see tox.ini. "error", "ignore::DeprecationWarning:twisted.web.static", # Twisted leaves the listening socket open after a failed bind @@ -372,12 +373,8 @@ filterwarnings = [ # queuelib's test helpers (reused by tests/test_squeues.py) leave queue # files open; the resulting warning surfaces at an arbitrary GC point. "ignore:.*<_io\\.FileIO name=.*queuelib-tests-:pytest.PytestUnraisableExceptionWarning", - # pyftpdlib imports the deprecated asyncore/asynchat modules on Python < 3.12. - "ignore:The async(ore|hat) module is deprecated:DeprecationWarning", - # Old w3lib (min env) compiles a regex with inline flags not at the start. - "ignore:Flags not at the start of the expression:DeprecationWarning", - # Old Twisted (min env) calls the deprecated threading.currentThread(). - "ignore:currentThread\\(\\) is deprecated:DeprecationWarning", + # itemadapter imports pydantic.v1, which warns on Python 3.14 and higher. + "ignore:Core Pydantic V1 functionality isn't compatible:UserWarning", ] [tool.ruff.lint] diff --git a/tests/ignores.txt b/tests/ignores.txt index 3717bbc95..5be8576f3 100644 --- a/tests/ignores.txt +++ b/tests/ignores.txt @@ -1,3 +1,4 @@ scrapy/core/downloader/handlers/http.py scrapy/extensions/statsmailer.py +scrapy/interfaces.py scrapy/mail.py diff --git a/tests/test_command_shell.py b/tests/test_command_shell.py index 5f8ad5a35..501f7132e 100644 --- a/tests/test_command_shell.py +++ b/tests/test_command_shell.py @@ -162,6 +162,16 @@ class TestShellCommand: assert ret == 0, out +def _stop(p: PopenSpawn[str]) -> None: + p.sendeof() + p.wait() # type: ignore[no-untyped-call] + # PopenSpawn leaves the subprocess pipes open, which triggers + # ResourceWarning at an arbitrary garbage collection point. + for pipe in (p.proc.stdin, p.proc.stdout): + if pipe: + pipe.close() + + class TestInteractiveShell: def test_fetch(self, mockserver: MockServer) -> None: args = ( @@ -179,12 +189,7 @@ class TestInteractiveShell: p.sendline(f"fetch('{mockserver.url('/')}')") p.sendline("type(response)") p.expect_exact("HtmlResponse") - p.sendeof() - p.wait() # type: ignore[no-untyped-call] - if p.proc.stdin: - p.proc.stdin.close() - if p.proc.stdout: - p.proc.stdout.close() + _stop(p) logfile.seek(0) assert "Traceback" not in logfile.read().decode() @@ -210,12 +215,7 @@ class TestInteractiveShell: p = PopenSpawn(args, env=env, timeout=5) p.logfile_read = logfile p.expect_exact("Available Scrapy objects") - p.sendeof() - p.wait() # type: ignore[no-untyped-call] - if p.proc.stdin: - p.proc.stdin.close() - if p.proc.stdout: - p.proc.stdout.close() + _stop(p) logfile.seek(0) return logfile.read().decode() @@ -240,12 +240,7 @@ class TestInteractiveShell: # shell=python was honored, regardless of platform-specific prompts. p.sendline("import sys; print('IPYMODULE', 'IPython' in sys.modules)") p.expect_exact("IPYMODULE False") - p.sendeof() - p.wait() # type: ignore[no-untyped-call] - if p.proc.stdin: - p.proc.stdin.close() - if p.proc.stdout: - p.proc.stdout.close() + _stop(p) logfile.seek(0) assert "Traceback" not in logfile.read().decode() diff --git a/tox.ini b/tox.ini index e10a7cc0c..b63295518 100644 --- a/tox.ini +++ b/tox.ini @@ -147,6 +147,9 @@ deps = {[test-requirements]deps} setenv = _SCRAPY_MIN=true + # Pinned old Python and library versions trigger warnings that we cannot + # fix, so these envs do not turn warnings into errors. + PYTEST_ADDOPTS=-W default {env:PYTEST_ADDOPTS:} commands = pytest {posargs:--cov-config=pyproject.toml --cov=scrapy --cov-report=xml --cov-report= --junitxml=min.junit.xml -o junit_family=legacy --durations=10 scrapy tests}