Skip to content

Wrong mypy behavior with warn_unreachable flag #18785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Sanchoyzer opened this issue Mar 11, 2025 · 2 comments
Closed

Wrong mypy behavior with warn_unreachable flag #18785

Sanchoyzer opened this issue Mar 11, 2025 · 2 comments
Labels
bug mypy got something wrong topic-reachability Detecting unreachable code

Comments

@Sanchoyzer
Copy link

mypy==1.15.0

[tool.mypy]
python_version = '3.12'
show_error_context = true
check_untyped_defs = true
ignore_missing_imports = true
warn_unused_ignores = true
warn_redundant_casts = true
show_error_code_links = true
warn_unreachable = true

Gist URL: https://gist.github.com/mypy-play/187d99115a24b12a7a58b437ae6127fb

Playground URL: https://mypy-play.net/?mypy=1.15.0&python=3.12&flags=ignore-missing-imports%2Ccheck-untyped-defs%2Cwarn-unreachable&gist=187d99115a24b12a7a58b437ae6127fb

For some reason, mypy displays the error "Statement is unreachable [unreachable]" for actual code that executes.

async_session: async_sessionmaker = async_sessionmaker(...)


class ProjectStatus(StrEnum):
    NEW = 'new'
    PENDING = 'pending'
    FINISHED = 'finished'


class Project(Base):
    __tablename__ = 'projects'

    uid: Mapped[int] = mapped_column(primary_key=True)
    status: Mapped[ProjectStatus] = mapped_column(
        Enum(*list(ProjectStatus._value2member_map_.keys()), name='project_status_enum'),
        server_default=ProjectStatus.NEW,
    )


@pytest_asyncio.fixture
async def project_id() -> int:
    ...


async def update_status(project_id: int, status: ProjectStatus) -> None:
    ...


async def test_project_status(project_id: int) -> None:
    async with async_session() as session:
        tmp: Project | None = await session.get(Project, project_id)
        assert tmp
        project: Project = tmp
        assert project.status == ProjectStatus.NEW  # if comment this line, the "unreachable" error will disappear

        for status in [ProjectStatus.PENDING, ProjectStatus.FINISHED]:
            await update_status(project_id=project.uid, status=status)
            await session.refresh(project)
            assert project.status == status
            if status == ProjectStatus.FINISHED:
                print('the end')  # error: Statement is unreachable  [unreachable]
@Sanchoyzer Sanchoyzer added the bug mypy got something wrong label Mar 11, 2025
@A5rocks
Copy link
Collaborator

A5rocks commented Mar 11, 2025

This is because the binder in mypy is optimistic that state will not change under it. I'm sure there's an earlier report of this (though I haven't looked yet).

@A5rocks A5rocks added the topic-reachability Detecting unreachable code label Mar 11, 2025
@A5rocks
Copy link
Collaborator

A5rocks commented Mar 11, 2025

Duplicate of #11969

@A5rocks A5rocks marked this as a duplicate of #11969 Mar 11, 2025
@A5rocks A5rocks closed this as not planned Won't fix, can't repro, duplicate, stale Mar 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-reachability Detecting unreachable code
Projects
None yet
Development

No branches or pull requests

2 participants