Skip to content

Empty dictionary argument is incompatible with union of mappings #14804

Closed
@tobast

Description

@tobast

Bug Report

When calling a function that calls for an argument of type Union[Mapping[x,z], Mapping[y,z]], the empty dictionary {} does not type-check.

I encountered this problem when trying to call subprocess.run with an empty environment, that is,

subprocess.run(..., env={})

To Reproduce

The smallest I've been able to reduce this issue to is the following code:

from typing import Optional, Union, Mapping
from os import PathLike


def foo(
    x: Union[
        Mapping[bytes, str],
        Mapping[str, str],
    ]
):
    pass


foo({})

Expected Behavior

I expect this code to type check, as the empty dictionary {} type checks against both sides of the Union — that is, if I remove the Union from the above code and leave only either side, mypy reports no issue.

Actual Behavior

Mypy reports an incompatible type:

test.py:14: error: Argument 1 to "foo" has incompatible type "Dict[<nothing>, <nothing>]"; expected "Union[Mapping[bytes, str], Mapping[str, str]]"  [arg-type]

If I break down the call to foo into

arg = {}
foo(arg)

mypy now complains that arg must be type annotated.

Your Environment

  • Mypy version used: 1.0.0
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini: none
  • Python version used: 3.10.9

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-inferenceWhen to infer types or require explicit annotations

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions