QProcess python script handles spaces in filenames differently than when run from command line
-
Hello,
I can successfully execute a python2.7 script using QProcess,a nd it gets its arguments in correctly and can write files. It can also read files as long as there are no spaces in the path name, but not if there are. I spent quite some time dtryign to determine whether I had other problems but have now isolated it to a vdery simple difference as below.This works:
@
inputListFile = '/Users/buckler/Documents/wilist_try.json'
with open(inputListFile, 'r') as input_fd:
wilist = WorkitemList.from_json(input_fd.read())but changing to inputListFile = '/Users/buckler/Documents/CAP Exam Data/wilist_try.json' causes the open to give an exception.
Note that an open for write allows a file to be opened in the same directory, i.e., the spaces don't seem to give it any trouble. Also, I tried it without the with, but this makes no difference.
The only clue I have is that using the path with the spaces results in os.stat indicating that the file exists but shows a zero size for it (which is not the case).
-
actually, one clarification
I see in what I wrote
it looks like I am saying the open gives an exception, but this isn't where the exception occurs
it is when I try to use the input, which is (incorrectly) of zero length.In other words, the problem isn't the exception as such, because I expect that if I try to process a zero length file. The problem is, why is the file zero length.
-
Is that your actual Python code in the first post? It seems incredibly strange to me that QProcess should have anything to do with how Python handles a hard coded path in a Python script.
Can you put together a minimal, fully working example (Python and Qt code) that exhibits the problem?
-
Thank you Besc. I too find it hard to believe that this would happen but yet here we are.
The Qt code:
QProcess *backdoorProcess = new QProcess(parent); QString program = "/usr/bin/python2.7"; QStringList arguments; arguments << backdoorScriptName << "--inputList" << listFilePath.replace(" ", "%20"); backdoorProcess->start(program, arguments);
The Python:
import os import sys import datetime import time import json from dateutil.tz import tzlocal if __name__ == '__main__': inputListFile = '/Users/buckler/Documents/CAP Exam Data/wilist_try.json' #urllib2.unquote(args.inputList) errors = "" # establish a log log_fd = open(os.path.join(os.path.dirname(inputListFile), 'wilist_summary.log'), 'w') print >> log_fd, inputListFile print >> log_fd, os.path.dirname(inputListFile) print >> log_fd, os.path.basename(inputListFile) #load the input list statinfo = os.stat(inputListFile) try: with open(inputListFile, 'r') as input_fd: if len(input_fd.read()) == 0: print >> log_fd, 'inputList empty' log_fd.close() sys.exit(errors) else: print >> log_fd, 'file is good' except Exception as e: print >> log_fd, '%s' % str(e) print >> log_fd, statinfo log_fd.close() sys.exit(errors) # now exit if errors == '': print >> log_fd, 'success' log_fd.close() sys.exit(len(errors))
Like this, it shows the file to be of zero length. If I remove the /CAP Exam Data part, it shows the correct length. I have placed the file at both levels for the testing of course.
-
I found the problem. Many thanks to besc and others that looked at this. It had nothing to do with spaces or for that matter with python at all. The file I needed to read had just been written in the c++; but it had not been flushed to disk yet. The reason it worked in the other cases I had tested is that the data had flushed; the specific need was to read it immediately after it was writtem, and adding a flush before callign out to python solved the problem.
Once again, many thanks to all,
Andy