diff --git a/pysam/libcutils.pyx b/pysam/libcutils.pyx index 7a03f3c44..002df096d 100644 --- a/pysam/libcutils.pyx +++ b/pysam/libcutils.pyx @@ -46,14 +46,19 @@ cpdef array_to_qualitystring(c_array.array qualities, int offset=33): """convert an array of quality values to a string.""" if qualities is None: return None - cdef int x - cdef c_array.array result - result = c_array.clone(qualities, len(qualities), zero=False) + cdef const unsigned char[::1] qualities_view = qualities + cdef size_t n = qualities_view.shape[0] - for x from 0 <= x < len(qualities): - result[x] = qualities[x] + offset - return force_str(result.tobytes()) + cdef bytearray result_ba = bytearray(n) + cdef unsigned char[::1] result_view = result_ba + + cdef size_t i + + for i in range(n): + result_view[i] = qualities_view[i] + offset + + return force_str(bytes(result_ba)) cpdef qualities_to_qualitystring(qualities, int offset=33): diff --git a/tests/AlignedSegment_test.py b/tests/AlignedSegment_test.py index 0e850600a..567640580 100644 --- a/tests/AlignedSegment_test.py +++ b/tests/AlignedSegment_test.py @@ -1901,5 +1901,27 @@ def test_string_export_import_with_tags(self): self.assertEqual(a, b) +class TestArrayUtilities(unittest.TestCase): + def test_array_to_qualstr(self): + data = [ + "", + "Q", + """!"#$%&'()*+,-./012...xyz{|}~""", + ">>?AB", + "ABDDEFGHIJabcdefghij", + "ACAFFGGFFFJDFJHHJIJIHKGGHKHHIJHHHJ7123" * 50, + ] + + for qual in data: + qual_array = pysam.qualitystring_to_array(qual) + result = pysam.array_to_qualitystring(qual_array) + self.assertEqual(result, qual) + + def test_longarray_to_qualstr(self): + qual_array = array.array('l', [64, 65, 66, 67, 68]) + with self.assertRaises(ValueError): + pysam.array_to_qualitystring(qual_array) + + if __name__ == "__main__": unittest.main() diff --git a/tests/libcutils_bench.py b/tests/libcutils_bench.py new file mode 100644 index 000000000..c85983066 --- /dev/null +++ b/tests/libcutils_bench.py @@ -0,0 +1,10 @@ +"""Benchmarking the libcutils module. Usage:: + +pytest tests/libcutils_bench.py +""" +import pysam + + +def test_array_to_qualitystring_long_sequences(benchmark): + result = benchmark(pysam.array_to_qualitystring, pysam.qualitystring_to_array("123") * 500) + assert result == "123" * 500