11

I wrote this funcion on a utils.py located on the app direcroty:

from bm.bmApp.models import Client

def get_client(user):
    try:
        client = Client.objects.get(username=user.username)
    except Client.DoesNotExist:
        print "User Does not Exist"
        return None
    else:       
        return client

def to_safe_uppercase(string):
    if string is None:
        return ''
    return string.upper()

Then when i use the function to_safe_uppercase on my models.py file, by importing it in this way:

from bm.bmApp.utils import to_safe_uppercase 

I got the python error:

     from bm.bmApp.utils import to_safe_uppercase
ImportError: cannot import name to_safe_uppercase

I got the solution for this problem when i change the import statement for:

from bm.bmApp.utils import *

But i can't understand why is this, why when i import the specific function i got the error?

4
  • This should not happen. I suspect there is something else going on. Commented Apr 18, 2012 at 15:41
  • unfortunately, django by default catches ImportErrors and replaces them with this errormessage. try to patch django, so that it gives you the traceback, this should point to the problem. I suspect cyclic imports or something like that. Commented Apr 18, 2012 at 15:46
  • @ch3ka patching django isn't a great idea... also he is getting the python traceback already. He's pasted part of it in the question Commented Apr 18, 2012 at 15:48
  • @Jiaaro not for production use, of course. And I don't think that's the full traceback, as said, django used to hide it (not sure it that's true for recent versions, though) But Mark spotted the Problem already anyways: as I suspected, it's a circular import. Commented Apr 18, 2012 at 15:50

3 Answers 3

13

You are doing what is known as a Circular import.

models.py:

from bm.bmApp.utils import to_safe_uppercase

utils.py:

from bm.bmApp.models import Client

Now when you do import bm.bmApp.models The interpreter does the following:

  1. models.py - Line 1: try to import bm.bmApp.utils
  2. utils.py - Line 1: try to import bm.bmApp.models
  3. models.py - Line 1: try to import bm.bmApp.utils
  4. utils.py - Line 1: try to import bm.bmApp.models
  5. ...

The easiest solution is to move the import inside the function:

utils.py:

def get_client(user):
    from bm.bmApp.models import Client
    try:
        client = Client.objects.get(username=user.username)
    except Client.DoesNotExist:
        print "User Does not Exist"
        return None
    else:       
        return client

def to_safe_uppercase(string):
    if string is None:
        return ''
    return string.upper()
Sign up to request clarification or add additional context in comments.

Comments

8

You are creating a circular import.

utils.py
from bm.bmApp.models import Client
# Rest of the file...

models.py
from bm.bmApp.utils import to_safe_uppercase
# Rest of the file...

I would suggest your refactor your code so that you don't have a circular dependency (i.e. utils should not need to import models.py or vice versa).

3 Comments

Thanks. You should consider adding something about it in your answer, it's part of the OP's question. :)
I've checking the link above, and it seems this get this problem:
0

I'm not sure I can explain the Import error, but I have three ideas. First, your function needs tweaking. You've used a reserved word 'string' as an argument. Consider renaming.

Second, what happens if you invoke ./manage.py shell, and do the import by hand. Does it give you any different?

Third, try deleting your pyc files to force django to recompile python code (this one is a very long shot...but worth eliminating)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.