diff --git a/scrapy/utils/datatypes.py b/scrapy/utils/datatypes.py index 4e65c062e..dd0e062d0 100644 --- a/scrapy/utils/datatypes.py +++ b/scrapy/utils/datatypes.py @@ -152,7 +152,9 @@ class LocalCache(OrderedDict[_KT, _VT]): self.limit: int | None = limit def __setitem__(self, key: _KT, value: _VT) -> None: - if self.limit: + if self.limit is not None: + if self.limit == 0: + return while len(self) >= self.limit: self.popitem(last=False) super().__setitem__(key, value) diff --git a/tests/test_resolver.py b/tests/test_resolver.py index 83fc8693b..7cca45ed1 100644 --- a/tests/test_resolver.py +++ b/tests/test_resolver.py @@ -53,3 +53,21 @@ def test_caching_hostname_resolver_no_addresses_not_cached(): resolver.resolveHostName(Mock(), "example.com") assert "example.com" not in dnscache + + +def test_caching_hostname_resolver_dnscache_disabled_rejects_storage(): + + def fake_resolve(receiver, *_): + receiver.resolutionBegan(Mock()) + receiver.addressResolved(Mock()) + receiver.resolutionComplete() + return receiver + + reactor = Mock() + reactor.nameResolver.resolveHostName.side_effect = fake_resolve + + resolver = CachingHostnameResolver(reactor, cache_size=0) + resolver.resolveHostName(Mock(), "example.com") + + assert "example.com" not in dnscache + assert len(dnscache) == 0 diff --git a/tests/test_utils_datatypes.py b/tests/test_utils_datatypes.py index ba6b82503..fe1f60c7d 100644 --- a/tests/test_utils_datatypes.py +++ b/tests/test_utils_datatypes.py @@ -309,6 +309,16 @@ class TestLocalCache: assert str(x) in cache assert cache[str(x)] == x + def test_cache_with_zero_limit(self): + cache = LocalCache(limit=0) + cache["a"] = 1 + cache["b"] = 2 + cache["c"] = 3 + assert len(cache) == 0 + assert "a" not in cache + assert "b" not in cache + assert "c" not in cache + class TestLocalWeakReferencedCache: def test_cache_with_limit(self):