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?
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:
models.py - Line 1: try to import bm.bmApp.utils
utils.py - Line 1: try to import bm.bmApp.models
models.py - Line 1: try to import bm.bmApp.utils
utils.py - Line 1: try to import bm.bmApp.models
...
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()
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).
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)
Related
I have the following folder structure.
check_site
- test_site
-- views.py
- app2
- app3
- modules
-- url.py
-- usability.py
module ulr.py contains one class inside - Url.py
class URL:
...
module usability.py contains one class that inherit URL class
from url import URL
class Usability(URL):
...
And then I have a view.py where I neen to import class Usability
from modules.url import URL
from modules.usability import Usability
And here is a problem. It gives me an error
from url import URL
ModuleNotFoundError: No module named 'url'
I've tried to change the import in usability.py to
from modules.url import URL but in this case it gives the error in the usability.py
Unable to import modules.url
I've also tried
from .url import URL and from check_site.modules.url import URL But these also don't work
If someone knows how to fix it, please help
Well, the problem lies here because by default Python searches for the file in the current directory but the file u want to import is not in the same directory as your program.
You should try sys.path
# some_file.py
import sys
# insert at 1, 0 is the script path (or '' in REPL)
sys.path.insert(1, '/path/to/application/app/folder')
import file
This should work in most cases.
I am trying to learn unittest patching. I have a single file that both defines a function, then later uses that function. When I try to patch this function, its return value is giving me the real return value, not the patched return value.
How do I patch a function that is both defined and used in the same file? Note: I did try to follow the advice given here, but it didn't seem to solve my problem.
walk_dir.py
from os.path import dirname, join
from os import walk
from json import load
def get_config():
current_path =dirname(__file__)
with open(join(current_path, 'config', 'json', 'folder.json')) as json_file:
json_data = load(json_file)
return json_data['parent_dir']
def get_all_folders():
dir_to_walk = get_config()
for root, dir, _ in walk(dir_to_walk):
return [join(root, name) for name in dir]
test_walk_dir.py
from hello_world.walk_dir import get_all_folders
from unittest.mock import patch
#patch('walk_dir.get_config')
def test_get_all_folders(mock_get_config):
mock_get_config.return_value = 'C:\\temp\\test\\'
result = get_all_folders()
assert set(result) == set('C:\\temp\\test\\test_walk_dir')
Try declaring the patch in such way:
#patch('hello_world.walk_dir.get_config')
As you can see this answer to the question you linked, it's recommended that your import statements match your patch statements. In your case from hello_world.walk_dir import get_all_folders and #patch('walk_dir.get_config') doesn't match.
The directory structure is like so:
AppCenter/
main.pyw
|
|
_apps/
__init__.py
TabularApp.py
UserAdministrationApp.py
RegisterApp.py
FnAdminApp.py
PyUi/
The contents of __init__.py:
import sys
sys.path.insert(1, '.')
__all__ = ['TabularApp',
'UserAdministrationApp',
'RegisterApp',
'FnAdminApp']
The problems pop up:
When main.pyw tries to from _apps import *.
In UserAdministrationApp.py i am trying to dynamically add tooltips to some QListWidget items like so:
for app in self.__APPS__:
app_icon = str(os.path.join(app_icons, f"{app}.png")).replace('\\', '/')
icon = QIcon(app_icon)
if app != self.__class__:
ttip_txt = eval(f'_apps.{app}.__doc__')
else:
ttip_txt = self.__doc__
item = QListWidgetItem(icon, app)
item.setText(app)
item.setToolTip(ttip_txt)
wdg.addItem(item)
The self.__APPS__ is just a copy of _apps.__all__.
The first problem I encountered was that i would get an AttributeError saying module x has no attribute y in ttip_txt = eval(f'_apps.{app}.__doc__') I resolved this by from _apps import * in UserAdministrationApp module. At this point I had already renamed this module for testing purposes and everything worked, but when I changed the name back to UserAdministrationApp.py I got another AttributeError saying module __apps has no attribute UserAdministrationApp.
Questions
I tried reading the python import docs but nothing in it really spoke to me.
I am sensing it has something to do with the script trying to import itself.
But i am still intrigued by these questions:
Why did the import fail in the first case, when i have import _apps?
Why in the second case does it not at least see itself and then produce an ImportError instead of AtributeError?
What is the optimal way to handle these types of situations?
Okay I found a solution, and though i think it is a bit dirty and not in best style, it works.
First
remove the from _apps import * and just from _apps import __all__.
Then
In initialization of the main class from the module UserAdministrationApp import in a loop skipping self.__class_.__name__
self.__APPS__ = _apps.__all__
self.class_name = self.__class__.__name__
for app in self.__APPS__:
if self.class_name != app:
exec(f'import _apps.{app}')
Finally
for app in self.__APPS__:
app_icon = str(os.path.join(app_icons, f"{app}.png")).replace('\\', '/')
icon = QIcon(app_icon)
if app != self.class_name:
ttip_txt = eval(f'_apps.{app}.__doc__')
else:
ttip_txt = self.__doc__
Having found the solution, I would still like to hear why the error was in the first place, for educational purposes.
So if anybody at any time glances over this and knows how to...you are more than welcome.
I have a check_login function in view module of django app named- userdata as shown below:
def check_login(request):
user_dict={}
cookieid=request.COOKIES.get('usercookie',None)
if cookieid is not None and cookieid :
u = UserDetails.objects.filter(uid=cookieid)
if u.exists():
user_dict['user']=u[0]
status=True
else:
status=False
else:
status=False
user_dict['cid']=cid
user_dict['login_status']=status
return user_dict
And i am trying to import it in another package as :
from userdata.views import check_login
but showing error.
All other functions from the same python_module could be imported except the function described above . what is wrong here ,why it couldn't be imported
import usage :
in trello apps' view:
from userdata.views import check_login
in userdata apps' view:
from trello.views import tr_ui
error occurance in 1st import of check_login
as pointed out by trnsnt
the problem was circular import :
in userdata app trello's view was called
from userdata.views import check_login
and
in trello app uderdata's view was called
from trello.views import tr_ui
if both imports are required then 1 can use local import instead of calling on top of the page as :
def trello_action(request):
from userdata.views import check_login
user_dict=check_login(request)
this solves the circular import problem
I'm trying to do a dynamic import of a python module in django. I have two different apps that I want to import from, and I want to replace these import statements:
from app1.forms import App1ProfileForm
from app2.forms import App2ProfileForm
I am dynamically able to create the strings App1ProfileForm and App2ProfileForm and then instantiate them like so:
globals()[form]()
I tried following some of the instructions in this post: Dynamically import class by name for static access
and so I tried doing this:
theModule = __import__("app1.forms.App1ProfileForm")
but I'm getting an error that says No module named App1ProfileForm
EDIT:::
Ok I tried this code:
theModule = __import__("app1")
print theModule
theClass = getattr(theModule,'forms')
print theClass
theForm = getattr(theClass,'App1ProfileForm')
print theForm
theForm.initialize()
but I get an error that type object 'App1ProfileForm' has no attribute 'initialize'
You don't want to do this. Imports are done when the relevant code is first executed - in the case of module-level imports, it's when the module itself is imported. If you're depending on something in the request, or some other run-time element, to determine what class you want, then this will not work.
Instead, just import them both, and get the code to choose which one you need:
from app1.forms import App1ProfileForm
from app2.forms import App2ProfileForm
forms = {'app1': App1ProfileForm,
'app2': App2ProfileForm}
relevant_form = forms[whatever_the_dependent_value_is]
I don't quite know how you're generting the string to import. I'll assume you generate the whole "path". Try this:
def import_from_strings(paths):
ret = []
for path in paths:
module_name, class_name = path.rsplit('.', 1)
module = __import__(module_name, globals(), locals(), [class_name], -1)
ret.append(getattr(module, class_name))
return ret
Aren't you trying to import a class, and not a module ? I'm not an expert, but I think you must import the module using __import__, then select it's App1ProfileForm class with something like yourmodule.App1ProfileForm
I figured it out. Here's how to do it:
theModule = __import__(module_name+".forms") # for some reason need the .forms part
theClass = getattr(theModule,'forms')
theForm = getattr(theClass,form_name)
then to initialize:
theForm() or theForm(request.POST)