Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/python-package-conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest, macos-latest, windows-latest, ubuntu-24.04-arm, macos-13]
os: [ubuntu-latest, macos-latest, windows-latest, ubuntu-24.04-arm, macos-15-intel]
python_version: ${{ fromJSON(needs.conf.outputs.supported_pythons) }}
use_conda: [true, false]
steps:
Expand Down
7 changes: 7 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
BIOM-Format ChangeLog
=====================

biom-2.1.18-dev
---------------

Bug fixes:

* A regression with parse of UTF-8 characters was introduced, reported [here](https://forum.qiime2.org/t/feature-table-gives-ascii-codec-cant-decode-byte-0xc3-in-position-4-error/33858/7)

biom-2.1.17
-----------

Expand Down
8 changes: 6 additions & 2 deletions biom/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -4182,11 +4182,15 @@ def ensure_utf8(x):
def axis_load(grp):
"""Loads all the data of the given group"""
# fetch all of the IDs
ids = grp['ids'][:]
ids = grp['ids']

if ids.size > 0:
ids = ids.asstr()[:]
ids_dtype = 'U%d' % max([len(v) for v in ids])
ids = np.asarray(ids, dtype=ids_dtype)
else:
# .asstr does not handle an empty dataset

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🫤 that feels rude of h5py

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be HDF5 as the C-API is touchy. Or, we may not be correctly enforcing types on empty tables

ids = ids[:]

parser = defaultdict(lambda: general_parser)
parser['taxonomy'] = vlen_list_of_str_parser
Expand Down Expand Up @@ -4234,7 +4238,7 @@ def _get_ids(source_ids, desired_ids):
else:
desired_ids = np.asarray(desired_ids)
# Get the index of the source ids to include
idx = np.in1d(source_ids, desired_ids)
idx = np.isin(source_ids, desired_ids)
# Retrieve only the ids that we are interested on
ids = source_ids[idx]
# Check that all desired ids have been found on source ids
Expand Down
10 changes: 10 additions & 0 deletions biom/tests/test_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import numpy as np
import numpy.testing as npt

from biom import example_table
from biom.parse import (generatedby, MetadataMap, parse_biom_table, parse_uc,
load_table, save_table)
from biom.table import Table
Expand Down Expand Up @@ -283,6 +284,15 @@ def test_parse_adjacency_table_no_header(self):
obs = Table.from_adjacency(''.join(lines))
self.assertEqual(obs, exp)

def test_parse_biom_table_hdf5_accent_utf8_regression(self):
tab = example_table.copy()
tab.update_ids({i: f'{i}fóó' for i in tab.ids()}, inplace=True)
with NamedTemporaryFile(delete=False) as tmpfile:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should delete be False? I think this would leave behind a file on the system.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potentially, but err'ing on following the style of the rest of the script. And, a left over file in TMPDIR isn't the best but not the worst thing to do

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see. It looks like those add this to the end of the test:

self.to_remove.append(tmpfile.name)

It's mostly github's problem these days I suppose. So your call, but wanted to mention it.

with h5py.File(tmpfile.name, 'w') as fp:
tab.to_hdf5(fp, 'asf')
obs = load_table(tmpfile.name)
self.assertEqual(obs, tab)

def test_parse_biom_table_hdf5(self):
"""Make sure we can parse a HDF5 table through the same loader"""
cwd = os.getcwd()
Expand Down
Loading