unittest working in PyCharm but unable to run from command line - python

I'm trying to run a unit test in the command line to generate code coverage. I can run the command from PyCharm fine, but running it from command line doesn't work.
The test is in a testing folder like the following
a/b/c/testing/UnitTest.py
The files I import are imported in the format
from a.b.c.main.classes import MyClass
If I try and directly run the unit test from the folder, it tells me that it can't import module a.
I'm fairly certain that PyCharm is fixing this issue because I have the boxes "Add content roots to PYTHONPATH" and "Add source roots to PYTHONPATH" checked, but I can't figure out how to do something equivalent in the command line.
How can I either fix my imports so it doesn't require it to be run from the root level, or add the content and source roots to PYTHONPATH so I can run in the command line?

if you are on Windows,
set PYTHONPATH=<Path to your Source folder >
for linux,
export PYTHONPATH=<Path to your Source folder >
once you set that running below command from project folder should do the work
python -m unittest discover

Try this:
cd project_dir
python -m unittest -v a/b/c/testing/UnitTest.py -k your_test_name
-v is for unittest verbose log output.

Related

Add a library path for .whl files to sys.path via a commandline option for python [duplicate]

I want to run:
python somescript.py somecommand
But, when I run this I need PYTHONPATH to include a certain directory. I can't just add it to my environment variables because the directory I want to add changes based on what project I'm running. Is there a way to alter PYTHONPATH while running a script? Note: I don't even have a PYTHONPATH variable, so I don't need to worry about appending to it vs overriding it during running of this script.
For Mac/Linux;
PYTHONPATH=/foo/bar/baz python somescript.py somecommand
For Windows, setup a wrapper pythonpath.bat;
#ECHO OFF
setlocal
set PYTHONPATH=%1
python %2 %3
endlocal
and call pythonpath.bat script file like;
pythonpath.bat /foo/bar/baz somescript.py somecommand
import sys
sys.path.append('your certain directory')
Basically sys.path is a list with all the search paths for python modules. It is initialized by the interpreter. The content of PYTHONPATH is automatically added to the end of that list.
If you are running the command from a POSIX-compliant shell, like bash, you can set the environment variable like this:
PYTHONPATH="/path/to" python somescript.py somecommand
If it's all on one line, the PYTHONPATH environment value applies only to that one command.
$ echo $PYTHONPATH
$ python -c 'import sys;print("/tmp/pydir" in sys.path)'
False
$ PYTHONPATH=/tmp/pydir python -c 'import sys;print("/tmp/pydir" in sys.path)'
True
$ echo $PYTHONPATH
You may try this to execute a function inside your script
python -c "import sys; sys.path.append('/your/script/path'); import yourscript; yourscript.yourfunction()"
You can paste the following code in the __init__.py of the package from which you want to import:
import sys
from pathlib import Path
sys.path.insert(0, Path(__file__).parent)
Then you can import modules from that package as you would usually do.
import <module_name>
<module_name>.<method_on_module>()
Example:
import algorithms
algorithms.run_algo1()
Your IDE might underline the module name, but that won't be a problem when you run the Python interpreted.
Also, if you need to read the path, later on, you can do:
DIR_PATH = Path(sys.path[0])
This is for windows:
For example, I have a folder named "mygrapher" on my desktop. Inside, there's folders called "calculation" and "graphing" that contain Python files that my main file "grapherMain.py" needs. Also, "grapherMain.py" is stored in "graphing". To run everything without moving files, I can make a batch script. Let's call this batch file "rungraph.bat".
#ECHO OFF
setlocal
set PYTHONPATH=%cd%\grapher;%cd%\calculation
python %cd%\grapher\grapherMain.py
endlocal
This script is located in "mygrapher". To run things, I would get into my command prompt, then do:
>cd Desktop\mygrapher (this navigates into the "mygrapher" folder)
>rungraph.bat (this executes the batch file)

Run Python module from command line like in Pycharm

I have a directory structure like this:
my_project
.idea
src
config.ini
method.py
... other py modules
When I open the project in PyCharm and run with the configuration below, it runs perfectly. It runs src.method as a module using an Anaconda 3 environment. The src.method module uses relative imports from other modules in src and takes config.ini as an argument.
I am trying to run the module in the same way through the Windows command line from src as the working directory
C:\Users\deimos\Anaconda3\envs\cveureka\python.exe -m src.method "config.ini"
but this gives a ModuleNotFoundErrorsaying it could not find src. I tried replacing src.method with just method but that gives ImportError: attempted relative import with no known parent package.
I have also tried setting the PYTHONPATH before running the module with
setlocal
set PYTHONPATH=%2
like in this answer, but to no effect.
It there a way to set up the command line to replicate the way that PyCharm runs the module?

Run python script in package

I am struggling with running python script in shell. I use PyCharm where is everything ok, but I want to run script without running PyCharm.
So my project folder is like:
data/
file.txt
main/
__init__.py
script.py
tools/
__init__.py
my_strings.py
I want to run main/script.py, which start with from tools import my_strings and working directory should be data/.
My PyCharm config is:
Script path: <PROJECT>/main/script.py
Working directory: <PROJECT>/data
Add content roots to PYTHONPATH: YES
Add source roots to PYTHONPATH: YES
So I want to run main/script.py in shell on Ubuntu. I tried:
PYTHONPATH=<PROJECT>
cd <PROJECT>/data
python3 ../main/script.py
But I just got: ImportError: No module named 'tools'
Check out this post, it's explains the PYTHONPATH variable.
How to use PYTHONPATH and the documentation the answer points to https://docs.python.org/2/using/cmdline.html#envvar-PYTHONPATH
When you run from the data directory by default python can't find your tools directory.
Also regarding your comment about needing to run from the data directory, you could just use open('../data/file.txt') if you decided to run from the main directory instead.
Ideally, you should be able to run your script from anywhere though. I find this snippet very useful os.path.dirname(sys.argv[0]). It returns the directory in which the script exists.
I simply forgot to export $PYTHONPATH as suggested by Steve.

Run Python plugins in Hiero

I am facing a small problem in executing custom made python code from Hiero. As everybody knows, the first place to look for details is the offical documentation "Nukepedia", the Python Dev Guide and the Hiero User Guide. Well according to the Python Dev Guide, Hiero creates a ".hiero" directory by default which lets people add plugin paths to use them in the software. Well, I can't find that directory and I deduced after several tests that Hiero is using the init.py saved in the ".nuke" directory.
So I thought that maybe I could add the plugin paths there but kept getting the famous Import Error for the _fnpython module (before creating Python/Startup directory).
I added Python/Startup folders in .nuke and added the plugins in Startup, I got the same error, I even tried it by adding the path to the plugins in init.py and got the same error too.
Then I created a ".hiero" folder and did the same thing as before but Hiero never took that folder into consideration, I deduced that by printing some strings in the console, Hiero always took the init.py saved in the ".nuke" folder and kept showing the same error.
Finally, I tried to look into the installation process and try to seperate Nuke and Hiero's folders maybe that would create the ".hiero" directory but everything was automated.
The code that I want to run is given by Nuke and Hiero (in the examples directory), I just can't figure out what to do in order to run it from the program.
What should I do in order to fix this problem ?
Thank you in advance.
The setup for The Foundry HIERO is a little different than for NUKE.
HIERO has a core module. You'll see it in __init__.py file:
import FnRedirect
import FnPythonFixes
import core
import ui
try:
if hasattr(core, "taskRegistry"):
import importers
import exporters
except ImportError as e:
pass
I'm running HIERO and NUKE STUDIO on a Mac, so there's a full path to HIERO's __init__.py file inside package contents:
/Applications/Nuke10.5v5/Contents/MacOs/pythonextensions/site-packages/hiero/__init__.py
You need to import this module using:
import hiero.core
or using a reference to the core package:
from core import *
To find HIERO's current paths you have to run this line in its Script Editor:
print hiero.core.pluginPath()
Click this link for further details: Hiero's Environment Setup
All these instructions are suitable for macOS 10.9 and above. Here are two blocks of steps: first for Terminal Mode and second for UI Mode.
BLOCK 1: setup for Terminal Sessions
You need to manually create .hiero directory in your Home area.
The recommended default location for running Python on startup is:
~/.hiero/Python/Startup
~/.hiero/Python/StartupUI
Type in your bash Terminal (when you're inside your Home user directory) the following line:
mkdir .hiero/
then:
mkdir .hiero/Python/
and then:
mkdir .hiero/Python/StartupUI/
then navigate to Home directory with:
cd ~
and check it with:
ls -a
Also you can specify any number of user-defined paths using the environment variable HIERO_PLUGIN_PATH, just like the standard Unix PATH environment variable.
For that you need to set up an environment variable in .bash_profile. To run in Terminal PICO editor just type (remember you need an administrator's password for sudo command):
sudo pico .bash_profile
and paste these three lines in it (change swift for <yourName> and save this file):
echo HIERO environment var is set...
export HIERO_PLUGIN_PATH=/Users/swift/.hiero/Python/StartupUI/
export PATH=$PATH:$HIERO_PLUGIN_PATH
Write out a file with ctrl o
Exit pico editor with ctrl x
Restart Terminal
In Terminal you could print this environment variable typing:
printenv HIERO_PLUGIN_PATH
You should put inside that StartupUI directory menu.py, any set of xxxx.py or xxxx.pyc files, as well as __init__.py file.
Now you can use /Users/swift/.hiero/Python/StartupUI/ path in Terminal Mode.
BLOCK 2: setup for UI Sessions
To assign the current paths that HIERO searches when loading plug-ins, you need to create __init__.py file with the following lines:
import hiero.core
path='/Users/swift/.hiero/Python/Startup/'
hiero.core.addPluginPath(path)
After that make Python/Startup/ subdirectories under ~/.nuke/ folder.
It's not a mistake: I typed .nuke.
Then place this __init__.py file into /Users/swift/.nuke/Python/Startup/ directory.
Restart HIERO (or NUKE STUDIO) if it works.
After that launch HIERO or NUKE STUDIO and run
print hiero.core.pluginPath()
command in the HIERO's Script Editor or in NUKE STUDIO's Script Editor and you'll see this result:
After that you'll find new __init__.pyc file in /Users/swift/.nuke/Python/Startup/ directory.
Each package or module discovered when you launch HIERO is imported and added to the built-in package hiero.plugins.
TEST 1: custom_guides.py
I do not have a commercial version of HIERO so I tested custom_guides.py script ( found here ) using NUKE STUDIO NC.
I placed custom_guides.py in ~/.nuke/Python/Startup directory and then added two lines to NUKE's init.py file located in ~/.nuke directory.
import nuke
nuke.pluginAddPath("./Python/Startup")
The only thing I could say: "it works" Do the same actions as I did and it'll work for HIERO.
Look at safe_zone and masking_ratio dropdown menus. They are different: before and after.
Before uploading custom_guides.py script:
After uploading custom_guides.py script:
# file custom_guides.py contains these lines:
viewer_masks = [
hiero.ui.guides.MaskGuide("NTSC", 0.91),
hiero.ui.guides.MaskGuide("PAL", 1.09),
hiero.ui.guides.MaskGuide("NTSC_16:9", 1.21),
hiero.ui.guides.MaskGuide("PAL_16:9", 1.46),
hiero.ui.guides.MaskGuide("Cinemascope 2:1", 2.0)
]
TEST 2: web_browser.py
I placed web_browser.py file in ~/.nuke/Python/Startup directory. This Python script creates dockable panel with web browser written with PySide Qt.
I do not have a commercial version of HIERO so I tested web_browser.py script ( found here ) using NUKE STUDIO NC.

Importing a module outside of Jenkins home directory

I am trying to run a custom Python module located at '/home/modules/module.py'
The python script is run by Jenkins and located at '/home/user_name/scripts/script.py'
Since Jenkins home directory is '/var/lib/jenkins' how can I import my module?
I have tried adding the following to the python script:
import sys
sys.path.insert(0,'/home/modules') """also /home/modules/"""
import module
but I am still getting the error:
ImportError: No module named
I am running everything in Ubuntu 14.04 and Python 2.7
EDIT:
I changed Jenkins user directory like this:
root#dwh-01:~$ usermod -m -d /home/jenkins jenkins
and modified JENKINS_HOME=/home/jenkins in /etc/default/jenkins
I think I can work with this, but now the issue is, if I log into jenkins shell and do:
jenkins#dwh-01:/$ cd
bash: cd: jenkins/: No such file or directory
Should the behaviour of the cd command direct me to /home/jenkins/ ?
If I repeat the same when in /home/ It works though.
If I try and start jenkins, it gives me:
Starting Jenkins Continuous Integration Server jenkins
No directory, logging in with HOME=/
EDIT-2:
User jenkins home dir error fixed, I just made sure the home directory of the user was /home/jenkins using usermod -d /home/jenkins jenkins
I'm a step closer to importing the module, but am still having issues going one step outside of the jenkins home directory.
You should have two options that would allow you to import module into your code.
Option 1
import sys
sys.path.append('/home/modules')
import module
Option 2
import importlib.machinery
importlib.machinery.SourceFileLoader('module', '/home/modules').load_module()
If neither of these work, hopefully they will at least point you and others in the right direction.
Ok finally figured it out.
What I did was change in the /etc/default/jenkins file the variable JENKINS_USER and JENKINS_GROUP to the user i needed to outside of the jenkins user folder (outside of /var/lib/jenkins).
This way the scripts ran by Jenkins will be ran as if it was the selected user I specified.
After that, I realized that in Jenkins, even if the working directory is /var/lib/jenkins/jobs/adjust_data_parser/workspace, scripts and files can be called from '/'
So the trick was:
-Accessing the script outside of the jenkins home directory
-Importing the module from its absolute path.

Categories