Python - Structuring an application with tests - python

I want to create the following structure for a simple app, i am having some trouble with imports:
Suggested structure: (Its the "Installable Single Package" from various sites)
/myapp
/helloworld
__init__.py
helloworld.py
utils.py
/tests
__init__.py
test_helloworld.py
test_utils.py
With helloworld.py:
import sys
import utils
def hello_world():
print("Hello world")
if __name__ == '__main__':
utils.util()
and utils.py:
def util():
print("util")
and test_helloworld.py:
import sys
sys.path.insert(0,'..')
from helloworld.helloworld import hello_world
from helloworld.utils import util
hello_world()
When i attempt to run helloworld.py it runs normally.
When i attempt to run test_helloworld.py i get this error:
Traceback (most recent call last):
File "test_helloworld.py", line 8, in <module>
from helloworld.helloworld import hello_world
File "..\helloworld\helloworld.py", line 3, in <module>
import utils
ModuleNotFoundError: No module named 'utils'
I think this is due to some relative path error, the only way i ve found to fix this was to alter the helloworld.py to be like:
import sys
# import utils
def hello_world():
print("Hello world")
if __name__ == '__main__':
import utils
utils.util()
and then they both run. Is there a way to do this import better? Is this a problem that i will not have to address if i construct unittests in "test_helloworld.py" and run it with unittest?

Related

Issues with importing from submodules

I've got a project with the following structure:
\main_model
__init__.py
main.py
\second_module
__init__.py
second.py
\third_module
__init__.py
third.py
second_module and third_module are both Git submodules used as libraries by many other projects.
The first line of main.py is an import statement: from main_model.second_module import second
And the first line of second.py is too: from second_module.third_module import third
Running main.py raises an error with the following Traceback:
Traceback (most recent call last):
File "/main_model/main.py", line 1, in <module>
from main_model.second_module import func_a, func_b
File "/main_model/second_module/second.py", line 1, in <module>
from third_module.third import func_c, func_d
ModuleNotFoundError: No module named 'third_module'
So evidently I would need to amend the import statement in second.py to be from main_model.second_module.third_module import third. I can't do that, though, because second_module is a standalone submodule.
Is there a consistent way of structuring the imports, or modifying PYTHONPATH, that would allow the same import syntax from all levels?

Python Import Error: I am getting error when importing function from package. Import error on test.py when performing mymath.multiply()

This is my Directory Structure:
test.py
mymath/
__init__.py
mymath.py
test.py
import mymath
mymath.multiply()
__init__.py
from mymath
import multiply
mymath.py
def multiply():
When I run:
python3 test.py
I get the error:
Traceback (most recent call last):
File "test.py", line 2, in <module>
import mymath
File "/home/kcb/python-scripts/mymath/__init__.py", line 1, in <module>
from mymath import multiply
ImportError: cannot import name 'multiply'
When you run python myscript.py, the current working directory directory is added to your module search path, and thus any modules in that directory are importable.
However, when mymath/__init__.py tries to do from mymath import multiply, it can't find mymath.py, because mymath/ is not in your module search path.
The best solution is to change mymath/__init__.py to use a different import statement:
from .mymath import multiply
This means "import multiply from a module named mymath in the same directory as this module."

How to specify an import path when the file is called from different directories?

I am facing an issue that is related to import path. I have a library file (func_a.py) as follows. This file is called from different directories. In such a case, how do I specify import path in client.py?
.
├── main.py
└── package_a
├── __init__.py
├── client.py
└── func_a.py
The codes are as follows:
$ cat package_a/func_a.py
def something():
print('something')
$ cat package_a/client.py
import func_a
func_a.something()
$ cat main.py import package_a.func_a as func_a
import package_a.client as client
func_a.something()
This is the error. When I call client.py, the file misses func_a.py since the current directory is the root, not package_a/.
$ python main.py Traceback (most recent call last):
File "main.py", line 2, in <module>
import package_a.client as client
File "/home/jef/work/test/package_a/client.py", line 1, in <module>
import func_a
ModuleNotFoundError: No module named 'func_a'
My python is 3.6. Thank you for your help.
Update
Although calling main.py is OK, calling client.py failed. I make both work.
$ cat client.py
from package_a import func_a
func_a.something()
$ python client.py
Traceback (most recent call last):
File "client.py", line 2, in <module>
from package_a import func_a
ModuleNotFoundError: No module named 'package_a'
$ cat package_a/client.py
import func_a
^ This import statement is incorrect. To import the func_a module from the package_a package, use this import statement instead:
from package_a import func_a
You will need to ensure that the directory containing package_a is visible in sys.path.

Why can `__init__.py` import a submodule but a test file with `from module import *` can't?

I have the following folder structure.
project/
sandbox.py
module/
__init__.py
klass.py
__init__.py has the following:
from klass import Klass
if __name__ == '__main__':
'do stuff'
This works fine. sandbox.py looks like this:
from module import *
if __name__ == '__main__":
'do similar stuff'
On the command line, while in the project directory:
$ python module/__init__.py
# things work correctly
$ python sandbox.py
Traceback (most recent call last):
File "sandbox.py", line 1, in <module>
from module import *
File "/Uses/chuck/.../project/module/__init__.py, line 1 in <module>
from klass import Klass
ImportError: No module named 'klass'
I think this might have to do with relative imports, and tried changing from klass import Klass to from .klass import Klass, but that didn't work either.
My goal is, from files outside the module, to be able to use from module import * or from module import Klass. What do I need to do?
In case it matters, this is with Python 3.5.2 under macOS within a virtual environment.
Use absolute path and __main__.py file for this:
from module.klass import Klass
'do stuff'
In __init__.py:
from .klass import Klass
Now you can execute it as follows:
$ python sandbox.py
do similar stuff
$ python -m module
do somthing

Running python from command line gives import error

I want to run my python program from command line but it gives me below error
ImportError: No module named 'main'
My folder structure is as below
Project
|-----main
|-----__init__.py
|-----S3Operations.py
|-----BusinessOperations.py
My init.py code is as below
import sys
from S3Operations import Models
sys.path.append("D:/code/Project/main")
if __name__ == '__main__':
s3=Models()
s3.test()
And my S3Operations.py code is
import os.path
from main import BusinessService
class ModelsMlS3(object):
def test(self):
print("Testing success")
When I run the program using command line i get the below error
$ python __init__.py
Traceback (most recent call last):
File "__init__.py", line 2, in <module>
from S3Operations import ModelsMlS3
File "D:\code\Project\main\S3Operations.py", line 11, in <module>
from main import BusinessService
ImportError: No module named 'main'
Can any one please suggest a solution for the same.
You just need to do:
import BusinessService # instead of `from main import BusinessService`
as in your project, there is no __init__.py file present in Project directory (which holds main.py).
For importing it like:
from main import BusinessService
you need to create __init__.py in the folder in order to make it as module.

Categories

Resources