python import relative path 'No module found error' - python

I am in folder2 trying to execute trigger.py
I used:
from ..folder1.subfolder1.function1 import *
from ..folder1.test.py
got error attempted relative import with no known parent package

If you're running out of folder2, then for all practical purposes, trigger.py is a module on its own, not part of a package hierarchy, and can't use relative imports to folder1 (because they're unrelated).
If you can, make your working directory the parent directory of Project, and invoke your script with:
python3 -m Project.folder2.trigger
which runs a module as the main entry point via import syntax, without losing the information on the package structure.
If the whole project is actually installed to system or user site-packages, your working directory won't matter (it's only needed if it's not in sys.path automatically, because the working directory itself is included in sys.path), and the invocation will work anywhere.

Related

Importing python script from some directory with dependent scripts

I have the following problem and would like to ask you what is the best way to solve it.
I the following structure of files:
Main Folder
1.1 Subfolder1
1.1.1 SubSubfolder1
I have main python script in main folder, and other sripts in subfolders, which are importing some other scripts from subsubfloders.
I need to run the main script in Main Folder, which is importing scripts from subfolders.
Each subfolder is standalone, and I just need to import and run scripts available in subfolders (which themselves are importing some other scripts).
I am getting an error because when I import scripts, the running directory is not changing automatically when the script is called.
So I need that if the script is imported, the dependent scripts were imported from the relative path.
Thanks
I believe using sys.path.append method from sys built-in module should work.
Here is the syntax :
sys.path.append(YourPath)
import YourScript
please note that your path should not lead to a file, but to a folder

PyCharm ModuleNotFoundError? [duplicate]

I am having a problem running my script in a cmd prompt despite it working in PyCharm. I have a folder structure as such:
MyCode # PyCharm project folder
/UsefulFunctions
/Messaging
/Texter.py
/DiscordBot
/DiscordBot.py
Within DiscordBot.py I have an import
from UsefulFunctions.Messaging import Texter
This works when I run it from PyCharm without a problem. However when I try to run from a command prompt located at the DiscordBot level it errors with:
ImportError: No module named 'UsefulFunctions'
So naturally I thought it meant that the UsefulFunctions folder was not on my path. Therefore, I went into my environment variables and added it to my PATH variable (as well as the MyCode folder for good measure). Still it encountered this error. I browsed some posts on here regarding imports (mainly Importing files from different folder) and they recommend doing something like:
import sys
sys.path.insert(0, '/path/to/application/app/folder')
import file
Or adding __init__.py files to each folder in order to get them to register as packages. I went ahead and added __init__ files to each folder and subfolder I was trying to import from, but still could not run from the command prompt...I ommitted the sys.path.insert() solution because I see no benefit from this after already explicitly adding it to my PATH variable. Another solution was to add "." before the import because supposedly otherwise it is only searching python's PATH. I attempted this as:
from .UsefulFunctions.Messaging import Texter
ImportError: attempted relative import with no known parent package
And this error shows on PyCharm now as well... I don't get why my initial script would work without a hitch on PyCharm, but the same program cannot seem to find my import when run from a prompt. Can somebody please explain the difference between PyCharm running the program and my prompt? Why will this not work despite having __init__.py files and having added MyCode and UsefulFunctions to my PATH variable on Windows?
From [Python.Docs]: Command line and environment - PYTHONPATH:
Augment the default search path for module files. The format is the same as the shell’s PATH: one or more directory pathnames separated by os.pathsep (e.g. colons on Unix or semicolons on Windows). Non-existent directories are silently ignored.
You can also find more details on [SO]: Strange error while using Pycharm to debug PyQt gui (#CristiFati's answer).
So, in order for Python to be able to load a module (package) without specifying its path, the path must be present in %PYTHONPATH% environment variable.
You mentioned %PATH% several times in the question but it's %PYTHONPATH% (MyCode must be added to it).
PyCharm does that because of (any of) the 2 checkboxes in the image below (dialog can be triggered from the menu: Run -> Edit Configurations...):
If you want to get things working from CmdLine, yo have to do the same thing there as well:
[cfati#CFATI-5510-0:e:\Work\Dev\StackOverflow\q054955891\DiscordBot]> sopr.bat
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###
[prompt]> set py
Environment variable py not defined
[prompt]> "e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" DiscordBot.py
Traceback (most recent call last):
File "DiscordBot.py", line 1, in <module>
from UsefulFunctions.Messaging import Texter
ModuleNotFoundError: No module named 'UsefulFunctions'
[prompt]> set PYTHONPATH=e:\Work\Dev\StackOverflow\q054955891
[prompt]> set py
PYTHONPATH=e:\Work\Dev\StackOverflow\q054955891
[prompt]> "e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" DiscordBot.py
e:\Work\Dev\StackOverflow\q054955891\UsefulFunctions\Messaging\Texter.py imported
Conversely, in PyCharm (with the content roots related checkbox from above, checked), more content roots can be added like in the image below (menu: File -> Settings..., select Project Structure then Add Content Root):
This is useful when some required modules are located deeper in the project tree (and some dirs aren't valid Python package names).
So, when dealing with this type of situation, checking [Python.Docs]: sys.path, [Python.Docs]: os.getcwd() and module path, can save lots of wasted time and headaches:
import os
import sys
print(sys.path)
print(os.getcwd())
import some_module
print(some_module)
As a side note, I personally hate names starting with My (e.g. MyCode). Such a name tells me that the purpose of whatever entity "wears" it, was not clear to the person who wrote the code. Try finding a more useful name (e.g. TestBotProject, or smth similar) :).
[SO]: PyCharm doesn't recognize installed module (#CristiFati's answer) might also contain some useful info.
Python uses the system variable PYTHONPATH, among other things, to decide what to import.
From the docs:
When a module named spam is imported, the interpreter first searches
for a built-in module with that name. If not found, it then searches
for a file named spam.py in a list of directories given by the
variable sys.path. sys.path is initialized from these locations:
The directory containing the input script (or the current directory
when no file is specified).
PYTHONPATH (a list of directory names,
with the same syntax as the shell variable PATH).
The installation-dependent default.
The reason PyCharm magically imports the module when you run the script is because of the Project Structure -> Content Root value. It points to your project directory, by default.
Check your Interpreter. It is different than your command prompt Interpreter, located in Appdata, whereas the interpreter for PyCharm is in the Workspace folder.
Set your Python path in System variables,So that you can run python -help from any where in directory
then
navigate to project folder
c:\nnnn..\mmm..\MyCode
run python c:\nnnn..\mmm..\MyCode\DiscordBot
\DiscordBot.py
or
C:\Python27\python.exe "C:\Users\Username\MyCode\DiscordBot
\DiscordBot.py" or
C:\Python27\python.exe C:\Users\Username\MyCode\DiscordBot
\DiscordBot.py
Try quotes if path has space

ModuleNotFoundError when running script from Terminal

I have the following folder structure:
app
__init__.py
utils
__init__.py
transform.py
products
__init__.py
fish.py
In fish.py I'm importing transform as following: import utils.transform.
When I'm running fish.py from Pycharm, it works perfectly fine. However when I am running fish.py from the Terminal, I am getting error ModuleNotFoundError: No module named 'utils'.
Command I use in Terminal: from app folder python products/fish.py.
I've already looked into the solutions suggested here: Importing files from different folder, adding a path to the application folder into the sys.path helps. However I am wondering if there is any other way of making it work without adding two lines of code into the fish.py. It's because I have many scripts in the /products directory, and do not want to add 2 lines of code into each of them.
I looked into some open source projects, and I saw many examples of importing modules from a parallel folder without adding anything into sys.path, e.g. here:
https://github.com/jakubroztocil/httpie/blob/master/httpie/plugins/builtin.py#L5
How to make it work for my project in the same way?
You probably want to run python -m products.fish. The difference between that and python products/fish.py is that the former is roughly equivalent to doing import products.fish in the shell (but with __name__ set to __main__), while the latter does not have awareness of its place in a package hierarchy.
This expands on #Mad Physicist's answer.
First, assuming app is itself a package (since you added __init__.py to it) and utils and products are its subpackages, you should change the import to import app.utils.transform, and run Python from the root directory (the parent of app). The rest of this answer assumes you've done this. (If it wasn't your intention making app the root package, tell me in a comment.)
The problem is that you're running app.products.fish as if it were a script, i.e. by giving the full path of the file to the python command:
python app/products/fish.py
This makes Python think this fish.py file is a standalone script that isn't part of any package. As defined in the docs (see here, under <script>), this means that Python will search for modules in the same directory as the script, i.e. app/products/:
If the script name refers directly to a Python file, the directory
containing that file is added to the start of sys.path, and the file
is executed as the __main__ module.
But of course, the app folder is not in app/products/, so it will throw an error if you try to import app or any subpackage (e.g. app.utils).
The correct way to start a script that is part of a package is to use the -m (module) switch (reference), which takes a module path as an argument and executes that module as a script (but keeping the current working directory as a module search path):
If this option is given, [...] the current directory
will be added to the start of sys.path.
So you should use the following to start your program:
python -m app.products.fish
Now when app.products.fish tries to import the app.utils.transform module, it will search for app in your current working directory (which contains the app/... tree) and succeed.
As a personal recommendation: don't put runnable scripts inside packages. Use packages only to store all the logic and functionality (functions, classes, constants, etc.) and write a separate script to run your application as you wish, putting it outside the package. This will save you from this kind of problems (including the double import trap), and has also the advantage that you can write several run configurations for the same package by just making a separate startup script for each.

Import Error: Python Unit Tests, on Jenkins

I have a few unit tests, which I wrote in Python 2.7. (On PyCharm)
All of these test run locally just fine. However, I am trying to run them on Jenkins automation server.
The problem is that when running on Jenkins I get: "ImportError: Failed to import test module: test_one." I believe this is because an import within that test, which is located a few levels above in the hierarchy. (See hierarchy below)
modules
jira
jira_module #File to be imported
unit_tests
test_one
So, test_one contains the line "import modules.jira.jira_module as jm"
But the command line on Jenkins apparently doesn't like the path using dots. Does anyone know how to solve this issue? I've attempted using runpy - run_path, but that did not work either.
For this line to work
import modules.jira.jira_module as jm
module package modules must be located within PYTHONPATH.
The right approach is that the root directory (which contains modules and unit_tests folders) would the one in which you start the tests. Usually in the project root a bootstrap file is created to run the tests (runtests.py or runtests.sh or similar).
If you don't know how to this, or find this difficult, you could tweak the paths adding the root folder to sys.path in test_one.py. But this is ugly and not right.

How to import python file located in same subdirectory in a pycharm project

I have an input error in pycharm when debugging and running.
My project structure is rooted properly, etc./HW3/. so that HW3 is the root directory.
I have a subfolder in HW3, util, and a file, util/util.py. I have another file in util called run_tests.py.
In run_tests.py, I have the following import structure,
from util.util import my_functions, etc.
This yields an input error, from util.util import load_dataset,proportionate_sample
ImportError: No module named 'util.util'; 'util' is not a package
However, in the exact same project, in another directory (same level as util) called data, I have a file data/data_prep.py, which also imports functions from util/util.py using a similar import statement...and it runs without any problems.
Obviously, I am doing this in the course of doing a homework, so please understand: this is ancillary to the scope of the homework.
The problem goes away when I move the file to another directory. So I guess this question is How do I import a python file located in the same directory in a pycharm project? Because pycharm raises an error if I just do import util and prompts me to use the full name from the root.
Recommended Way:
Make sure to set the working folder as Sources.
You can do it in Pycharm -> Preferences -> Project: XYZ -> Project Structure
Select your working folder and mark it as Sources. Then Pycharm recognize the working folder as a Source folder for the project and you will be able to simply add other files within that folder by using
import filename.py
or
from filename.py import mudule1
=================
Not recommended way:
In Pycharmyou can simply add . before the .py file which you are going to import it from the same folder. In your case it will be
from .util import my_functions
Resource
There is a good reference also for more information with example how to implement Package Relative Imports. I would highly recommend to check this page.
Package Relative Imports
If you don't have an __init__.py create one and add this line
from util.util import my_function
then you can easily import the module in your scripts
the __init__.py tells python that it should treat that folder as a python package, it can also be used to import/load modules too.
in most cases the __init__.py is empty.
Quoting the docs:
The __init__.py files are required to make Python treat the
directories as containing packages; this is done to prevent
directories with a common name, such as string, from unintentionally
hiding valid modules that occur later on the module search path. In
the simplest case, __init__.py can just be an empty file, but it can
also execute initialization code for the package or set the __all__
variable, described later.
Right-click on the folder which you want to be marked as the source > Mark Directory as > Source root.
In my case, it worked only when I omit the extension. Example:
import filename
Note: May be a bit unrelated.
I was facing the same issue but I was unable to import a module in the same directory (rather than subdirectory as asked by OP) when running a jupyter notebook (here the directory didn't have __init__.py). Strangely, I had setup python path and interpreter location and everything. None of the other answers helped but changing the directory in python did.
import os
os.chdir(/path/to/your/directory/)
I'm using PyCharm 2017.3 on Ubuntu 16.04
I had the same issue with pycharm, but the actual mistake was that the file I was trying to import didn't have a .py extension, even though I was able to run it as a standalone script. Look in the explorer window and make sure it has a .py extension. If not, right click on the file in the explorer window, pick refactor, and then rename it with a .py extension.
In Pycharm go to "Run - Configuration" and uncheck
'Add Content root to Pythonpath' and
'Add source roots to Pythonpath',
then use
from filename import functionname
For me the issue was, the source directory was marked correctly, but my file to import was named starting with numeric value. Resolved by renaming it.
import 01_MyModuleToImport
to
import MyModuleToImport

Categories