You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Werkzeug EnvironHeaders is not considered a Mapping #3569
It seems that the EnvironHeaders class of werkzeug (and probably the base class Headers too) is not compatible with Mapping, however it looks like it should be compatible (it implements all needed methods, and functions like one).
I opened #3576 for the underlying issue. My best suggestion for now is to use a custom protocol for your own code and - depending on the outcome of the discussion in #3576 - submit PRs for code in typeshed.
For posterity, here is a custom protocol that works for me in one particular place:
from typing import overload
import typing_extensions
class HeadersType(typing_extensions.Protocol):
"""common subtype of Mapping[str, str] and werkzeug.datastructures.EnvironHeaders"""
@overload
def get(self, k: str) -> Optional[str]:
...
@overload
def get(self, k: str, default: str) -> str:
...
This is not a general solution to the problem! But I just spent at least an hour banging my head against this until I got it working. Hopefully this can save someone else some time in the future.
Deriving Headers from Mapping would introduce a false negatives. For example, cgi.FieldStorage takes a headers arguments, but checks for Mapping explicitly:
fromcgiimportFieldStoragefromwerkzeug.datastructuresimportHeadersFieldStorage(headers=Headers()) # throws a TypeError
Activity
srittau commentedon Jan 3, 2020
Do you have an example that you think should type check but doesn't?
libre-man commentedon Jan 3, 2020
Here is small example:
On which mypy errors with:
test.py:10: error: Argument 1 to "get" has incompatible type "EnvironHeaders"; expected "Mapping[str, <nothing>]".srittau commentedon Jan 5, 2020
I opened #3576 for the underlying issue. My best suggestion for now is to use a custom protocol for your own code and - depending on the outcome of the discussion in #3576 - submit PRs for code in typeshed.
gward commentedon Jul 7, 2020
For posterity, here is a custom protocol that works for me in one particular place:
This is not a general solution to the problem! But I just spent at least an hour banging my head against this until I got it working. Hopefully this can save someone else some time in the future.
I just had to change my code from
to
and now mypy is happy.
Introduce Mapping-like protocols
srittau commentedon Jul 10, 2020
A brief addendum on why we can't just derive
HeadersfromMapping: SinceMappingis not a protocol, the following code returnsFalseat runtime:Deriving
HeadersfromMappingwould introduce a false negatives. For example,cgi.FieldStoragetakes aheadersarguments, but checks forMappingexplicitly:Introduce Mapping-like protocols (#4325)
srittau commentedon May 18, 2021
Closing as the werkzeug stubs will be removed in a few months.