This question already has answers here:
Running unittest with typical test directory structure
(24 answers)
Closed 23 days ago.
I met a strange problem in python package. I have a python package named manchinetranslator in which I created a subfolder for unit tests as shown below.
manchinetranslator/translator.py
manchinetranslator/__init__.py
manchinetranslator/tests/tests.py
In translator.py, two functions are defined as:
def english_to_french(text):
...
def french_to_english(text):
...
The init.py is:
from . import translator
The tests.py contains unit tests of the two functions in translator.py and is as follows:
import unittest
from translator import english_to_french, french_to_english
class Test_english_to_french(unittest.TestCase):
...
class Test_french_to_english(unittest.TestCase):
...
But when running tests.py, it gives an error as follows:
Traceback (most recent call last):
File "C:\Python\manchinetranslator\tests\tests.py", line 3, in <module>
from manchinetranslator.translator import english_to_french, french_to_english
ModuleNotFoundError: No module named 'manchinetranslator'
However, when tests.py is put in the same folder as translator.py, it works fine. I guess it may need to set $PYTHONPATH, but I am not sure how to do it. So I need help with this problem.
You are trying to import from the parent directory, that won't work. tests.py cannot import from translator because it is inside it.
See this SO answer instead for what to do: https://stackoverflow.com/a/24266885/30581
Related
This question already has answers here:
How to import python class file from same directory?
(2 answers)
Closed 7 months ago.
I have looked into other similar posts, but could not find an answer.
So,
Here is the structure of the project I am working on:
lyrics/__init__.py
lyrics/functions.py
manifold.py
When I execute manifold.py with this command:
./manifold.py
it calls:
import lyrics as lyr
which in turn calls init.py, which calls:
from lyrics import *
import functions
Here is the error that I get:
Traceback (most recent call last):
File "./manifold.py", line 20, in <module>
import lyrics as lyr
File "/g../__init__.py", line 2, in <module>
import functions
ModuleNotFoundError: No module named 'functions'
Any idea where the error comes from ?
Thanks
If you want to import relatively, you have to add the . before functions, i.e. from . import functions
The import there works similar to unix: The single dot is for the current directory. If you put two dots (..) you go up one level, three dots (...) goes up two levels and so on.
If you want to go absolute, then from lyrics import functions should work.
This question already has answers here:
Reimport a module while interactive
(7 answers)
Closed 1 year ago.
I have 2 Python files,
one is main.py (main code) and other is source.py (functions).
I import source.py into the main.py and call all the functions defined in source.py.
But when I write a new function at the run time, it will be shown in by the source.py's object but when called it shows an error.
# source.py
def fun1():
print('India is the best !!!!!!!!!')
def fun2():
print('Delhi is capital of India !!!!!!!!!')
# main.py
import source
source.fun1()
source.fun2()
This code runs properly.
When I add a new function to the source.py
def fun3():
print('Modi is India's Prime minister!!!!!!!')
If I import source.py again and call fun3() from main.py, It show the following error :
Traceback (most recent call last): File "", line 1, in AttributeError: module 'source' has no attribute 'fun3'
I want to know how to re-import the source.py so that it uses newly coded function without restarting the IDE I am using.
I am using Visual Studio 2017 for development in python
TIA
Thanks all of you to for your reply,
Problem solved after running following command:
import importlib
importlib.reload(source)
I have a custom Python library ("common") that is being imported and used from several Python projects.
That central library has the following structure:
/common
/__init__.py
/wrapper.py
/util
/__init__.py
/misc.py
Our custom library resides in a central place /data/Development/Python, so in my Python projects I have an .env file in order to include our lib:
PYTHONPATH="/data/Development/Python"
That works fine, I can for example do something like:
from common.util import misc
However, now I want to make use of a class MyClass within common/wrapper.py from the code in common/util/misc.py. Thus I tried the following import in misc.py:
from ..wrapper import MyClass
But that leads to the following error:
Exception has occurred: ImportError
cannot import name 'MyClass'
Any ideas what I am doing wrong here?
PS: When I do an from .. import wrapper instead and then from code I use wrapper.MyClass, then it works fine. Does that make any sense?
It's finding wrapper, otherwise you'd get a different error:
>>> from wibble import myclass
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'wibble'
So it seems wrapper does not contain MyClass. Typo?
"However, now I want to make use of a class MyClass within common/wrapper.py from the code in common/util/misc.py. Thus I tried the following import in misc.py:"
If you do export PYTHONPATH=~/common
In order to import MyClass you will do:
from wrapper import MyClass
Because you have added common to your root folder, utils is already in your path since it is in you root folder.
Similarly, if you wanted to import from wrapper you would do from utils.misc import ThisClass since utils.misc is already in the root folder common
I am currently doing a personal coding project and I am trying to build a module, but I don't know why my structure doesn't work the way it's supposed to:
\mainModule
__init__.py
main.py
\subModule_1
__init__.py
someCode_1.py
someCode_2.py
\subModule_2
__init__.py
otherCode.py
I want to be able to run the following code from main.py:
>>> from subModule_1 import someCode_1
>>> someCode_1.function()
"Hey, this works!"
>>> var = someCode_2.someClass("blahblahblah")
>>> var.classMethod1()
>>> "blah blah blah"
>>> from subModule2 import otherCode
>>> otherCode("runCode","#ff281ba0")
However, when I try to import someCode_1, for example, it returns an AttributeError, and I'm not really sure why. Is it to do with the __init__.py file?
REVISIONS
Minimal, Complete and verifiable (I hope...)
\mainDir
__init__.py # blank file
main.py
\subDir
__init__.py # blank file
codeFile.py
Using this...
#main.py file
import subDir
subDir.codeFile.function()
And this...
#codeFile.py file
def function():
return "something"
...it returns the same problem mentioned above**.
** The exact error is:
Traceback (most recent call last):
File "C:\...\mainDir\main.py", line 2, in <module>
subDir.codeFile.function()
AttributeError: module 'subDir' has no attribute 'codeFile'
Credits to #jonrsharpe: Thanks for showing me how to use Stack Overflow correctly.
You have two options to make this work.
Either this:
from subdir import codeFile
codeFile.function()
Or:
import subdir.codeFile
subdir.codeFile.function()
When you import subDir, it does three things:
executes the code in mainDir/subDir/__init__.py (i.e. in this case does nothing, because this file is empty)
imports the resulting module under the name subDir locally, which will in turn make it an attribute of the mainDir module;
registers the new import globally in the sys.modules dictionary (because the import is being performed from a parent module mainDir, the name is completed to 'mainDir.subDir' for the purposes of this registration);
What it does not do, because it hasn't been told to, is import subDir.codeFile. Therefore, the code in codeFile.py has not been run and the name codeFile has not yet been imported into the namespace of mainDir.subDir. Hence the AttributeError when trying to access it. If you were to add the following line to mainDir/subDir/__init__.py then it would work:
import codeFile
Specifically, this will:
run the code in codeFile.py
add the resulting module as an attribute of the mainDir.subDir module
store a reference to it as yet another entry in sys.modules, this time under the name mainDir.subDir.codeFile.
You could also achieve the same effect from higher up the module hierarchy, by saying import subDir, subDir.codeFile instead of just import subDir in your mainDir.main source file.
NB: When you test this from the command line or IDE, make sure that your current working directory (queried by os.getcwd(), changed using os.chdir(wherever) ) is neither mainDir nor subDir. Work from somewhere else—e.g. the parent directory of mainDir. Working from inside a module will lead to unexpected results.
I must be missing something very basic about building a package in Python. When I create a package following the guidelines of https://docs.python.org/2/tutorial/modules.html#packages and import it, Python does not find any of the modules. For example, say I create the package holygrail with the following structure:
holygrail/
__init__.py
knights.py
I leave __init__.py empty because the docs say that I can and I'm just trying to make a basic package to start. In knights.py I have:
def say():
print 'Ni!'
If I try import holygrail, Python doesn't give any errors, but holygrail.knights.say() results in Python telling me that the "'module' object [holygrail] has no attribute 'knights'." However, if I specifically import knights via from holygrail import knights, then knights.say() works. In addition, holygrail.knights.say() then also works.
I tried adding the line
__all__ = ['knights']
in the __init__.py file, but this did not change the behavior.
How do I construct a package such that import package loads in all of the modules, allowing statements like package.module.function()?
Python does not implicitly import the whole package hierarchy. You have to be explicit about what to import on what level of the package using the __init__.py files.
When you set __all__ = ['knights'] in the __init__.py it works only for the import all statements for that module, e.g.:
>>> import holygrail
>>> holygrail.knights.say()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'knights'
>>> from holygrail import *
>>> knights.say()
Ni!
It can also act as a filter on import all, importing from the module only what's specified.
To get knights automatically imported on import holygrail you have to put import knights or from . import knights (intra-package or relative import) to the __init__.py. You'll have to do the same for every module explicitly.
Add import knights into __init__.py.
The link you provided does state "In the simplest case, __init__.py can just be an empty file..." Your example is not the simplest case, that's all.