BUG: properly close files opened by parsers · pandas-dev/pandas@4a80521 (original) (raw)
`@@ -92,16 +92,24 @@ def init(self, path_or_buf, index=None, convert_dates=True,
`
92
92
`self._path_or_buf, _, _ = get_filepath_or_buffer(path_or_buf)
`
93
93
`if isinstance(self._path_or_buf, compat.string_types):
`
94
94
`self._path_or_buf = open(self._path_or_buf, 'rb')
`
``
95
`+
self.handle = self._path_or_buf
`
95
96
``
96
97
`self._get_properties()
`
97
98
`self._parse_metadata()
`
98
99
``
``
100
`+
def close(self):
`
``
101
`+
try:
`
``
102
`+
self.handle.close()
`
``
103
`+
except AttributeError:
`
``
104
`+
pass
`
``
105
+
99
106
`def _get_properties(self):
`
100
107
``
101
108
`# Check magic number
`
102
109
`self._path_or_buf.seek(0)
`
103
110
`self._cached_page = self._path_or_buf.read(288)
`
104
111
`if self._cached_page[0:len(const.magic)] != const.magic:
`
``
112
`+
self.close()
`
105
113
`raise ValueError("magic number mismatch (not a SAS file?)")
`
106
114
``
107
115
`# Get alignment information
`
`@@ -175,6 +183,7 @@ def _get_properties(self):
`
175
183
`buf = self._path_or_buf.read(self.header_length - 288)
`
176
184
`self._cached_page += buf
`
177
185
`if len(self._cached_page) != self.header_length:
`
``
186
`+
self.close()
`
178
187
`raise ValueError("The SAS7BDAT file appears to be truncated.")
`
179
188
``
180
189
`self._page_length = self._read_int(const.page_size_offset + align1,
`
`@@ -219,6 +228,7 @@ def _get_properties(self):
`
219
228
`# Read a single float of the given width (4 or 8).
`
220
229
`def _read_float(self, offset, width):
`
221
230
`if width not in (4, 8):
`
``
231
`+
self.close()
`
222
232
`raise ValueError("invalid float width")
`
223
233
`buf = self._read_bytes(offset, width)
`
224
234
`fd = "f" if width == 4 else "d"
`
`@@ -227,6 +237,7 @@ def _read_float(self, offset, width):
`
227
237
`# Read a single signed integer of the given width (1, 2, 4 or 8).
`
228
238
`def _read_int(self, offset, width):
`
229
239
`if width not in (1, 2, 4, 8):
`
``
240
`+
self.close()
`
230
241
`raise ValueError("invalid int width")
`
231
242
`buf = self._read_bytes(offset, width)
`
232
243
`it = {1: "b", 2: "h", 4: "l", 8: "q"}[width]
`
`@@ -238,11 +249,13 @@ def _read_bytes(self, offset, length):
`
238
249
`self._path_or_buf.seek(offset)
`
239
250
`buf = self._path_or_buf.read(length)
`
240
251
`if len(buf) < length:
`
``
252
`+
self.close()
`
241
253
`msg = "Unable to read {:d} bytes from file position {:d}."
`
242
254
`raise ValueError(msg.format(length, offset))
`
243
255
`return buf
`
244
256
`else:
`
245
257
`if offset + length > len(self._cached_page):
`
``
258
`+
self.close()
`
246
259
`raise ValueError("The cached page is too small.")
`
247
260
`return self._cached_page[offset:offset + length]
`
248
261
``
`@@ -253,6 +266,7 @@ def _parse_metadata(self):
`
253
266
`if len(self._cached_page) <= 0:
`
254
267
`break
`
255
268
`if len(self._cached_page) != self._page_length:
`
``
269
`+
self.close()
`
256
270
`raise ValueError(
`
257
271
`"Failed to read a meta data page from the SAS file.")
`
258
272
`done = self._process_page_meta()
`
`@@ -302,6 +316,7 @@ def _get_subheader_index(self, signature, compression, ptype):
`
302
316
`if (self.compression != "") and f1 and f2:
`
303
317
`index = const.index.dataSubheaderIndex
`
304
318
`else:
`
``
319
`+
self.close()
`
305
320
`raise ValueError("Unknown subheader signature")
`
306
321
`return index
`
307
322
``
`@@ -598,6 +613,7 @@ def _read_next_page(self):
`
598
613
`if len(self._cached_page) <= 0:
`
599
614
`return True
`
600
615
`elif len(self._cached_page) != self._page_length:
`
``
616
`+
self.close()
`
601
617
`msg = ("failed to read complete page from file "
`
602
618
`"(read {:d} of {:d} bytes)")
`
603
619
`raise ValueError(msg.format(len(self._cached_page),
`
`@@ -643,6 +659,7 @@ def _chunk_to_dataframe(self):
`
643
659
`rslt.loc[ii, name] = np.nan
`
644
660
`js += 1
`
645
661
`else:
`
``
662
`+
self.close()
`
646
663
`raise ValueError("unknown column type %s" %
`
647
664
`self.column_types[j])
`
648
665
``