Make AlignmentFile __dealloc__ and close more stringent
@@ -146,8 +146,7 @@ cdef bam_hdr_t * build_header_from_dict(new_header):
This method inserts the text field, target_name and target_len.
'''
-
- lines = []
+ cdef list lines = []
# create new header and copy old data
cdef bam_hdr_t * dest = bam_hdr_init()
@@ -1300,16 +1299,22 @@ cdef class AlignmentFile(HTSFile):
return res
def close(self):
- '''
- closes the :class:`pysam.AlignmentFile`.'''
+ '''closes the :class:`pysam.AlignmentFile`.'''
if self.htsfile == NULL:
return
cdef int ret = hts_close(self.htsfile)
- hts_idx_destroy(self.index)
self.htsfile = NULL
+ if self.index != NULL:
+ hts_idx_destroy(self.index)
+ self.index = NULL
+
+ if self.header != NULL:
+ bam_hdr_destroy(self.header)
+ self.header = NULL
+
if ret < 0:
global errno
if errno == EPIPE:
@@ -1318,28 +1323,23 @@ cdef class AlignmentFile(HTSFile):
raise OSError(errno, force_str(strerror(errno)))
def __dealloc__(self):
- # remember: dealloc cannot call other methods
- # note: no doc string
- # note: __del__ is not called.
-
- # FIXME[kbj]: isn't self.close a method? I've been duplicating
- # close within __dealloc__ (see BCFFile.__dealloc__). Not a pretty
- # solution and perhaps unnecessary given that calling self.close has
- # been working for years.
- # AH: I have removed the call to close. Even though it is working,
- # it seems to be dangerous according to the documentation as the
- # object be partially deconstructed already.
- cdef int ret = 0
+ cdef int ret
if self.htsfile != NULL:
ret = hts_close(self.htsfile)
- hts_idx_destroy(self.index);
self.htsfile = NULL
- bam_destroy1(self.b)
+ if self.index != NULL:
+ hts_idx_destroy(self.index)
+ self.index = NULL
+
if self.header != NULL:
bam_hdr_destroy(self.header)
+ self.header = NULL
+ if self.b:
+ bam_destroy1(self.b)
+ self.b = NULL
if ret < 0:
global errno
