scrapy/scrapy
tanishqtayade 6591cb756c
Fix to LocalCache with limit=0 still stores items rather than disabling the cache (#7663)
* Fix cell-var-from-loop in _send_catch_log_deferred

Replace lambda capturing receiver by reference with a default
argument to capture it by value, fixing a potential bug where
all deferred callbacks could reference the last receiver in the
loop instead of their respective receivers.

Removes the pylint disable comment and TODO that were suppressing
this issue.

* chore: trigger CI rerun for mypy network error

* Fix mypy error: pass receiver via addBoth args instead of lambda default

* style: apply pre-commit ruff formatting

* fix: LocalCache with limit=0 incorrectly stores items

When limit=0 is passed to LocalCache (e.g. when DNSCACHE_ENABLED=False),
the condition 'if self.limit' evaluates to False due to Python's truthiness
rules, causing items to be stored despite the cache being disabled.

This leads to an unbounded memory leak during long crawls when DNS caching
is explicitly disabled.

Fix changes the condition to 'if self.limit is not None' and adds an early
return when limit=0 to correctly handle the disabled cache case.

* test: add resolver-level regression tests for DNSCACHE_ENABLED=False

Add two regression tests that verify DNS results are not stored in
dnscache when DNSCACHE_ENABLED=False (cache_size=0):

- test_caching_hostname_resolver_dnscache_disabled_rejects_storage:
  verifies _CachingResolutionReceiver does not write to dnscache
  when CachingHostnameResolver is initialized with cache_size=0

- test_caching_threaded_resolver_dnscache_disabled_rejects_storage:
  verifies dnscache rejects storage at the LocalCache level
  when limit=0

* test: drop misleading threaded resolver test

it was writing directly to dnscache, not actually going through
CachingThreadedResolver at all. the threaded resolver already has
its own if dnscache.limit: guard so the bug doesnt affect it anyway.

keeping only the hostname resolver test which covers the actual
bug path through _CachingResolutionReceiver

* test: clean up comments in resolver test

* test: remove unnecessary comment
2026-06-29 21:37:06 +05:00
..
commands Deprecate ScrapyCommand.help() (#7633) 2026-06-19 06:49:32 +02:00
contracts Address warnings in tests. (#7637) 2026-06-19 06:55:02 +02:00
core Close various garbage collectible resources (mostly in tests) (#7644) 2026-06-26 23:05:08 +05:00
downloadermiddlewares Improve test coverage for downloader middlewares (#7655) 2026-06-25 01:48:28 +05:00
extensions Close various garbage collectible resources (mostly in tests) (#7644) 2026-06-26 23:05:08 +05:00
http Undeprecated the basic FormRequest API (#7671) 2026-06-26 17:35:46 +02:00
linkextractors chore: more ruff rules and overall minor improvements (#7386) 2026-04-03 19:00:13 +05:00
loader Small docs fixes. (#7598) 2026-06-11 10:51:03 +02:00
pipelines Fix image store ACL settings for S3 and GCS (#7614) 2026-06-16 00:24:44 +05:00
selector Enable the flake8-builtins rules. (#6942) 2025-07-05 21:43:18 +05:00
settings Implement HTTP Auth settings and request metadata keys (#7590) 2026-06-11 15:56:53 +05:00
spidermiddlewares Improve test coverage for spider middlewares (#7664) 2026-06-25 15:35:25 +05:00
spiders Document scrapy-lint, remove start_url check (#7627) 2026-06-22 20:12:16 +05:00
templates Improve the item pipeline docs (#7676) 2026-06-26 16:18:22 +05:00
utils Fix to LocalCache with limit=0 still stores items rather than disabling the cache (#7663) 2026-06-29 21:37:06 +05:00
VERSION Bump version: 2.15.2 → 2.16.0 2026-05-19 17:27:16 +05:00
__init__.py Remove code deprecated in 2.12.0 (#7126) 2025-10-27 17:14:38 +05:00
__main__.py Improve coverage statscollectors (#7641) 2026-06-19 16:59:25 +02:00
addons.py Move to mypy --strict with exceptions. (#7300) 2026-03-02 15:47:23 +05:00
cmdline.py Reactorless shell and other small shell improvements (#7395) 2026-04-08 18:24:51 +05:00
crawler.py Do not ignore CrawlerProcess settings (#7647) 2026-06-22 20:10:10 +05:00
dupefilters.py Add Jobdir documentation (#5260) 2026-02-06 22:33:02 +04:00
exceptions.py Refactor HTTP download handlers (#7238) 2026-02-03 20:13:30 +01:00
exporters.py Close various garbage collectible resources (mostly in tests) (#7644) 2026-06-26 23:05:08 +05:00
extension.py Restore 2.14 getwithbase, add a new method for class key deduplication (#7449) 2026-04-22 19:01:59 +05:00
interfaces.py Remove useless pylint: disable lines. 2025-01-02 12:32:25 +05:00
item.py Update the outdated Item docstring. (#6427) 2024-11-04 16:17:56 +05:00
link.py Link.__eq__: return NotImplemented instead of raising NotImplementedError (#7611) 2026-06-12 14:56:15 +02:00
logformatter.py Release notes for 2.14.0 (#7035) 2026-01-05 14:51:05 +05:00
mail.py chore: more ruff rules and overall minor improvements (#7386) 2026-04-03 19:00:13 +05:00
middleware.py Disable mypy allow_any_generics. (#7532) 2026-05-18 15:54:06 +02:00
mime.types moved module scrapy.core.downloader.responsetypes to scrapy.responsetypes 2011-08-07 02:49:57 -03:00
pqueues.py Close various garbage collectible resources (mostly in tests) (#7644) 2026-06-26 23:05:08 +05:00
py.typed Add py.typed 2023-09-21 13:06:12 +02:00
resolver.py Improve coverage resolver (#7642) 2026-06-19 23:26:54 +05:00
responsetypes.py Improve test coverage for responsetypes.py (#7646) 2026-06-22 20:10:38 +05:00
robotstxt.py Enable mypy warn_return_any. (#7492) 2026-05-04 22:24:47 +02:00
shell.py Small docs fixes. (#7598) 2026-06-11 10:51:03 +02:00
signalmanager.py Move to mypy --strict with exceptions. (#7300) 2026-03-02 15:47:23 +05:00
signals.py Deprecate the mail API (#7263) 2026-03-24 21:31:12 +01:00
spiderloader.py chore: more ruff rules and overall minor improvements (#7386) 2026-04-03 19:00:13 +05:00
squeues.py Disable mypy allow_any_generics. (#7532) 2026-05-18 15:54:06 +02:00
statscollectors.py Move to mypy --strict with exceptions. (#7300) 2026-03-02 15:47:23 +05:00