@@ -1758,11 +1758,25 @@ def value_labels(self):
17581758 return self .value_label_dict
17591759
17601760
1761- def _open_file_binary_write (fname , encoding ):
1761+ def _open_file_binary_write (fname ):
1762+ """
1763+ Open a binary file or no-op if file-like
1764+
1765+ Parameters
1766+ ----------
1767+ fname : string path, path object or buffer
1768+
1769+ Returns
1770+ -------
1771+ file : file-like object
1772+ File object supporting write
1773+ own : bool
1774+ True if the file was created, otherwise False
1775+ """
17621776 if hasattr (fname , 'write' ):
17631777 # if 'b' not in fname.mode:
1764- return fname
1765- return open (fname , "wb" )
1778+ return fname , False
1779+ return open (fname , "wb" ), True
17661780
17671781
17681782def _set_endianness (endianness ):
@@ -1899,7 +1913,9 @@ class StataWriter(StataParser):
18991913 ----------
19001914 fname : path (string), buffer or path object
19011915 string, path object (pathlib.Path or py._path.local.LocalPath) or
1902- object implementing a binary write() functions.
1916+ object implementing a binary write() functions. If using a buffer
1917+ then the buffer will not be automatically closed after the file
1918+ is written.
19031919
19041920 .. versionadded:: 0.23.0 support for pathlib, py.path.
19051921
@@ -1970,6 +1986,7 @@ def __init__(self, fname, data, convert_dates=None, write_index=True,
19701986 self ._time_stamp = time_stamp
19711987 self ._data_label = data_label
19721988 self ._variable_labels = variable_labels
1989+ self ._own_file = True
19731990 # attach nobs, nvars, data, varlist, typlist
19741991 self ._prepare_pandas (data )
19751992
@@ -2183,9 +2200,7 @@ def _prepare_pandas(self, data):
21832200 self .fmtlist [key ] = self ._convert_dates [key ]
21842201
21852202 def write_file (self ):
2186- self ._file = _open_file_binary_write (
2187- self ._fname , self ._encoding or self ._default_encoding
2188- )
2203+ self ._file , self ._own_file = _open_file_binary_write (self ._fname )
21892204 try :
21902205 self ._write_header (time_stamp = self ._time_stamp ,
21912206 data_label = self ._data_label )
@@ -2205,6 +2220,23 @@ def write_file(self):
22052220 self ._write_file_close_tag ()
22062221 self ._write_map ()
22072222 finally :
2223+ self ._close ()
2224+
2225+ def _close (self ):
2226+ """
2227+ Close the file if it was created by the writer.
2228+
2229+ If a buffer or file-like object was passed in, for example a GzipFile,
2230+ then leave this file open for the caller to close. In either case,
2231+ attempt to flush the file contents to ensure they are written to disk
2232+ (if supported)
2233+ """
2234+ # Some file-like objects might not support flush
2235+ try :
2236+ self ._file .flush ()
2237+ except AttributeError :
2238+ pass
2239+ if self ._own_file :
22082240 self ._file .close ()
22092241
22102242 def _write_map (self ):
@@ -2374,7 +2406,7 @@ def _prepare_data(self):
23742406
23752407 def _write_data (self ):
23762408 data = self .data
2377- data . tofile ( self ._file )
2409+ self ._file . write ( data . tobytes () )
23782410
23792411 def _null_terminate (self , s , as_string = False ):
23802412 null_byte = '\x00 '
@@ -2641,7 +2673,9 @@ class StataWriter117(StataWriter):
26412673 ----------
26422674 fname : path (string), buffer or path object
26432675 string, path object (pathlib.Path or py._path.local.LocalPath) or
2644- object implementing a binary write() functions.
2676+ object implementing a binary write() functions. If using a buffer
2677+ then the buffer will not be automatically closed after the file
2678+ is written.
26452679 data : DataFrame
26462680 Input to save
26472681 convert_dates : dict
@@ -2879,7 +2913,7 @@ def _write_data(self):
28792913 self ._update_map ('data' )
28802914 data = self .data
28812915 self ._file .write (b'<data>' )
2882- data . tofile ( self ._file )
2916+ self ._file . write ( data . tobytes () )
28832917 self ._file .write (b'</data>' )
28842918
28852919 def _write_strls (self ):
0 commit comments