__init__.py not working correctly in python - python

i want to make a sample package in python 2.7 just to clear my concepts whose structure looks like this:
calculator/
main.py
operations/
file1.py
file2.py
__init__.py
new_operations/
__init__.py
file3.py
main.py content: (this file is present inside calculator folder)
from operations import power
print power(2,2)
__init__.py content: (this file is present inside operations folder)
from .file1 import add
from .file1 import sub
from .file2 import mul
from .file2 import div
file1.py content: (this file is present inside operations folder)
def add(a,b):
return(a+b)
def sub(a,b):
return(a-b)
file2.py content: (this file is present inside operations folder)
def mul(a,b):
return(a*b)
def div(a,b):
return(a/b)
__init__.py content: (this file is present inside new_operations folder)
from .file3 import power
file3.py content: (this file is present inside new_operations folder)
def power(a,b):
return(a**b)
Now, when i run main.py, i got following error:
Traceback (most recent call last):
File "C:\Python27\mycodes\calculator\main.py", line 3, in <module>
from operations import power
ImportError: cannot import name power
Can anyone tell me, what mistake i am doing ? Help me.

Use the following line in your "main.py" file:
from operations.new_operations import power

You are missing an 'add' function in your calculator module. If you create an 'add' function, I would assume that the code would work.
maybe try doing this in the module calculator:
def add(num1,num2):
print(num1+num2)
return num1+num2;
If you don't want it to print while calculating, remove the print statement.
Hope this helps!

Related

Python unittest with test/ and src/ not finding src modules

I have a simple directory structure:
proj/
src/
__init__.py
foo.py
bar.py
test/
__init__.py
test_foo.py
test_foo.py
import unittest
import sys
sys.path.append('../src')
from src import foo
class TestFoo(unittest.TestCase):
def test_foo(self):
foo.start()
if __name__ == '__main__':
unittest.main()
foo.py
import bar
def start():
bar.do_stuff()
When running my test (I'm using vscode), I get the following error:
Failed to import test module: test_foo
Traceback (most recent call last):
File "~/.pyenv/versions/3.8.6/lib/python3.8/unittest/loader.py", line 436, in _find_test_path
module = self._get_module_from_name(name)
File "~/.pyenv/versions/3.8.6/lib/python3.8/unittest/loader.py", line 377, in _get_module_from_name
__import__(name)
File "~/proj/test/test_foo.py", line 6, in <module>
from src import foo
File "~/proj/src/foo.py", line 1, in <module>
import bar
ModuleNotFoundError: No module named 'bar'
I'm not sure why the test can't discover the src/bar when importing src/foo
Instead of import bar try from src import bar.
from src import bar
def start():
bar.do_stuff()
Notice
Keep in mind, that you only adjusted the path in the test. You do not want the tests to work, but the application to fail because you forgot to adjust the path in the application at some point.
What is in your bar.py file? Just the do_stuff() function? Or is the do_stuff() function a method of object bar?
Depending on the answer to the question above, try doing something like this in your foo.py file:
from proj.src.bar import [name of function you're testing here]
In your specific case, it would be like this if do_stuff() is a standalone function:
from proj.src.bar import do_stuff
and then your foo.py file would be:
from proj.src.bar import do_stuff
def stuff():
do_stuff()
However, if do_stuff() is a method of the bar object, it would probably be something like this, although it's hard to tell without knowing the contents of the bar.py file:
from proj.src.bar import bar
and then your foo.py file would be similar to the way you have it now:
from proj.src.bar import bar
def stuff():
bar.do_stuff()
I recently ran into a similar problem when trying to import one neighboring file into another. This link helped me out, too.
Two changes:
from src import bar in foo.py,
before import modules in test_foo.py, add
import sys
sys.path.append("./")
Then you should be able to run code successfully.
In my case, I had imports of modules which are not actually installed, in my bar.py file, such as:
import requests
After installing those modules, VSCode showed tests properly.

Python files not working proprely as modules (Just in VS code maybe?)

Before I show you the problem, I will give a simple example here:
(Please consider reading the whole problem and the important notes)
-Main folder: contains:
+main.py
+Extern modules folder (named ex_modules)
-Extern modules folder: contains:
+module1.py
+module2.py
main.py needs module1.py AND module2.py, but module1.py just needs module2.py
So I thought about importing module2.py into module1.py and then import module1.py into the main file, this is how I proceeded:
module2.py:
def module2_function1():
return something
def module2_function2():
return something2
def module2_function3():
return something3
module1.py:
from module2 import * #as I said, they are both in the same folder
def module1_function():
module2_function1()
module2_function2()
main.py:
from ex_modules.module1 import *
module1_function() #a module1 function that uses module2 functions
module2_function3() #a module2 function
VS code doesn't show any warnings when working on the main file
but this error occurs when I run it:
ModuleNotFoundError: No module named 'module2'
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
c:\some path xD\Main folder\main.py in <module>
----> 2 from ex_modules.module1 import *
3
4 module1_function()
5 module2_function3()
c:\some path xD\Main folder\ex_modules\module1.py in <module>
1
----> 2 from module2 import * #as I said, they are both in the same folder
3
4 def module1_function():
5 module2_function1()
ModuleNotFoundError: No module named 'module2'
This is due to the fact that it imports module2 (that is inside the ex_modules folder) as if it was in the main folder with main.py
I tried to import both modules in the main file as 'ex_modules.module1 and ex_modules.module2' and yeah, it doesn't work
The question is:
Is my syntax wrong? Or is this just a VS code bug?
The issue comes from running in the directory above ex_modules. Try changing the import in module1.py to a relative import:
from .module2 import *

A strange "No module named 'XX' " problem

I know how to import a package or module, but I meet a quite strange problem.
If I run swmm5_extend_function/example.py, everything is fine. However, when I run example.py, errors occur:
Traceback (most recent call last):
File "example.py", line 2, in <module>
from swmm5_extend_function.Swmm5Extend import SWMM5ReadInp
File "C:\project\swmm5_extend_function\Swmm5Extend.py", line 1, in <module>
import swig.SWMM5ReadInpFile as swmm
ModuleNotFoundError: No module named 'swig'
Here is my project structure:
project/
-- example.py
-- ......
-- swmm5_extend_function/
-- __init__.py
-- example.py
-- Swmm5Extend.py
-- swig/
-- __init__.py
-- SWMM5ReadInpFile.py
-- ....
Here is code of each .py file:
swmm5_extend_function/Swmm5Extend.py
import swig.SWMM5ReadInpFile as swmm
class SWMM5ReadInp(object):
pass
swmm5_extend_function/example.py
from Swmm5Extend import SWMM5ReadInp
example.py
from swmm5_extend_function.Swmm5Extend import SWMM5ReadInp
I want to know why this strange error happens.
For a better explanation, I've created the following folder structure:
test/
-- __init__.py
-- greeter.py # Greets in German
-- subfolder/
-- __init__.py
-- greeter.py # Greets in Italian
-- test.py
-- deepfolder/
-- __init__.py
-- greeter.py # Greets in France
As you may notice, we have 3 files with the same name, each one greets in a different language using a function with the same name. The only function in a greeter.py file is:
def says():
print("Hello World!")
IMPORT FROM THE SAME FOLDER
If from test.py file we import greeter and run the says function, we'll have:
import greeter as greeter
greeter.says()
Output:
Buongiorno Mondo! # Italian output
IMPORT FROM A SUBFOLDER
But what if we want to import from a subfolder?
To import from a subfolder (i.e., deepfolder/), we simply add an empty __init__.py file into the folder, then we can specify the path in the import:
import deepfolder.greeter as greeter
greeter.says()
Output:
Bonjour le Monde! # France output
IMPORT FROM A PARENT FOLDER
At last, you may want to import from a parent folder.
You should try to have your main running file at the top of the folder tree, but things happens and you find yourself looking to import a module from a parent folder.
For doing this, you need to add the parent folder to the sys.path:
import sys
sys.path.append("/path/to/dir")
from test import greeter as greeter
greeter.says()
Output:
Guten Morgen Welt! # German output
Importing scripts and modules isn't really the most pythonic way to solve things, you may want to have a look on Python's documentation about packages.
TL;DR
In your project/example.py use
import swmm5_extend_function.swig.SWMM5ReadInpFile as swmm
instead of
import swig.SWMM5ReadInpFile as swmm

import on Python doesn't work as expected

Although the variable should be imported, I get "name X is not defined" exception.
main.py
from config import *
from utils import *
say_hello()
utils.py
from config import *
def say_hello():
print(config_var)
config.py
from utils import *
config_var = "Hello"
Trying to run "main.py":
Traceback (most recent call last):
File "main.py", line 3, in
say_hello()
File "C:\Users\utils.py", line 3, in say_hello
print(config_var)
NameError: name 'config_var' is not defined
What happened here? Why some_var is not accessible from utils.py?
You are importing config in util and util in config which will causing this error(create cross loop). remove from utils import * from config.py and then try this.
And in main.py you don't need to import the from config import * unless you are using variables from config directly in your main()
you should also import config.config_var, since this variable belongs to that specific module
You are creating to many import statements perhaps try the following below, but also you need to define a parameter in utils.py if you are passing a parameter through there.
In utils.py we require a parameter to be passed since you want to print out the appropriate value, In config.py you are defining a value. Then in main.py as discussed before using the wildcard operator "*" isn't entirely good in this situation then in order to call the respective functions you need to address them through their file name
In utils.py :
def say_hello(config_var):
print(config_var)
In config.py
config_var = "Hello"
Then in main.py
import config as cn
import utils as ut
ut.say_hello(cn.config_var)
Check out this thread for how to write python modules as well How to write a Python module/package?

Why do I get ImportError when running the tests?

I am using Python 3 to try and get a test file for sample application working yet it keeps throwing ImportError: No module named 'calculate'
My file structure is:
/calculate
__init__.py
calculate.py
test/
__init__.py
calculate_test.py
I cannot figure out why this is the case, any help would be much appreciated.
The __init__.py files are empty.
calculate.py contains:
class Calculate(object):
def add(self, x, y):
return x + y
if __name__ == '__main__':
calc = Calculate()
result = calc.add(2, 2)
print(result)
calculate_test.py contains:
import unittest
from calculate import Calculate
class TestCalculate(unittest.TestCase):
def setUp(self):
self.calc = Calculate()
def test_add_method_returns_correct_result(self):
self.assertEqual(4, self.calc.add(2,2))
if __name__ == '__main__':
unittest.main()
I am running python test/calculate_test.py from the root /calculate folder and am getting the error
Traceback (most recent call last):
File "test/calculate_test.py", line 2, in <module>
from calculate import Calculate
ImportError: No module named 'calculate'
I have been fiddling around with different structures and cannot understand what the problem is.
Your project's structure is the reason. The test script doesn't have the outer directory in the search path when you start it. Here are some ways to fix that
Move the test file into the same directory that contains the module it imports. That will require no changes in the test file.
Use this structure
./project/
calculate_test.py
calculate/
__init__.py
calculate.py
This will require you to change the import signature in calculate_test.py to something like from calculate import calculate

Categories

Resources