Skip to content

Union type of two concrete modules is ModuleType #22302

Open

Description

@flying-sheep

Bug Report

It’s #11085, but that one was closed as a duplicate of an unrelated bug, so I’m filing the actual one again

To Reproduce

import json
import pickle


def f(flag: bool) -> None:
    mod = json if flag else pickle
    reveal_type(mod)        # types.ModuleType
    reveal_type(mod.dumps)  # Any
    mod.does_not_exist      # no error

Expected Behavior

Creates a union of two concrete module types

Actual Behavior

Loses all type information about the modules

Your Environment

  • Mypy version used: 2.4.0 (compiled: yes)
  • Mypy command-line flags: none (mypy r.py)
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.14.7

Activity

  1. A5rocks commented on Oct 27, 2026

    @A5rocks
    Collaborator

    I assumed this was just join v union but surprisingly we do take the union here, if you substitute mod = 5 if flag else "5" mod has the type str | int!

  2. flying-sheep commented on Oct 27, 2026

    @flying-sheep
    Author

    That doesn’t surprise me at all, I don’t think anything else makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-join-v-unionUsing join vs. using unions

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions