user4464019
user4464019

Reputation:

Python reading from tempfile not successful

with tempfile.NamedTemporaryFile(delete = False) as tmpfile:
    subprocess.call(editor + [tmpfile.name])    # editor = 'subl -w -n' for example 
    tmpfile.seek(0)
    print tmpfile.read()

... opens my Sublime Text but when I enter something and close the file, I get no output nor errors, just an empty line (on Python 2). And yes, the program does wait until I'm finished writing.

EDIT:
I just discovered that it probably is a problem specific to Sublime Text since vi, emacs and nano all working fine when entered as editor. But I still wonder how I could solve this.

Upvotes: 0

Views: 244

Answers (2)

jfs
jfs

Reputation: 414835

It works as is if the output file is written directly:

#!/usr/bin/env python
import subprocess
import sys
import tempfile

editor = [sys.executable, '-c', "import sys;"
                                "open(sys.argv[1], 'w').write('abc')"]
with tempfile.NamedTemporaryFile() as file:
    subprocess.check_call(editor + [file.name])
    file.seek(0)
    print file.read() # print 'abc'

It fails if the editor writes to its own temporary file first and renames it at the end:

#!/usr/bin/env python
import subprocess
import sys
import tempfile

editor = [sys.executable, '-c', r"""import os, sys, tempfile
output_path = sys.argv[1]
with tempfile.NamedTemporaryFile(dir=os.path.dirname(output_path),
                                 delete=False) as file:
    file.write(b'renamed')
os.rename(file.name, output_path)
"""]
with tempfile.NamedTemporaryFile() as file:
    subprocess.check_call(editor + [file.name])
    file.seek(0)
    print file.read() #XXX it prints nothing (expected 'renamed')

Reopening the file as @Vor suggested helps:

#!/usr/bin/env python
import os
import subprocess
import sys
import tempfile

editor = [sys.executable, '-c', r"""import os, sys, tempfile
output_path = sys.argv[1]
with tempfile.NamedTemporaryFile(dir=os.path.dirname(output_path),
                                 delete=False) as file:
    file.write(b'renamed')
os.rename(file.name, output_path)
"""]
try:
    with tempfile.NamedTemporaryFile(delete=False) as file:
        subprocess.check_call(editor + [file.name])
    with open(file.name) as file:
        print file.read() # print 'renamed'
finally:
    os.remove(file.name)

Upvotes: 1

Vor
Vor

Reputation: 35149

According to the "edit" section, you can save the file and then reopen it again, this might not be the best solution, and it doesn't "solve" the original problem, but at least it should work:

import subprocess
import tempfile

editor = ['gedit']

with tempfile.NamedTemporaryFile(delete=False) as tmpfile:
    subprocess.call(editor + [tmpfile.name])    # editor = 'subl -w -n' for example 
    tmpfile.file.close()
    tmpfile = file(tmpfile.name)
    print tmpfile.read()

Upvotes: 1

Related Questions