Repository navigation
TypedDict with generic function #9827
Copy link
Copy link
Closed
Labels
bugmypy got something wrongmypy got something wrongtopic-type-formTypeForm might fix thisTypeForm might fix thistopic-typed-dict
Description
Bug Report
Using a TypedDict with a generic function gives a strange type error with the same "expected" and "actual" types.
I also wonder that if we could use TypeVar('TD', bound=TypedDict) as well.
(NOTE: This is a follow-up to #9820)
To Reproduce
Given
import sys
from typing import Any, Mapping, Type, TypeVar, cast
import typeguard
TD = TypeVar('TD')
def check_typed_dict(value: Mapping[Any, Any], expected_type: Type[TD]) -> TD:
"""
Validates the given dict against the given TypedDict class, and wraps the value as the given TypedDict type.
This is a shortcut to :func:`typeguard.check_typed_dict()` function to fill extra information
"""
assert issubclass(expected_type, dict) and hasattr(expected_type, '__annotations__'), \
f"expected_type ({type(expected_type)}) must be a TypedDict class"
frame = sys._getframe(1)
_globals = frame.f_globals
_locals = frame.f_locals
memo = typeguard._TypeCheckMemo(_globals, _locals)
typeguard.check_typed_dict('value', value, expected_type, memo)
# Here we passed the check, so return it after casting.
return cast(TD, value)and
from typing import Dict, Literal, Optional, TypedDict
class HardwareMetadata(TypedDict):
status: Literal["healthy", "degraded", "offline", "unavailable"]
status_info: Optional[str]
metadata: Dict[str, str],
running mypy against the following code snippet
async def gather_agent_hwinfo(self, instance_id: AgentId) -> Mapping[str, HardwareMetadata]:
agent = await self.get_instance(instance_id, agents.c.addr)
async with RPCContext(agent['addr'], None) as rpc:
result = await rpc.call.gather_hwinfo()
return {
k: check_typed_dict(v, HardwareMetadata) # L259
for k, v in result.items()
}
async def gather_storage_hwinfo(self, vfolder_host: str) -> HardwareMetadata:
proxy_name, volume_name = self.storage_manager.split_host(vfolder_host)
async with self.storage_manager.request(
proxy_name, 'GET', 'volumes/hwinfo',
query={'volume': volume_name},
raise_for_status=True,
) as (_, storage_resp):
return check_typed_dict(await storage_resp.json(), HardwareMetadata) # L270reports
src/ai/backend/manager/registry.py:259: error: Value expression in dictionary comprehension has incompatible type "HardwareMetadata"; expected type "HardwareMetadata"
src/ai/backend/manager/registry.py:270: error: Incompatible return value type (got "HardwareMetadata", expected "HardwareMetadata")
Expected Behavior
It should pass the type check, or give a more understandable error message.
Actual Behavior
It's reporting a type error with the same "expected" and "actual" types.
Your Environment
- Mypy version used: 0.790
- Mypy command-line flags:
python -m mypy src/ai/backend tests - Mypy configuration options from
mypy.ini(and other config files):
[mypy]
ignore_missing_imports = true
namespace_packages = true
- Python version used: 3.8.5
- Operating system and version: Ubuntu 20.04
Reacted by Brendon J. Boldt and Aaron Schif
Metadata
Metadata
Assignees
Labels
bugmypy got something wrongmypy got something wrongtopic-type-formTypeForm might fix thisTypeForm might fix thistopic-typed-dict
Activity
typecheck: temporarily ignore bug (python/mypy#9827)
achimnol commentedon Jan 27, 2021
This is still happening with v0.800 release.
Note that my config has been updated:
brendon-boldt commentedon Feb 2, 2021
For what it's worth I have a minimal example here:
Python 3.9.1 and mypy 0.800.
Incidentally, I am also unable to use
TypedDicts as the upper bound of theTypeVar.erictraut commentedon Aug 12, 2023
I think this bug has been fixed. I'm not able to repro it with the latest version of mypy.