Support iterable values in BaseSettings.update() (#7763)

This commit is contained in:
Mridankan Mandal 2026-07-23 16:07:21 +05:30 committed by GitHub
parent 628a3afbbd
commit 8489b3dad8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 10 deletions

View File

@ -25,7 +25,9 @@ if TYPE_CHECKING:
# typing.Self requires Python 3.11
from typing_extensions import Self
_SettingsInput: TypeAlias = SupportsItems[str, Any] | str | None
_SettingsInput: TypeAlias = (
SupportsItems[str, Any] | Iterable[tuple[str, Any]] | str | None
)
SETTINGS_PRIORITIES: dict[str, int] = {
@ -560,7 +562,7 @@ class BaseSettings(MutableMapping[str, Any]):
if key.isupper():
self.set(key, getattr(module, key), priority)
# BaseSettings.update() doesn't support all inputs that MutableMapping.update() supports
# BaseSettings.update() doesn't support kwargs input like MutableMapping.update().
def update(self, values: _SettingsInput, priority: int | str = "project") -> None: # type: ignore[override]
"""
Store key/value pairs with a given priority.
@ -577,7 +579,7 @@ class BaseSettings(MutableMapping[str, Any]):
command.
:param values: the settings names and values
:type values: dict or string or :class:`~scrapy.settings.BaseSettings`
:type values: dict, iterable, string or :class:`~scrapy.settings.BaseSettings`
:param priority: the priority of the settings. Should be a key of
:attr:`~scrapy.settings.SETTINGS_PRIORITIES` or an integer
@ -591,7 +593,12 @@ class BaseSettings(MutableMapping[str, Any]):
for name, value in values.items():
self.set(name, value, cast("int", values.getpriority(name)))
else:
for name, value in values.items():
items: Iterable[tuple[str, Any]]
if hasattr(values, "items"):
items = cast("SupportsItems[str, Any]", values).items()
else:
items = values
for name, value in items:
self.set(name, value, priority)
def delete(self, name: str, priority: int | str = "project") -> None:

View File

@ -221,13 +221,11 @@ class TestBaseSettings:
settings = BaseSettings({"key": 0})
settings.update(key=1) # pylint: disable=unexpected-keyword-arg
@pytest.mark.xfail(
raises=AttributeError,
reason="BaseSettings.update doesn't support iterable input",
)
def test_update_iterable(self):
settings = BaseSettings({"key": 0})
settings.update([("key", 1)])
settings = BaseSettings({"key": 0}, priority=0)
settings.update([("key", 1)], priority=10)
assert settings["key"] == 1
assert settings.getpriority("key") == 10
def test_update_jsonstring(self):
settings = BaseSettings({"number": 0, "dict": BaseSettings({"key": "val"})})