question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Interfaces lead to circular imports when splitting type definitions across files

See original GitHub issue

I’m not sure if this issue has been raised before. Did a quick search through issues and didn’t find anything. But I was wondering if anyone had run into this issue before and there’s an existing Python solution I’m not thinking about or if this is an existing issue.

Basically, when defining a type that implements an interface, we specify the interface class that is being implemented by this new type in the Meta interface option.

class Character(graphene.Interface): 
    id = graphene.ID(required=True)
    name = graphene.String(required=True)
    friends = graphene.List(lambda: Character)

class Human(graphene.ObjectType):
    class Meta:
        interfaces = (Character, ) # <----- here

    starships = graphene.List(Starship)
    home_planet = graphene.String()

But if we would like to split the class definitions across two files:

#schema.py 

import graphene
from human import Human
from droid import Droid


class Character(graphene.Interface):
    id = graphene.ID(required=True)
    name = graphene.String(required=True)
    friends = graphene.List(lambda: Character)

   def resolve_type(cls, instance, info):
        if instance.type == 'DROID':
            return Droid
        return Human # <----- here we need to import Human




....


schema = graphene.Schema(query=Query, mutation=Mutation, types=[Human])

and

#human.py
class Human(graphene.ObjectType):
    class Meta:
        interfaces = (Character, ) # <--- would require us to import Character

    starships = graphene.List(Starship)
    home_planet = graphene.String()

then how would the Human class be able to import the Character class it needs to specify in the interfaces it implements without introducing circular imports?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
ekampfcommented, Jul 10, 2019
# interfaces.py

import graphene

class Character(graphene.Interface):
    id = graphene.ID(required=True)
    name = graphene.String(required=True)
    friends = graphene.List(lambda: Character)

   def resolve_type(cls, instance, info):
        from droid import Droid
        from human import Human
        if instance.type == 'DROID':
            return Droid
        return Human

0reactions
klairetancommented, Jul 16, 2019

apparently, resolve_type can actually return Strings, so you can return ‘Droid’ and ‘Human’ instead of the classes themselves

Read more comments on GitHub >

github_iconTop Results From Across the Web

Yet another solution to dig you out of a circular import hole in ...
The circular import problem in Python. ... abstract interfaces, merge modules, split modules, use local imports, defer imports, etc.
Read more >
go - Circular import with structs - Stack Overflow
To split something between separate packages A and B you'd normal try to isolate an API for access to A.Type that can be...
Read more >
Code Structure and Multiple Files - SQLModel - tiangolo
Circular Imports and Type Annotations​​ The problem with circular imports is that Python can't resolve them at runtime . But when using Python...
Read more >
Programming FAQ — Python 3.11.1 documentation
Circular imports are fine where both modules use the “import <module>” form of import. ... Parameters define what kind of arguments a function...
Read more >
Structuring Your Project - The Hitchhiker's Guide to Python
By “structure” we mean the decisions you make concerning how your project best ... In this case, the interface file needs to import...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found