Skip to content

v0.16.0

Latest

Choose a tag to compare

@nsoranzo nsoranzo released this 29 Oct 01:41
2929e48

What's Changed

Breaking changes

  • Dropped support for Python 3.10, which reached end of life on 2026-10-01. Python >= 3.11 is now required.
  • Temporarily stopped building PyPy 3.12 wheels, because NumPy 2.5.0 dropped support for PyPy 3.12. They will come back once numpy/numpy#32332 is merged.

Performance

  • Alignment.remove_all_gap_columns() now runs in linear time and compacts components shared between alignments only once. For 80,000 columns of which 90% are all-gap, it takes about 0.02 s instead of 3 s, and its peak extra memory use with 100 components drops from 61 MiB to 1.1 MiB. By @DylanCosto in #124

Bug fixes

  • Fixed remove_all_gap_columns() misaligning sequences after an empty component, which could leave all-gap columns in the following components.
  • Fixed bx.seq.SeqFile handling of the revcomp parameter: with "+5'" or "-3'", get() silently returned the reverse complement of the wrong interval.
  • Fixed bx.align.core.get_reader() and get_indexed() passing species_to_lengths to the wrong parameter. This made get_reader() fail with a TypeError for MAF and AXT, and get_indexed() ignore it.
  • Passed memo to the deepcopy() calls in Alignment.__deepcopy__(), so objects shared between alignments (e.g. the species_to_lengths dict) are no longer duplicated inside a single deep copy.
  • read_lengths_file() now closes the file when a line is malformed.
  • lav.Reader now names the right file when the second sequence file can't be opened.

Other changes

  • Added type annotations to bx.align.core and to the functions it relies on in bx.align.axt, bx.align.lav, bx.align.maf and bx.misc.readlengths. This brings some small behaviour changes for invalid input:
    • Alignment.slice_by_component() raises ValueError when no component matches the given src, instead of AttributeError.
    • Alignment.column_iter() and Component.coord_to_col() raise ValueError for a non-empty component without text, instead of TypeError.
    • maf.Writer.write() asserts that the required component fields are set, instead of failing with TypeError.
    • SeqFile.get() now raises AssertionError for falsy revcomp values other than False (e.g. 0, None, "").

New Contributors

Full Changelog: v0.15.1...v0.16.0