I am working with phonenumbers module in Python. I am having the issue of circular import. This error omits whenever I run the file from desktop location (C:\Users\AsadA\Desktop). But it raises an error whenever I tried to run this in a particular folder (C:\Users\AsadA\Desktop\Python_projects\28-FindingTheNUMBER ). Please help me!
Sample Code:
import phonenumbers
from phonenumbers import geocoder
from phonenumbers import carrier
from phonenumbers import timezone
my_Num=phonenumbers.parse("SAMPLE_NUM")
print(geocoder.description_for_number(my_Num,'en'))
print(carrier.name_for_number(my_Num,'en'))
print(timezone.time_zones_for_number(my_Num))
ERROR:
Traceback (most recent call last):
File "c:/Users/AsadA/Desktop/Python_projects/28-FindingTheNUMBER/phonenumbers.py", line 1, in <module>
import phonenumbers
File "c:\Users\AsadA\Desktop\Python_projects\28-FindingTheNUMBER\phonenumbers.py", line 2, in <module>
from phonenumbers import geocoder
ImportError: cannot import name 'geocoder' from partially initialized module 'phonenumbers' (most likely due to a circular import) (c:\Users\AsadA\Desktop\Python_projects\28-FindingTheNUMBER\phonenumbers.py)
You might probably named your file as "phonenumber.py". If you are importing something in python, please make sure that file name is not same as imported file. If it is same, then it will create an error.
This happens due to same name conflict with imported file as imported file name is also the same. And if this occur then python always give priority to file with current directory you are working.
So, let say your code is something like below.
import xyz
print(xyz.version)
And your file name is "xyz.py". Python compiler now sees that there are two files of same name "xyz.py", one in script folder where python is installed and another in current directory we are working. So, python compiler compiler choose file to import from current directory you are working on.
So, python read first line import xyz, it imports the file from current directory which means it import again this file and start reading it. In that, again first line is import xyz, then it again imports xyz in current folder causing a loop to occur.
This is called as circular loop.
So, in short, changing your file name can solve the problem.
You are importing the module phonenumbers using 'import phonenumbers' and then you are importing the relevant definitions inside that module in the next few lines. They are redundant.
Fixed code:
import phonenumbers
my_Num=phonenumbers.parse("SAMPLE_NUM")
print(phonenumbers.geocoder.description_for_number(my_Num,'en'))
print(phonenumbers.carrier.name_for_number(my_Num,'en'))
print(phonenumbers.timezone.time_zones_for_number(my_Num))
Or something like this:
from phonenumbers import (
parse,
geocoder,
carrier,
timezone,
)
my_Num=parse("SAMPLE_NUM")
print(geocoder.description_for_number(my_Num,'en'))
print(carrier.name_for_number(my_Num,'en'))
print(timezone.time_zones_for_number(my_Num))
Related
My file is named "foo.py". It has only two lines.
import random
print(random.randint(10))
The error is...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/random.py", line 45, in <module>
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
File "math.py", line 2, in <module>
from random import randint
ImportError: cannot import name randint
I am on MacOS 10.14.6
I note that I did not call random.randint() in this script, even
though it showed up in the error text.
I ran the script with $python
My /usr/bin/python is linked to python 2.7
I've tried this with python 3 as well, with the same error.
EDIT:
My script was originally named "math.py", but I changed it in response to another solution that pointed out the name conflict with the math.py library (even though my script was not importing that library). Even after my script name change, I'm still seeing --File "math.py"-- errors. Even after I'm no longer using random.randint(), I'm still seeing that function referenced in my errors.
I've tried deleting random.pyc and math.pyc to purge the artifacts of previous executions. But these do not see to eliminate the remnants of earlier errors.
Read the traceback:
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/random.py"
Python tries to do something inside the standard library random module...
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
in particular, it tries to import the standard library math module...
File "math.py", line 2, in <module>
but it gets yours instead (notice there's no path on the filename this time; it's just math.py in the current directory); i.e. the script you started from. Python detects the circular import and fails:
ImportError: cannot import name randint
Actually using randint doesn't matter, because this is a problem with the actual import of the module.
This happens because Python is configured by default (using sys.path, which is a list of paths to try, in order) to try to import scripts from the current working directory before looking anywhere else. It's convenient when you just want to write a few source files in the same folder and have them work with each other, but it causes these problems.
The expected solution is to just rename your file. Unfortunately there isn't an obvious list of names to avoid, although you could peek at your installation folder to be sure (or just check the online library reference, though that's not quite so direct).
I guess you could also modify sys.path:
import sys
sys.path.remove('') # the empty string in this list is for the current directory
sys.path.append('') # put it back, at the end this time
import random # now Python will look for modules in the standard library first,
# and only in the current folder as a last resort.
However, this is an ugly hack. It might break something else (and it can't save you if you have a local sys.py).
My project path is like:
main.py
modules/
__init__.py
databaseManager.py
sync.py
excel.py
in main.py:
from modules.databaseManger import addExcelToDb, searchInDbAll
from modules.excel import search, showExcelDirContents
from modules.sync import syncExcelAndDB
and for example in database.py :
from modules.excel import showExcelDirContents
from modules.sync import insertExcelNameToSyncDb
but when I run main.py I get this error:
Traceback (most recent call last):
File "main.py", line 6, in <module>
from modules.databaseManger import searchIn
ImportError: cannot import name 'searchInDbAll'
and also having error when trying to import a function from each file in modules directory to others.
I need some examples of importing.
This is circular import issue.
Explanation:
You start by triggering import of databaseManager module.
During this databaseManager code starts to import excel.
During excel importing, excel code tries to retrieve function searchInDbAll() from databaseManager. But at that moment this function does not exist - because databaseManager is in process of importing excel and he hasn't started defining any functions.
How to fix:
In modules where circular import conflicts exist, import modules instead of functions. For example, change this:
from modules.excel import showExcelDirContents
to that:
from modules import excel
And of course, you must then change corresponding function calls, from showExcelDirContents() to excel.showExcelDirContents().
You must do this in your databaseManger, excel and sync modules. With this fix, I actually could run your code.
And yeah, remove appends to sys.path, that is wrong
You can append to your path where you put your modules like this:
import sys
sys.path.append('modules/')
or
import sys
sys.path.append('c:/mycode/stuff/modules/')
note those are forward slashes, or you can use double backslashes like \\
Then just have your databaseManger.py file in /modules
You'll also need to have a file in the /modules folder named:
__init__.py
Which is just an empty file
Then you should be able to do:
from databaseManger import addExcelToDb, searchInDbAll
I've been working on a project where I have a file which needs to call a function from a file in a sub package/directory, which in turn is calling a function from another file in the same sub package. As such, I have a main file which is importing a sub file. This sub file is also importing another sub file which is in the same package.
The first sub file has no issue whatsoever importing the second sub file. The main file also has no issue importing the first sub file. However, when I put it all together and run the main file, Python thinks that the second sub file doesn't exist, which I find strange. I've simplified and visualised my problem with an example below:
I have the following file hierarchy:
test_package\
__init__.py
main_file.py
test_sub_package\
__init__.py
subfile1.py
subfile2.py
main_file code:
import test_sub_package.subfile1
subfile1 code:
import subfile2
subfile2 code:
def get_string():
return ("Hello, World!")
So, I would expect main_file to import subfile2 via subfile1. However this doesn't seem to be the case because I get an error:
Traceback (most recent call last):
File "...\Test\main_file.py", line 1, in <module>
import test_package.subfile1
File "...\Test\test_sub_package\subfile1.py", line 1, in <module>
import subfile2
ModuleNotFoundError: No module named 'subfile2'
I was a little surprised that I got this error before I even attempted to call the functionality in subfile2. Either way, I'm confused why this doesn't work. Am I just doing something stupid here or am I trying to do something Python fundamentally doesn't support. If anyone can give me a solution it would be most appreciated.
I suspect this is probably a duplicate but I couldn't find an answer to my specific problem. So, sorry in advance.
When you import a module into another module from the same directory you must use must use a relative import in subfile1.py you will need to write:
from . import subfile2
Note, that doesn't give subfile 1 access to get_string to use it in subfile1, you would need to either write subfile2.get_string() or import it directly with:
from .subfile2 import get_string
I have tried this out and it works, I hope this helps :)
Note: that, if you are running a python script, and you need to import a module in that same directory, you can just say import module_name. It makes a difference if it is a script you are running, or a module that is being used in some other script. For a detailed explanation as to why see here
(I assume from your error message that you want to run main.py, if this is not the case you will need to change import test_sub_package.subfile1 to from . import test_sub_package.subfile1)
main file should be:
from test_sub_package.subfile1 import get_string
get_string()
subfile1.py
import test_sub_package.subfile2
I've found that I need to install 'glue' first.
But after that, this error is still there.
Traceback (most recent call last):
File "C:\Users\Saisa\Desktop\Code\python\myWebSpiderForPixiv_top100.py", line 1, in <module>
from gwpy.timeseries import TimeSeries
File "C:\Users\Saisa\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gwpy\timeseries\__init__.py", line 27, in <module>
from .core import *
File "C:\Users\Saisa\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gwpy\timeseries\core.py", line 45, in <module>
from ..data import (Array2D, Series)
File "C:\Users\Saisa\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gwpy\data\__init__.py", line 29, in <module>
from glue.lal import (Cache, CacheEntry)
ImportError: No module named 'glue.lal'
Here is another idea of what you could try:
If I understand right, your directory hieracy looks something like this:
\root
\glue
\lal
\other
\another
and in lal there are the functions and classes and whatever you want. Is lal a directory or a file? If it is a directory, I don't understand why It is not working, I just wrote a analogue code and for me it worked perfectly. Maybe ther error is somewhere entierely else, sh*t happens in python, too. But if it is a file like lal.py you don't have to tell from glue.lal import (whatsoever)! This whatsoever are functions then in one file. Just type from glue import lal, it will import everything in there.
Your Problem is that Python does not know where to find the module. You must add the path to the Path Browser where the module code is saved in and then you can use the
import themoduleyouwant
Or
from themoduleyouwant import *
command.
You can find the Path Browser under "File >> Option >> Path Browser"
Usually, it will show you the standard libraries and your current working directory (cwd). So if you are looking for a quick solution, just take the directory of 'glue' and copy+paste it into your cwd.
Result: The Error will disappear.
I have a simple test script:
import requests
response = requests.get('http://httpbin.org/get')
print response.text
It works when the python script is named test.py but fails if named email.py or logging.py:
Traceback (most recent call last):
File "./email.py", line 3, in <module>
import requests
File "/usr/lib/python2.7/dist-packages/requests/__init__.py", line 53, in <module>
from urllib3.contrib import pyopenssl
File "/usr/lib/python2.7/dist-packages/urllib3/__init__.py", line 16, in <module>
from .connectionpool import (
File "/usr/lib/python2.7/dist-packages/urllib3/connectionpool.py", line 59, in <module>
from .request import RequestMethods
File "/usr/lib/python2.7/dist-packages/urllib3/request.py", line 12, in <module>
from .filepost import encode_multipart_formdata
File "/usr/lib/python2.7/dist-packages/urllib3/filepost.py", line 15, in <module>
from .fields import RequestField
File "/usr/lib/python2.7/dist-packages/urllib3/fields.py", line 7, in <module>
import email.utils
File "/home/ubuntu/temp/email.py", line 4, in <module>
response = requests.get('http://httpbin.org/get')
AttributeError: 'module' object has no attribute 'get'
It appears that requests imports urllib3, which imports email built-in module. Why is Python not finding the built-in email module first, instead of looking in the current path for email.py?
Is there a way to make this work, or do I just have to always avoid naming my Python scripts any built-in module that may be imported by any dependency?
First, as you indicated in a comment, Python checks for a 'built-in' module of that name. Not all modules in the standard library are 'built-in'. You can see the list by:
print sys.builtin_module_names
If it's not found there, the order searched is outlined by Burhan's accepted answer here:
What is the extent of the import statement in Python
Python searches for things it can import in the following order:
From the directory where the script was executed.
From the directories in the PYTHONPATH environment variable (if its set).
From the system-wide Python installation's module directory.
In your case, email is not built-in, so the current directory is checked first.
So, yes, don't shadow a python library name. Technically you could shadow a built-in module's name, but please - please don't. It makes Python cry.
Take a look at sys.path and you'll see '' as the first entry:
>>> import sys
>>> sys.path
['',
'/.../3.3/lib/python33.zip',
'/.../3.3/lib/python3.3',
'/.../3.3/lib/python3.3/plat-darwin',
'/.../3.3/lib/python3.3/lib-dynload',
'/.../3.3/lib/python3.3/site-packages']
That '' is the current directory.
You could modify sys.path, but it's a wiser decision, long-term, to just not give python files names that match builtin modules.
The reason Python is looking for the modules in the current directory first is that that's how Python works. If you look at sys.path you will see that its first element is almost always '' which indicates the current directory. This applies to everything but the built-in modules, which are "imported" at interpreter startup. (They are not really imported, just assigned into sys.modules.)
In general, you are supposed to not name your own modules the same names as other modules you're using (whether they came with Python or not). I tend to put my initials on scripts I'm working with just to avoid this pitfall.
Of course, you can just manipulate sys.path so it doesn't look for modules in the current directory:
import sys
if not sys.path[0]:
del sys.path[0]
import requests
Note that you only need to remove the '' entry when you import. You should put it back after you do your imports, in case you need to import modules of the same name from your own script's directory. A context manager is handy for this.
import sys
from contextlib import contextmanager
#contextmanager
def no_cwd_imports():
old_path = sys.path[:]
if not sys.path[0]:
del sys.path[0]
try:
yield
finally:
sys.path[:] = old_path
with no_cwd_imports():
import requests
That's not a problem with Requests.
The "problem" comes from Python. email and logging are standard modules, it is not advisable to name your own modules same unless you understand and are willing to resolve conflicts.