python / python/mypy

"Cannot assign multiple types to name" error when using get_dynamic_class_hook

Open
#9,627 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug topic-plugins
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Hello there, I'm working on a plugin that allows this syntax:

MyUnion = strawberry.union("Entity", types=(str, int))

to be equivalent of

MyUnion = Union[str, int]

We do this mainly because we need to add some metadata to the union, and we can't use Annotated for two reasons:

  1. it is currently broken for the usage we need (there's an issue for that)
  2. we want to keep strawberry.union as the API as it looks better than the alternative to annotated.

That being said we managed to get a basic plugin working, but it breaks in some cases, here's the first one as I was able to reproduce it in a minimal repo.

We running mypy on this example:

from __future__ import annotations

import strawberry

x: MyUnion

MyUnion = strawberry.union("Entity", types=(str, int))


reveal_type(MyUnion)
reveal_type(x)

we get this error:

example.py:7: error: Cannot assign multiple types to name "MyUnion" without an explicit "Type[...]" annotation
example.py:10: note: Revealed type is 'builtins.object'
example.py:11: note: Revealed type is 'Union[builtins.str, builtins.int]'
Found 1 error in 1 file (checked 1 source file)

if I move x: MyUnion below, everything works as expected, but I still think there's a bug in either mypy or the plugin I'm writing as we managed to get this issue in a different scenario too.

I've set up a repo with the minimal code for this issue:

https://github.com/patrick91/mypy-issue/blob/main/plugin_1.py

I've also tried to defer the add_symbol_table_node to the final iteration, but looks like that did't work.

Is this a bug in mypy or me using it wrong?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running mypy on the example in the issue with the plugin from plugin_1.py, focusing on get_dynamic_class_hook and the deferred add_symbol_table_node behavior. Compare the diagnostics and revealed types when x: MyUnion appears before versus after the assignment, and establish whether the result is expected or a mypy/plugin bug.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.