Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vim Editor in python script tempfile

I have been successful in finding code for spawning a vim editor and creating a tempfile from a python script. The code is here, I found it here: call up an EDITOR (vim) from a python script

import sys, tempfile, os
from subprocess import call

EDITOR = os.environ.get('EDITOR','vim') 

initial_message = "" 

with tempfile.NamedTemporaryFile(suffix=".tmp") as tempfile:
  tempfile.write(initial_message)
  tempfile.flush()
  call([EDITOR, tempfile.name])

The problem I having is that I cannot access the contents of the tempfile after I quit the editor.

tempfile
<closed file '<fdopen>', mode 'w+b' at 0x87c47b0>

tempfile.readline()

I get

ValueError: I/O operation on closed file

I did:

myfile = open(tempfile.name)
IOError: [Errno 2] No such file or directory: '/tmp/tmp7VKzfl.tmp'

How would I access the file in a python script once it has been edited with the editor?

Thank you

like image 382
Neeran Avatar asked Apr 11 '12 09:04

Neeran


People also ask

How do I write to Tempfile?

If you want to write text data into a temp file, you can use the writelines() method instead. For using this method, we need to create the tempfile using w+t mode instead of the default w+b mode. To do this, a mode param can be passed to TemporaryFile() to change the mode of the created temp file.

What is the purpose of Tempfile module?

This module creates temporary files and directories. It works on all supported platforms. TemporaryFile , NamedTemporaryFile , TemporaryDirectory , and SpooledTemporaryFile are high-level interfaces which provide automatic cleanup and can be used as context managers.


2 Answers

Everything inside a with block is scoped. If you create the temporary file with the with statement, it will not be available after the block ends.

You need to read the tempfile contents inside the with block, or use another syntax to create the temporary file, e.g.:

tempfile = NamedTemporaryFile(suffix=".tmp")
# do stuff
tempfile.close()

If you do want to automatically close the file after your block, but still be able to re-open it, pass delete=False to the NamedTemporaryFile constructor (else it will be deleted after closing):

with tempfile.NamedTemporaryFile(suffix=".tmp", delete=False) as tempfile:

Btw, you might want to use envoy to run subprocesses, nice library :)

like image 148
Danilo Bargen Avatar answered Oct 06 '22 01:10

Danilo Bargen


I was running into the same problem and had the same question.

It just didn't feel like a best practice to NOT delete a temp file just so that it could be read. I found the following way to read what was written to an instance of a NamedTempFile after vim editing, read it, and retain the advantage of deleting the tempfile. (It's not temporary if it's not deleted on its own, right?!)

One must rewind the tempfile and then read it. I found the answer at: http://pymotw.com/2/tempfile/

import os
import tempfile
from subprocess import call

temp = tempfile.TemporaryFile()
try:
    temp.write('Some data')
    temp.seek(0)

    print temp.read()
finally:
    temp.close()

Here is the actual code I used in my script: import tempfile import os from subprocess import call

EDITOR = os.environ.get('EDITOR', 'vim')
initial_message = "Please edit the file:"

with tempfile.NamedTemporaryFile(suffix=".tmp") as tmp:
    tmp.write(initial_message)
    tmp.flush()
    call([EDITOR, tmp.name])
    #file editing in vim happens here
    #file saved, vim closes
    #do the parsing with `tempfile` using regular File operations
    tmp.seek(0)
    print tmp.read()
like image 26
dmmfll Avatar answered Oct 06 '22 00:10

dmmfll