10000 Overhaul AlignmentFile error reporting · pysam-developers/pysam@a36e656 · GitHub
[go: up one dir, main page]

Skip to content

Commit a36e656

Browse files
committed
Overhaul AlignmentFile error reporting
Use OSError_from_errno() throughout for I/O errors, and check for errors from sam_hdr_write() and bgzf_seek().
1 parent ab6c58f commit a36e656

File tree

1 file changed

+23
-26
lines changed

1 file changed

+23
-26
lines changed

pysam/libcalignmentfile.pyx

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ import re
6565
import warnings
6666
import array
6767
from libc.errno cimport errno, EPIPE
68-
from libc.string cimport strcmp, strpbrk, strerror
68+
from libc.string cimport strcmp, strpbrk
6969
from libc.stdint cimport INT32_MAX
7070

7171
from cpython cimport array as c_array
7272

7373
from pysam.libcutils cimport force_bytes, force_str, charptr_to_str
74-
from pysam.libcutils cimport encode_filename, from_string_and_size
74+
from pysam.libcutils cimport OSError_from_errno, encode_filename, from_string_and_size
7575
from pysam.libcalignedsegment cimport makeAlignedSegment, makePileupColumn
7676
from pysam.libchtslib cimport HTSFile, hisremote, sam_index_load2, sam_index_load3, \
7777
HTS_IDX_SAVE_REMOTE, HTS_IDX_SILENT_FAIL
@@ -818,6 +818,7 @@ cdef class AlignmentFile(HTSFile):
818818
cdef char *cindexname = NULL
819819
cdef char *cmode = NULL
820820
cdef bam_hdr_t * hdr = NULL
821+
cdef int ret
821822

822823
if threads > 1 and ignore_truncation:
823824
# This won't raise errors if reaching a truncated alignment,
@@ -921,9 +922,7 @@ cdef class AlignmentFile(HTSFile):
921922

922923
if self.htsfile == NULL:
923924
if errno:
924-
raise IOError(errno, "could not open alignment file `{}`: {}".format(
925-
force_str(filename),
926-
force_str(strerror(errno))))
925+
raise OSError_from_errno("Could not open alignment file", filename)
927926
else:
928927
raise ValueError("could not open alignment file `{}`".format(force_str(filename)))
929928
if format_options and len(format_options):
@@ -939,16 +938,17 @@ cdef class AlignmentFile(HTSFile):
939938
if "b" in mode or "c" in mode or "h" in mode:
940939
hdr = self.header.ptr
941940
with nogil:
942-
sam_hdr_write(self.htsfile, hdr)
941+
ret = sam_hdr_write(self.htsfile, hdr)
942+
if ret < 0:
943+
raise OSError_from_errno("Could not write headers", filename)
943944

944945
elif mode[0] == "r":
945946
# open file for reading
946947
self.htsfile = self._open_htsfile()
947948

948949
if self.htsfile == NULL:
949950
if errno:
950-
raise IOError(errno, "could not open alignment file `{}`: {}".format(force_str(filename),
951-
force_str(strerror(errno))))
951+
raise OSError_from_errno("Could not open alignment file", filename)
952952
else:
953953
raise ValueError("could not open alignment file `{}`".format(force_str(filename)))
954954

@@ -1014,7 +1014,7 @@ cdef class AlignmentFile(HTSFile):
10141014

10151015
if not self.index and (cindexname or require_index):
10161016
if errno:
1017-
raise IOError(errno, force_str(strerror(errno)))
1017+
raise OSError_from_errno("Could not open index file", self.index_filename)
10181018
else:
10191019
raise IOError('unable to open index file `%s`' % self.index_filename)
10201020

@@ -1679,12 +1679,11 @@ cdef class AlignmentFile(HTSFile):
16791679

16801680
self.header = None
16811681

1682-
if ret < 0:
1683-
global errno
1684-
if errno == EPIPE:
1685-
errno = 0
1682+
if ret < 0 and errno != EPIPE:
1683+
if isinstance(self.filename, (str, bytes)):
1684+
raise OSError_from_errno("Closing failed", self.filename)
16861685
else:
1687-
raise IOError(errno, force_str(strerror(errno)))
1686+
raise OSError_from_errno("Closing failed")
16881687

16891688
def __dealloc__(self):
16901689
cdef int ret = 0
@@ -1703,12 +1702,11 @@ cdef class AlignmentFile(HTSFile):
17031702
bam_destroy1(self.b)
17041703
self.b = NULL
17051704

1706-
if ret < 0:
1707-
global errno
1708-
if errno == EPIPE:
1709-
errno = 0
1705+
if ret < 0 and errno != EPIPE:
1706+
if isinstance(self.filename, (str, bytes)):
1707+
raise OSError_from_errno("Closing failed", self.filename)
17101708
else:
1711-
raise IOError(errno, force_str(strerror(errno)))
1709+
raise OSError_from_errno("Closing failed")
17121710

17131711
cpdef int write(self, AlignedSegment read) except -1:
17141712
'''
@@ -1742,8 +1740,7 @@ cdef class AlignmentFile(HTSFile):
17421740
# when ret == -1 we get a "SystemError: error return without
17431741
# exception set".
17441742
if ret < 0:
1745-
raise IOError(
1746-
"sam_write1 failed with error code {}".format(ret))
1743+
raise IOError("sam_write1 failed with error code {}".format(ret))
17471744

17481745
return ret
17491746

@@ -2298,14 +2295,14 @@ cdef class IteratorRowSelection(IteratorRow):
22982295
# end iteration if out of positions
22992296
if self.current_pos >= len(self.positions): return -1
23002297

2298+
cdef int ret
23012299
cdef uint64_t pos = self.positions[self.current_pos]
23022300
with nogil:
2303-
bgzf_seek(hts_get_bgzfp(self.htsfile),
2304-
pos,
2305-
0)
2301+
ret = bgzf_seek(hts_get_bgzfp(self.htsfile), pos, 0)
2302+
if ret < 0:
2303+
raise OSError_from_errno("Can't seek", self.samfile.filename)
23062304
self.current_pos += 1
23072305

2308-
cdef int ret
23092306
cdef bam_hdr_t * hdr = self.header.ptr
23102307
with nogil:
23112308
ret = sam_read1(self.htsfile,
@@ -2911,7 +2908,7 @@ cdef class IndexedReads:
29112908
with nogil:
29122909
self.htsfile = hts_open(cfilename, 'r')
29132910
if self.htsfile == NULL:
2914-
raise OSError("unable to reopen htsfile")
2911+
raise OSError_from_errno("Unable to reopen file", cfilename)
29152912

29162913
# need to advance in newly opened file to position after header
29172914
# better: use seek/tell?

0 commit comments

Comments
 (0)
0