Skip to content

Incorrect handling of overloads with defaultdict and MutableMapping #19525

@Dr-Irv

Description

@Dr-Irv

Bug Report
This came from a PR with pandas-stubs. The overloads with defaultdict and MutableMapping aren't working correctly.

Requires a stub file and a test file.

To Reproduce

File defdictover.pyi :

from collections import defaultdict
from typing import TypeVar, MutableMapping, overload, Literal, Hashable, Any

_T_MUTABLE_MAPPING = TypeVar("_T_MUTABLE_MAPPING", bound=MutableMapping, covariant=True)

@overload
def to_dict(
    orient: Literal["records"],
    *,
    into: type[dict] = ...,
) -> list[dict[Hashable, Any]]: ...
@overload
def to_dict(
    orient: Literal["index"],
    *,
    into: defaultdict,
) -> defaultdict[Hashable, dict[Hashable, Any]]: ...
@overload
def to_dict(
    orient: Literal["index"],
    *,
    into: MutableMapping | type[MutableMapping],
) -> MutableMapping[Hashable, dict[Hashable, Any]]: ...

File tstdefdictover.py :

from collections import defaultdict
from typing import Any
from defdictover import to_dict

target: defaultdict[Any, list] = defaultdict(list)

reveal_type(to_dict("index", into=target))

Then mypy tstdefdictover.py produces:

tstdefdictover.py:7: note: Revealed type is "Any"

Expected Behavior

With pyright, we get:

tstdefdictover.py:7:13 - information: Type of "to_dict("index", into=target)" is "defaultdict[Hashable, dict[Hashable, Any]]"

Actual Behavior

See above - it sees the type as Any

Your Environment

  • Mypy version used: 1.17
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.12

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions