Skip to content

A 'type only' module import should not count as importing a module #11503

@KotlinIsland

Description

@KotlinIsland

given:

my-app/
├─ package/
│  ├─ __init__.py
│  ├─ things.py
├─ entry.py
├─ mod.py

entry.py:

import mod
import package

mod.func(package.things.Thing())

mod.py:

def func(it):
    ...

In typeshed/bundled stubs: mod.pyi

from package.things import Thing

def func(it: Thing) -> None: ...
OR, if this is fake imported in the .py module: mod.py
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING
    # do a type import so doesn't cause circular imports or slow down loading
    from package.things import Thing

def func(it: Thing) -> None:
    ...

package.things.py

class Thing:
    ...

When mypy --strict entry.py is executed, no error is generated.
When python entry.py is run: AttributeError: module 'package' has no attribute 'things'

Mypy treats the 'type import' as importing package.things, when in reality it isn't. I understand this is consistent with what TYPE_CHECKING should do, but seems really sus if you ask me.

This more seriously affects typeshed, where all imports are fake and mypy will think all fakely imported modules are really imported.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions