Python not able to find my module even it exists - python

My folder structure is
fold1/fold2/a.py
fold1/fold3/b.py
fold1/fold3/c.py
a.py is doing
from fold1.fold3 import c
c.py is doing
import b
When I run a.py, I am getting error "No module named b"
I have __init__.py in all folders, but still why I am getting that error.
I know that lastly python checks for packages in current directory, so here current directory is "fold2" and I am not finding "b.py" in that fold2? but both "c.py" and "b.py" are in same directories right but still why I am getting that error?
Edit: The code is generated by pyxb python module, so I cannot change import statements.

import b is an absolute import: b has to be found in a package listed in sys.path.
In order to import b relative to the package containing c, use the relative import
from . import b
. refers to the package containing c (fold3). .. would refer to the package containing that package (fold1). You could also write
from ..fold3 import b
.. refers to fold1, so ..fold3 refers to the module fold3 in the package fold1.
When using relative imports, it doesn't matter where fold1 exists: it could be in sys.path, it could be a submodule of some other package. As long as the internal structure of fold1 remains the same, the relative imports will continue to work the same.

All the paths are relative to where you start the interpreter from!
c.py is looking for b in the parent of fold1
try using a form like from fold1.fold3 import b instead

Related

cannot import submodule from a module [duplicate]

This question already has answers here:
Attempted relative import with no known parent package [duplicate]
(4 answers)
Closed 1 year ago.
I am having following structure for my project
Object_Detection/
setup.py
setup.cfg
requirement.txt
object_detection/
models
__init__.py #contains from . import models
tests/
# inside tests dir
test_utils_image.py
__init__.py #empty
utils/
# inside utils dir
__init__.py #inside
utils_image_preprocess.py
utils_image.py
utils_tfrecord.py
Now init.py inside utils directory contains the following code.
# inside __init__.py
from . import utils_image_preprocess
from . import utils_image
from . import utils_tfrecord
Running above init.py files gives me an error:
ImportError: attempted relative import with no known parent package
test_utils.py inside tests dir contains the following code
# inside test_utils.py
from object_detection.utils import utils_image
While running test_utils.py I got the following error
ImportError: cannot import name 'utils_image' from 'object_detection.utils'
I have gone through this and this and tried to follow every aspect mentioned there but details about what to put inside init.py is not clear.
This problem seems to be associated with the structuring of init.py in different dir.
I have gone through various and got to know that if we keep even an empty init.py file then things will work out but I am not sure about my understanding.
Please let me know
what I am missing here and whether I am following the correct structure for packaging my code or not?
How to resolve these two errors?
Is this issue related to setting up source in IDE as I am using Vscode and I have also seen this has been mentioned at many places. See here? (But also tried the same code with PyCharm and encountered same error )
If you want to be able to say ...
from object_detection.utils import utils_image
... then clearly the utils directory must be a subdirectory of the object_detection directory and not a sibling directory, i.e. at the same level.
Now for your other error:
ImportError: attempted relative import with no known parent package
You did not really specify under what circumstances you get this error other than saying "Running above init.py files gives me an error:". But how are you "running" these py files or what does that even mean?
If you are executing a script when this occurs (how else would you be getting this error?), the script must be invoked as a module (because scripts cannot have relative imports -- see below) as follows (we will assume that the script you are trying to execute is test_utils_image.py):
First, the parent directory of object_detection, which is Object_Detection, must be in the system path of directories to be searched for finding modules and packages referenced in import statements. In general, this can be accomplished several ways, for instance
The script you are executing is in Object_Detection (the directory of the script is automatically added to the sys.path list of directories to be searched by the interpreter).
Dynamically appending Object_Detection to the sys.path list of directories at runtime by your script.
Appending Object_Detection to the PYTHONPATH environment variable.
Item 1 above would not be applicable for this specific case since the module we are executing by definition is not in the Object_Detection directory.
Note that if your classes will eventually be installed with pip, then site-packages will be the parent directory of object_detection, which is already in sys.path.
Then you can execute your script as:
python -m tests.test_utils_image
If you want to execute this .py file as a script, for example by right-mouse clicking on it is VS Code, then see Relative imports for the billionth time, in particular the section Scripts can't import relative, which says it all -- it cannot work!
To invoke this as a script, just convert the relative imports to absolute imports. In fact, the PEP 8 Style Guide says:
Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages) if the import system is incorrectly configured (such as when a directory inside a package ends up on sys.path):
Have you tried to do the following?
inside your utils __init__.py import your modules as follows:
from .utils_image_preprocess import <func1>... <rest of functions/classes you want to import>
from .utils_image import <func1>... <rest of functions/classes you want to import>
from .utils_tfrecord import <func1>... <rest of functions/classes you want to import>
And then in your test file do:
from object_detection.utils.utils_image import *
OR
from object_detection.utils.utils_image import <func1>,...
Also, make sure you don't have any circular dependencies in your modules. for example importing of function from your tests to your util module and vise versa
Python3 has two types of packages
Regular Packages
Namespace Packages
Regular packages contains init.py and namespace packages don't need to have init.py
Regarding your folder structure, it is correct, no change needed. You just need to import like this
from utils import utils_image
without mentioning the objects_detection as objects_detection is just a namespace package.
So it would be usefull when you would refer to the utils module from outside the objects_detection folder.
Here what python docs say about the namespace packages:
A namespace package is a composite of various portions, where each portion contributes a subpackage to the parent package.

Python Imports Not Working with Directories

I am having trouble importing python modules in a different folder than the one I am using. I know there are a number of posts about this on StackOverflow, but I am still running into a few issues with importing. Here is my general file structure:
Folder
__init__.py
A.py
folder
__init__.py
B.py
tests
__init__.py
C.ipynb
I am trying to import B from C, but doing so gives me a number of errors. If I write
from folder import B
I get
ModuleNotFoundError: No module named 'folder'.
If I write
from . import B
I get
ImportError: attempted relative import with no known parent package.
If I write
from . import B
or
from .. import B
I get
ImportError: attempted relative import with no known parent package.
Additionally, if I try to import B from A, I also get errors. Running
import folder.B
or
from folder import B
gives
ModuleNotFoundError: No module named 'folder'.
Could someone help me import these files correctly? I know that modifying sys.path is an option (although I am not entirely sure how to implement this), but I feel like there must be a way to do this without modifying sys.path.
Thank you, and I apologize if this has been answered already!

Moving python package without messing internal imports

I wrote a python package that includes many modules. The modules import each other within the package.
Now after it is complete I wish to move my package inside a different package as a subdirectory. But I can't do it because now all the imports get errors because they can't find the modules on their new path.
For example -
In module my_package.a I have:
x = 5
In module my_package.b:
from my_package.a import x
print x
Before I did: from my_package import b, and now I wish to do from tools.my_package import b, and get the same result.
What is the right way to change a package logic path without having to add the new path to sys.path?
I would use relative imports internally:
from .a import x
If your module is self-contained, you can relocate it without issues if it uses relative imports.

pydev - how to avoid adding sub directories to python path in order to fix unresolved import issue

My project has root src folder created by pydev project wizard. Src folder is in the project's python path. Underneath that folder I have a package (folder with __init__.py) with two files: a.py and b.py. b.py is trying to import from a.py but I'm getting the error of unresolved import.
I was able to "fix" error by explicitly adding that subfolder to project's python path as additional src folder. Now I have two folders as src folders in pythonpath. What I don't understand is, why pydev is not able to resolve import since the package/folder I'm talking about is directly underneath root src folder which is in the python path. There are no python files in root src folder.
If I add __init__.py to root src folder, the issue is still there. I simply have to add subfolder to pythonpath in order to make error go away.
Am I doing something wrong ? This doesn't seem right.
EDIT:
I was wrong. My import syntax was incorrect. I should have done: from package.module import someting and not from module import something
It's hard to tell from your description, and actual code would help, but I suspect what you're looking for is a relative import.
If you have a file pkg/a.py that just does this:
import b
That will look for a top-level module somewhere on your sys.path named b.py.
But if you do this:
from . import b
Then it will look within (and only within) pkg for a file named b.py.
Alternatively, you could use an absolute import, the same way you would in a module outside the package, like one of these:
import pkg.b
from pkg import b
Your attempted workaround of adding pkg to sys.path is a very bad idea, for multiple reasons. For example, b and pkg.b will become different modules as far as Python is concerned, so the top-level code can end up getting run twice, you can end up with two separate copies of all of the globals (and even if you think "I'm not using globals", you probably as—classes and functions are globals, and you can easily end up with a situation where b.MyClass(3) != pkg.b.MyClass(3) unexpectedly, which is always fun to debug…), etc.
Adding an __init__.py to src is also a bad idea. That turns src into a package, meaning the proper qualified name for b is now src.pkg.b, rather than pkg.b, but there's no way to import it under the proper name (unless the parent directory of src happens to be on sys.path as well as src… in which case you have the exact same problem as the above paragraph).
See PEP 328 for more details, and the tutorial section on Packages for a simpler overview.

Python cannot import name if placed in module [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to do relative imports in Python?
I'm experiencing something that seems very random to me.
I have a folder structure much like this:
dir A
__init__.py is empty
a.py imports stuff and b.py
dir B
__init__.py is empty
b.py imports NOTHING
a.py raises an error (cannot import name b). This only happens while b is part of module B.
If I move it outside the directory, the import error does NOT occur.
Any help would be appreciated. I must be overlooking something.
Did you try the relative import
from ..B import b
?
EDIT: This does not apply if it doesn't matter where package B lives.
But you don't describe what exactly you do. As you may know or not, there are several import forms:
import module
import package # imports package.__init__ under the name package
import package.module
from package import module
import package
from module import component
from package.module import component
As you only write
a.py imports stuff and b.py
I don't know what exactly happens: if you try to
import b
that fails because b lives in the package B. So you need one of
from B import b
import B.b
Your comment above mentions a name clash. Which of two equally named packages and modules have priority depends on in which directory you are: '.' is normally at the very start of sys.path, so if you are directly under your utils directory you might have a different experience than otherwise.

Categories