Image assets won't load when using pytest - python

I'm developing a GUI with PySide and I create pixmap from images like this:
PHONE_IMAGE_PATH = "resources/images/phone.png"
self.phone_null = QtGui.QPixmap(GREY_DOT_PATH)
self.phone_null = self.phone_null.scaledToWidth(20)
This works perfectly when I run the program but when I test it with py.test this happens:
QPixmap::scaleWidth: Pixmap is a null pixmap
It says that the pixmap is null, so it seems like the image wasn't loaded properly.
I really want to test my code and I can't find any information about this problem anywhere. Does anyone have a solution to my problem?

From Wikipedia:
By contrast, a relative path starts from some given working directory, avoiding the need to provide the full absolute path. A filename can be considered as a relative path based at the current working directory. If the working directory is not the file's parent directory, a file not found error will result if the file is addressed by its name.
It seems that ou are using a relative path for your image asset, so when you run your program the relative path is correct, but i assume that your tests are located in different directory from your main program.
You could obtain current file location with: __file__
Example:
main_script_dir = os.path.dirname(__file__)
rel_path = "resources/images/phone.png"
PHONE_IMAGE_PATH = os.path.join(main_script_dir, rel_path)

Related

os.path.abspath from where is executed

a newby Python dev here.
I have a json file in the root project folder /json
I´m using os.path.abspath to obtain the absolute path.
abspath = os.path.abspath("json/quotes.json")
But it seems that depending from which class I execute that code is getting the path since that part.
So running my server, the absolute path return
******/app/resources/json/quotes.json'
And if I try from my unit test
*******/tests/json/quotes.json'
What I'm missing here?
Regards
The path to the file is relative to the location of script being executed.
In your case:
abspath = os.path.abspath("json/quotes.json")
is equivalent to:
abspath = os.path.join(os.getcwd(), "json/quotes.json")
The file may not be present at that location and attempting to open it may result in an error.
You could use an environment variable to set a base path and then use this in your script.
# Set a default in an environment variable
if not os.getenv('BASE_PATH'):
os.environ['BASE_PATH'] = '/path/to/base'
# Use the environment variable
abspath = os.path.join(os.getenv('BASE_PATH'), "json/quotes.json")

Relative paths error depending on Terminal's current folder

I've been trying to implement in my scripts that work with files the possibility to run my program regardless of the path the package is located in.
I found that with this code, it would generally work well:
import os.path
file_path = os.path.dirname(__file__)
data_path = file_path + '/myfile's/path/'
If from Terminal I try to execute
python3 path/to/my/script/script.py
I get no problem. However, if I try to run my script within the current folder it is located in (cd path/to/my/script/) an error shows up. Claiming that /myfile's/path is not a valid directory.
I figured that I could implement the following:
file_path = os.path.dirname(__file__)
if file_path:
data_path = file_path + '/myfile's/path'
else:
data_path = 'myfile's/path'
This seems to work out fine, but I wonder if there is a normalized or better way to do this that regards other types of errors I might have not encountered yet.
Thanks ;)
not really (this question isnt actually appropriate for SO but here goes)
you need to do this... but when I do i tend to abstract it out
def rel_path(*parts):
BASE = os.path.dirname(__file__)
return os.path.abspath(os.path.join(BASE,*parts))
then I use this function everywhere
my_path = rel_path("myfiles","path","example.jpg")
# /path/to/this/file/myfiles/path/example.jpg

Parent path Python Maya

I have a problem. I have a GUI in maya generated by a script in python.
The GUI, when launched opens an image.To load the image I used the following line of code:
cmds.image( image='/home/s4915717/myName/artefacts/Images/UIheader02.png' )
As you can understand, if I move my script into another computer, I should manually change the path to correctly load the image.
Is there a way to prevent this and let the program find to allocation of the image by itself?
I also tried to use the following method:
import os
.
.
.
path = os.path.abspath('myName/artefacts/Images/UIheader02.png')
cmds.image( image=path )
it works on my pc, but if I move on another one it doesn't work(yes I moved the whole folder with the image inside myName/artefacts...
Your first path is absolute, your second is relative, which may be part of your issue.
Depending on your OS, Maya looks in slightly different places in the user directory for icons. See this page in the docs down near the bottom, under XBMLANGPATH for the locations Maya is expecting. You can also set XBMLANGPATH to a custom location before starting Maya if you want to point at a special place, like a network share.
If your script is called from a file outside of Maya, you can use the __file__ attribute which will give you the path to the file where you use it. You can then use it to build your path.
For example, if your script is stored in '/home/s4915717/myName/artefacts', the __file__ will return '/home/s4915717/myName/artefacts'
So __file__ + '/Images/UIheader02.png' will give you the full path : '/home/s4915717/myName/artefacts/Images/UIheader02.png'
The safest way is probably to have all your scripts stored in a specific folder (for example the Maya script file) from which you can build relative paths.
Like Martin mentioned, you can use __file__ within your script and it will return that script's full path.
So let's say you have your image in a folder with your script like so:
+--my_script.py
+--my_folder
| +--my_image.png
You can access the image in your script this way:
import os
os.path.join(os.path.dirname(__file__), "my_folder", "my_image.png")
And let's say your folder was up one directory like so:
+--my_image.png
+--my_folder
| +--my_script.py
You can use os.path.abspath instead:
import os
os.path.abspath(os.path.join(__file__, "..", "..", "my_image.png"))
abspath helps resolve the ".." to go up a directory. At the end you can use os.path.exists to verify that the resulting path does in fact exist.

Python, Creating a new file/folder in the same directory as the script

I've written a script that basically creates two new folders when it's run the first time, if the folders don't already exist.
import os
try:
os.makedirs('results/graphs')
except OSError:
pass
And everytime the script is run, the graphs are produced in the results/graphs folder.
But I noticed recently that if the script is run from another directory, (eg. script is in home/user/script/ but I run it from: home/user/programs/), the new folders are created in home/user/programs/.
My goal is ultimately that the folders are created only in the script folder and all eventual graphs that are produced will thus be destined to home/user/script/results/graphs.
Is there someway to achieve this using python?
I'm using Debian 8 and python 2.7.13. The graphs are produced using matplotlib.
It's a solution for me, check it (I tried it on windows):
import os
d = os.path.dirname(__file__) # directory of script
p = r'{}/results/graphs'.format(d) # path to be created
try:
os.makedirs(p)
except OSError:
pass
In your script results/graphs refers to the results folder within whatever folder you ran the script from. If you always want the folders to be created in /home/user/script/results/graphs use ~/script/results/graphs in your script instead. Alternatively you could hard code the whole path, /home/user/script/results/graphs.
There is another way, apart from hard coding which is mentioned earlier. You can use __file__ to extract the path of the file where the script is present. And then you can use it to append as parent path to results/graphs
All you have to do is to define the path where your script is. This can be done within the code as:
path = 'home/user/script/'
or by getting the input from the user using a filedialog box.
Then you can use the path variable to make the directories.
os.makedirs(path + 'results/graphs')
##creating folder
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename()
dirctry = os.path.dirname(file_path)
toolSharePath = os.path.abspath(dirctry)
final_directory = os.path.join(toolSharePath, r'new_folder')
if not os.path.exists(final_directory):
os.makedirs(final_directory,exist_ok=True)

How to make python config file, in which relative paths are defined, but when scripts in other directories import config, paths are correct?

I have the following directory structure for a program I'm writing in python:
\code\
main.py
config.py
\module_folder1\
script1.1.py
\data\
data_file1
data_file2
My config.py is a set of global variables that are set by the user, or generally fixed all the time. In particular config.py defines path variables to the 2 data files, something like path1 = os.path.abspath("../data/data_file1"). The primary use is to run main.py which imports config (and the other modules I wrote) and all is good.
But sometimes I need to run script1.1.py by itself. Ok, no problem. I can add to script1.1 the usual if __name__ == '__main__': and I can import config. But then I get path1 = "../code/data/data_file1" which doesn't exist. I thought that since the path is created in config.py the path would be relative to where config.py lives, but it's not.
So the question is, how can I have a central config file which defines relative paths, so I can import the config file to scripts in different directories and have the paths still be correct?
I should mention that the code repo will be shared among multiple machines, so hardcoding an absolute path is not an option.
You know the correct relative path to the file from the directory where config.py is located
You know the correct relative path to the directory where config.py is located (in your case, ..)
Both of this things are system-independent and do not change unless you change the structure of you project. Just add them together using os.path.join('..', config.path_repative_to_config)
(Not sure who posted this as a comment, then deleted it, but it seems to work so I'm posting as an answer.) The trick is to use os.path.dirname(__file__) in the config file, which gives the directory of the config file (/code/) regardless of where the script that imports config is.
Specifically to answer the question, in the config file define
path1 = os.path.abspath(os.path.join(os.path.join(os.path.join( os.path.dirname(__file__) , '..'), 'data' ), 'data_file1' ) )

Categories

Resources