Reputation: 21971
with NamedTemporaryFile(suffix='.shp').name as tmp_shp:
df.to_file(tmp_shp)
In code above, I get this error:
AttributeError: __enter__
How can I use a named temporary file using with statement? and since tmp_shp
is just a path, does it still stay available outside of with
?
Upvotes: 3
Views: 6993
Reputation: 155418
The name
attribute is a string; trying to access it in the with
statement makes it the managed resource (and str
has no concept of context management). You need to manage the NamedTemporaryFile
itself, and access the name
as needed:
with NamedTemporaryFile(suffix='.shp') as tmp_shp:
df.to_file(tmp_shp.name) # Access .name here, assuming you need a str
If to_file
accepts file-like objects (I can't find docs for such a method), you'd avoid using .name
at all (in either line).
Update: Because you're on Windows, you can't actually open a file opened by NamedTemporaryFile
with delete=True
(the default) until the NamedTemporaryFile
is closed (which means you can't use any data written to that file handle, since it's deleted, and introduces a race condition even if using it solely to generate a unique name; the file is deleted at that point, so you're really just creating a new file, but someone else might race you to creating that file later). Best I can suggest here is to using it without deletion support to get a unique name, wrapping it to force deletion yourself, e.g.:
tmp_shp = None
try:
with NamedTemporaryFile(suffix='.shp', delete=False) as tmp_shp:
df.to_file(tmp_shp.name) # Access .name here, assuming you need a str
... do any other stuff with the file ...
finally:
if tmp_shp is not None:
os.remove(tmp_shp.name)
Yeah, it's ugly. There aren't a lot of good options here; NamedTemporaryFile
is fundamentally broken on Windows.
Upvotes: 6
Reputation: 20214
You should use with statement for NamedTemporaryFile
itself but not its name
attribute.
with NamedTemporaryFile(suffix='.shp') as tmp_file:
df.to_file(tmp_file) # As temp_file is a file object, I think to_file should work?
And as the official doc, tmp_file
will be deleted outside of with
unless you pass delete=False
to NamedTemporaryFile
.
That means you should with NamedTemporaryFile(suffix='.shp', delete=False) as tmp_file:
Upvotes: 2
Reputation: 2030
You use the name attribute as a context manager. Try:
with NamedTemporaryFile(suffix='.shp') as tmp_shp:
df.to_file(tmp_shp)
Upvotes: 1