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.

Circular import question

See original GitHub issue

In our project we have schema consisting of around 20 different classes and we want to divide it in different files instead of having only one. But while trying to do this, we encountered circular import problem. We have tried using advices given in https://github.com/graphql-python/graphene/issues/110 and https://github.com/graphql-python/graphene/issues/436 but couldn’t solve the problem:

# Basic example (we need to import Dictionary on language.py and Language in dictionary.py)
# mymodule/language.py
class Language(graphene.ObjectType):
    id = graphene.Int()
    dictionaries = graphene.List(Dictionary)
    def resolve_dictionaries(self, args, context, info):
        result = list()
        for dictionary in db_list:
            result.append(Dictionary(id=dictionary.id))
        return result


# mymodule/dictionary.py
class Dictionary(graphene.ObjectType):
    id = graphene.Int()
    language = graphene.Field(Language)
    def resolve_language(self, args, context, info):
        language = db_object
        return Language(id=language.id)

# first example (working, but it violates pep8)
# mymodule/language.py
class Language(graphene.ObjectType):
    id = graphene.Int()
    dictionaries = graphene.List(lambda: Dictionary)
    def resolve_dictionaries(self, args, context, info):
        result = list()
        for dictionary in db_list:
            result.append(Dictionary(id=dictionary.id))
        return result
from .dictionary import Dictionary


# mymodule/dictionary.py
class Dictionary(graphene.ObjectType):
    id = graphene.Int()
    language = graphene.Field(lambda: Language)
    def resolve_language(self, args, context, info):
        language = db_object
        return Language(id=language.id)
from .language import Language

# second example (Dictionary(id=dictionary.id) and Language(id=language.id) 
# gives TypeError: import_string() got an unexpected keyword argument 'id')
# mymodule/language.py
Dictionary = lazy_import('mymodule.dictionary.Dictionary')
class Language(graphene.ObjectType):
    id = graphene.Int()
    dictionaries = graphene.List(Dictionary)
    def resolve_dictionaries(self, args, context, info):
        result = list()
        for dictionary in db_list:
            result.append(Dictionary(id=dictionary.id))
        return result


# mymodule/dictionary.py
Dictionary = lazy_import('mymodule.language.Language')
class Dictionary(graphene.ObjectType):
    id = graphene.Int()
    language = graphene.Field(Language)
    def resolve_language(self, args, context, info):
        language = db_object
        return Language(id=language.id)

How can we solve this problem without violating pep8? Thanks in advance

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

13reactions
totakicommented, Aug 22, 2017

My solve problem, something like this iteration.py

class IterationObject(graphene.ObjectType):
    id = graphene.Int()
    tasks = graphene.List(TaskObject)

tasks.py

class TaskObject(graphene.ObjectType):
    id = graphene.Int()
    iteration = graphene.Field('iteration.IterationObject')

    @property
    def iteration_class(self):
        return self._meta.fields['iteration'].type
2reactions
Bizilizicommented, Feb 4, 2021

Yep, I would like to see any pretty workaround for this issue. I was actually really surprised that there is no “out of box” solution for this.

My suggestion is to use your import strategy as part of import_string. In order preserve already overloaded syntax as simple as possible:

from graphene import ObjectType, List


class FooBarBaz(ObjectType):
    foo_bars = List('FooBar', required= True)
Read more comments on GitHub >

github_iconTop Results From Across the Web

Python Circular Import Problem and Solutions
Generally, the Python Circular Import problem occurs when you accidentally name your working file the same as the module name and those modules ......
Read more >
What happens when using mutual or circular (cyclic) imports?
If a module does exist in sys.modules then an import simply returns that module whether or not it has completed executing. That is...
Read more >
Python Circular Imports Module: Solving Circular Import Problem
Python Circular Imports is a type of Circular dependency. It occurs in python when two or more models import each other and it...
Read more >
Avoiding Circular Imports in Python | by André Menck - Medium
We can trivially fix this particular circular import by changing our imports to import from the module where the object is actually defined....
Read more >
Python Circular Imports - Stack Abuse
Circular importing is a form of circular dependency that is created with the import statement in Python. For example, let's analyze the ...
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