Skip to content

Commit e47badf

Browse files
ioanaifpre-commit-ci[bot]jpivarski
authored
feat: add support for std::bitset (#1182)
* feat: add support for bitset * style: pre-commit fixes * Update test file name to match pr nr --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Jim Pivarski <[email protected]>
1 parent de95747 commit e47badf

File tree

3 files changed

+117
-3
lines changed

3 files changed

+117
-3
lines changed

src/uproot/containers.py

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,9 @@ class AsVectorLike(AsContainer):
864864

865865
def __init__(self, header, values):
866866
self.header = header
867-
if isinstance(values, AsContainer):
867+
if isinstance(self, uproot.containers.AsBitSet):
868+
self._items = numpy.dtype(numpy.bool_)
869+
elif isinstance(values, AsContainer):
868870
self._items = values
869871
elif isinstance(values, type) and issubclass(
870872
values, (uproot.model.Model, uproot.model.DispatchByVersion)
@@ -1117,7 +1119,6 @@ class AsList(AsVectorLike):
11171119
header (bool): Sets the :ref:`uproot.containers.AsContainer.header`.
11181120
values (:doc:`uproot.model.Model` or :doc:`uproot.containers.Container`): Data
11191121
type for data nested in the container.
1120-
11211122
A :doc:`uproot.containers.AsContainer` for ``std::list``.
11221123
"""
11231124

@@ -1139,6 +1140,36 @@ def _container_type(self):
11391140
return STLList
11401141

11411142

1143+
class AsBitSet(AsVectorLike):
1144+
"""
1145+
Args:
1146+
header (bool): Sets the :ref:`uproot.containers.AsContainer.header`.
1147+
keys (:doc:`uproot.model.Model` or :doc:`uproot.containers.Container`): Data
1148+
type for data nested in the container.
1149+
1150+
A :doc:`uproot.containers.AsContainer` for ``std::bitset``.
1151+
"""
1152+
1153+
_specialpathitem_name = "bitset"
1154+
1155+
@property
1156+
def typename(self):
1157+
return f"std::bitset<{_content_typename(self.keys)}>"
1158+
1159+
@property
1160+
def keys(self):
1161+
"""
1162+
Data type for data nested in the container.
1163+
"""
1164+
return self._items
1165+
1166+
_form_parameters = {"__array__": "bitset"}
1167+
1168+
@property
1169+
def _container_type(self):
1170+
return STLBitSet
1171+
1172+
11421173
class AsSet(AsVectorLike):
11431174
"""
11441175
Args:
@@ -1633,6 +1664,49 @@ def tolist(self):
16331664
]
16341665

16351666

1667+
class STLBitSet(Container, Sequence):
1668+
"""
1669+
Args:
1670+
values (``numpy.ndarray`` or iterable): Contents of the ``std::vector``.
1671+
1672+
Representation of a C++ ``std::bitset`` as a Python ``Sequence``.
1673+
"""
1674+
1675+
def __init__(self, numbytes):
1676+
self._numbytes = numpy.asarray(numbytes)
1677+
1678+
def __str__(self, limit=85):
1679+
def tostring(i):
1680+
return _tostring(self._values[i])
1681+
1682+
return _str_with_ellipsis(tostring, len(self), "[", "]", limit)
1683+
1684+
def __repr__(self, limit=85):
1685+
return f"<STLBitSet {self.__str__(limit=limit - 30)} at 0x{id(self):012x}>"
1686+
1687+
def __getitem__(self, where):
1688+
return self._numbytes[where]
1689+
1690+
def __len__(self):
1691+
return self._numbytes
1692+
1693+
def __iter__(self):
1694+
return iter(self._numbytes)
1695+
1696+
def __eq__(self, other):
1697+
if isinstance(other, STLBitSet):
1698+
return self._numbytes == other._numbytes
1699+
elif isinstance(other, Sequence):
1700+
return self._numbytes == other
1701+
else:
1702+
return False
1703+
1704+
def tolist(self):
1705+
return [
1706+
x.tolist() if isinstance(x, (Container, numpy.ndarray)) else x for x in self
1707+
]
1708+
1709+
16361710
class STLSet(Container, Set):
16371711
"""
16381712
Args:

src/uproot/interpretation/identify.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,7 @@ def _parse_node(tokens, i, typename, file, quote, header, inner_header):
964964
return (
965965
i + 4,
966966
_parse_maybe_quote(
967-
f'uproot.containers.AsFIXME("std::bitset<{num_bits}>")',
967+
f"uproot.containers.AsBitSet({header}, {num_bits})",
968968
quote,
969969
),
970970
)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# BSD 3-Clause License; see https://github.com/scikit-hep/uproot5/blob/main/LICENSE
2+
3+
import uproot
4+
import skhep_testdata
5+
6+
7+
def test_add_support_for_bitset():
8+
with uproot.open(skhep_testdata.data_path("uproot-issue-40.root")) as f:
9+
assert (
10+
repr(f["tree"]["bitset8"].interpretation)
11+
== "AsObjects(AsBitSet(True, dtype('bool')))"
12+
)
13+
assert (
14+
repr(f["tree"]["bitset16"].interpretation)
15+
== "AsObjects(AsBitSet(True, dtype('bool')))"
16+
)
17+
18+
assert f["tree"]["bitset8"].array().tolist() == [
19+
[True, False, True, False, True, False, False, False]
20+
]
21+
assert f["tree"]["bitset16"].array().tolist() == [
22+
[
23+
False,
24+
True,
25+
False,
26+
True,
27+
False,
28+
True,
29+
True,
30+
True,
31+
True,
32+
False,
33+
True,
34+
False,
35+
True,
36+
False,
37+
False,
38+
False,
39+
]
40+
]

0 commit comments

Comments
 (0)