Skip to content

Commit

Permalink
Headers is not MutableMapping (#2991)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidism authored Nov 4, 2024
2 parents 1317014 + ac87bf8 commit 1803db6
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 12 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Unreleased

- Improve type annotation for ``TypeConversionDict.get`` to allow the ``type``
parameter to be a callable. :issue:`2988`

- ``Headers`` does not inherit from ``MutableMapping``, as it is does not
exactly match that interface. :issue:`2989`


Version 3.1.1
Expand Down
20 changes: 10 additions & 10 deletions src/werkzeug/datastructures/headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
T = t.TypeVar("T")


class Headers(cabc.MutableMapping[str, str]):
class Headers:
"""An object that stores some headers. It has a dict-like interface,
but is ordered, can store the same key multiple times, and iterating
yields ``(key, value)`` pairs instead of only keys.
Expand Down Expand Up @@ -107,7 +107,7 @@ def lowered(item: tuple[str, ...]) -> tuple[str, ...]:

__hash__ = None # type: ignore[assignment]

@t.overload # type: ignore[override]
@t.overload
def get(self, key: str) -> str | None: ...
@t.overload
def get(self, key: str, default: str) -> str: ...
Expand Down Expand Up @@ -208,17 +208,17 @@ def get_all(self, name: str) -> list[str]:
"""
return self.getlist(name)

def items(self, lower: bool = False) -> t.Iterable[tuple[str, str]]: # type: ignore[override]
def items(self, lower: bool = False) -> t.Iterable[tuple[str, str]]:
for key, value in self:
if lower:
key = key.lower()
yield key, value

def keys(self, lower: bool = False) -> t.Iterable[str]: # type: ignore[override]
def keys(self, lower: bool = False) -> t.Iterable[str]:
for key, _ in self.items(lower):
yield key

def values(self) -> t.Iterable[str]: # type: ignore[override]
def values(self) -> t.Iterable[str]:
for _, value in self.items():
yield value

Expand Down Expand Up @@ -322,7 +322,7 @@ def popitem(self) -> tuple[str, str]:
"""Removes a key or index and returns a (key, value) item."""
return self._list.pop()

def __contains__(self, key: str) -> bool: # type: ignore[override]
def __contains__(self, key: str) -> bool:
"""Check if a key is present."""
try:
self._get_key(key)
Expand All @@ -331,7 +331,7 @@ def __contains__(self, key: str) -> bool: # type: ignore[override]

return True

def __iter__(self) -> t.Iterator[tuple[str, str]]: # type: ignore[override]
def __iter__(self) -> t.Iterator[tuple[str, str]]:
"""Yield ``(key, value)`` tuples."""
return iter(self._list)

Expand Down Expand Up @@ -486,7 +486,7 @@ def __setitem__(
else:
self._list[key] = [(k, _str_header_value(v)) for k, v in value] # type: ignore[misc]

def update( # type: ignore[override]
def update(
self,
arg: (
Headers
Expand Down Expand Up @@ -562,7 +562,7 @@ def to_wsgi_list(self) -> list[tuple[str, str]]:
:return: list
"""
return list(self) # type: ignore[arg-type]
return list(self)

def copy(self) -> te.Self:
return self.__class__(self._list)
Expand Down Expand Up @@ -640,7 +640,7 @@ def _get_key(self, key: str) -> str:
def __len__(self) -> int:
return sum(1 for _ in self)

def __iter__(self) -> cabc.Iterator[tuple[str, str]]: # type: ignore[override]
def __iter__(self) -> cabc.Iterator[tuple[str, str]]:
for key, value in self.environ.items():
if key.startswith("HTTP_") and key not in {
"HTTP_CONTENT_TYPE",
Expand Down
2 changes: 1 addition & 1 deletion src/werkzeug/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def lookup(self, obj: Request) -> WSGIEnvironment:
class header_property(_DictAccessorProperty[_TAccessorValue]):
"""Like `environ_property` but for headers."""

def lookup(self, obj: Request | Response) -> Headers:
def lookup(self, obj: Request | Response) -> Headers: # type: ignore[override]
return obj.headers


Expand Down

0 comments on commit 1803db6

Please sign in to comment.