You forgot to show us your definition for LazyType. And, honestly, a lot more context explaining what you're trying to do and why.

But passing ".type_a" to any generic type isn't going to work in mypy, it's always going to be treated as a syntax error.

Maybe you can play some game with `if TYPE_CHECKING` inside strawberry so that mypy thinks that LazyType is an alias for Annotated, but at runtime it's something else?

On Thu, Jul 23, 2020 at 3:14 PM Patrick Arminio <> wrote:
Hello again, I'm working on a library that uses the return type of methods at runtime to generate GraphQL types and I'm trying to
deal with the case of circular imports and classes referencing each others.

I was thinking of create a LazyType where you can pass the type name and the module, so that we are able to resolve
the actual type at runtime without having to guess where it came from, like this:

import typing

import strawberry

if typing.TYPE_CHECKING:
    from .type_a import TypeA

class TypeB:
    def type_a(self, info) -> strawberry.LazyType["TypeA", ".type_a"]:
        from .type_a import TypeA

        return TypeA()

As previous post unfortunately I can't relay on sys.module, since the type is only imported when TYPE_CHECKING is True or inside the method.
Now, I managed to make it work with a custom LazyType class, so the annotation above works;

strawberry.LazyType["TypeA", ".type_a"]

I don't dislike this to be honest, but looks like mypy isn't really happy, as you can see from the errors here:

tests/test_cyclic/ error: "LazyType" expects no type arguments, but 2 given
tests/test_cyclic/ error: Invalid type comment or annotation
tests/test_cyclic/ error: Incompatible return value type (got "TypeA", expected "LazyType")

The first one could be resolve by using generics, but I'm not sure that's a good idea. The last one could be solved by creating a plugin, hopefully it won't be too difficult.
But I have no clue about `Invalid type comment or annotation`. Why would that be the case?

I noticed that the error disappears when removing the dot from the module name, but I'd like to be able to pass a dot there, so
users of the library don't have to type the full module, since we can infer that.

Any ideas? Or do I need to change the approach for this? Maybe doing a less typehint-y way:

def x() -> strawberry.LazyType("TypeA", ".type_a"):

Let me know! :)
Typing-sig mailing list --
To unsubscribe send an email to
Member address:

--Guido van Rossum (
Pronouns: he/him (why is my pronoun here?)