Skip to content

Commit f5f4933

Browse files
committed
CPP histgram returns CPP axis now
1 parent 48563a9 commit f5f4933

File tree

4 files changed

+85
-20
lines changed

4 files changed

+85
-20
lines changed

boost_histogram/_internal/hist.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,9 @@ def _arg_shortcut(item):
2929
elif isinstance(item, Axis):
3030
return item._ax
3131
else:
32-
# TODO: This currently support raw axis object for old tests.
33-
# Replace with:
34-
# raise TypeError("Only axes supported in histogram constructor")
32+
raise TypeError("Only axes supported in histogram constructor")
3533
# TODO: Currently segfaults if we pass in a non-axis to the C++ code
36-
return cast(item, Axis)._ax
34+
# Using the public interface above, this should never be possible.
3735

3836

3937
def _expand_ellipsis(indexes, rank):
@@ -71,7 +69,7 @@ def _compute_commonindex(hist, index, expand):
7169
# Allow [bh.loc(...)] to work
7270
for i in range(len(indexes)):
7371
if callable(indexes[i]):
74-
indexes[i] = indexes[i](cast(hist.axis(i), Axis))
72+
indexes[i] = indexes[i](cast(hist.axis(i), Axis, cpp=False))
7573
elif hasattr(indexes[i], "flow"):
7674
if indexes[i].flow == 1:
7775
indexes[i] = hist.axis(i).size
@@ -203,14 +201,17 @@ def _axis(self, i):
203201
"""
204202
Get N-th axis.
205203
"""
206-
return cast(self._hist.axis(i), Axis)
204+
return cast(self._hist.axis(i), Axis, self._cpp_module)
207205

208206
@property
209207
def _storage_type(self):
210-
return cast(self._hist._storage_type, Storage, is_class=True)
208+
return cast(
209+
self._hist._storage_type, Storage, cpp=self._cpp_module, is_class=True
210+
)
211211

212212

213213
class histogram(BaseHistogram):
214+
_cpp_module = True
214215
axis = BaseHistogram._axis
215216

216217
def rank(self):
@@ -260,6 +261,8 @@ def _project(self, *args):
260261

261262

262263
class Histogram(BaseHistogram):
264+
_cpp_module = False
265+
263266
@inject_signature("self, *axes, storage=Double()", locals={"Double": Double})
264267
def __init__(self, *args, **kwargs):
265268
super(Histogram, self).__init__(*args, **kwargs)

boost_histogram/_internal/utils.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def cpp_module(cls):
88
Simple decorator to declare a class to be in the cpp
99
module.
1010
"""
11-
cls._cpp_mode = True
11+
cls._cpp_module = True
1212
return cls
1313

1414

@@ -24,15 +24,20 @@ def register(*args):
2424
"""
2525

2626
def add_registration(cls):
27+
if len(args) == 0:
28+
cls._types = set()
29+
return cls
30+
2731
if not hasattr(cls, "_types"):
2832
cls._types = set()
33+
2934
for cpp_type in args:
3035
if cpp_type in cls._types:
3136
raise TypeError("You are trying to register {} again".format(cpp_type))
3237

3338
cls._types.add(cpp_type)
34-
if not hasattr(cls, "_cpp_mode"):
35-
cls._cpp_mode = False
39+
if not hasattr(cls, "_cpp_module"):
40+
cls._cpp_module = False
3641
return cls
3742

3843
return add_registration
@@ -59,7 +64,7 @@ def cast(cpp_object, parent_class, cpp=False, is_class=False):
5964
if (
6065
hasattr(canidate_class, "_types")
6166
and cpp_class in canidate_class._types
62-
and canidate_class._cpp_mode == cpp
67+
and canidate_class._cpp_module == cpp
6368
):
6469
if is_class:
6570
return canidate_class

boost_histogram/cpp/axis/__init__.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,32 @@
44

55
__all__ = ("options", "regular", "variable", "integer", "category", "transorm")
66

7-
from ...axis import (
8-
options,
9-
Regular as regular,
10-
Variable as variable,
11-
Integer as integer,
12-
Category as category,
13-
)
14-
15-
# TODO: Make these proper classes with proper names/module
7+
from ... import axis as _axis
8+
from ..._internal.utils import cpp_module as _cpp_module
169

10+
from ...axis import options
1711
from . import transform
12+
13+
14+
@_cpp_module
15+
class regular(_axis.Regular):
16+
def __repr__(self):
17+
return repr(self._ax)
18+
19+
20+
@_cpp_module
21+
class variable(_axis.Variable):
22+
def __repr__(self):
23+
return repr(self._ax)
24+
25+
26+
@_cpp_module
27+
class integer(_axis.Integer):
28+
def __repr__(self):
29+
return repr(self._ax)
30+
31+
32+
@_cpp_module
33+
class category(_axis.Category):
34+
def __repr__(self):
35+
return repr(self._ax)

tests/test_boost_histogram.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,42 @@ def test_convert_bh():
2727

2828
assert not hasattr(h, "axis")
2929
assert hasattr(h, "axes")
30+
31+
32+
def test_reprs():
33+
# Mixing bh/bhc is fine; histogram correctly always returns matching axis,
34+
# axis returns matching transform, etc.
35+
h = bhc.histogram(bh.axis.Regular(4, 0, 4))
36+
assert (
37+
repr(h)
38+
== """\
39+
histogram(regular(4, 0, 4, metadata="None", options=underflow | overflow))
40+
+--------------------------------------------------------------+
41+
[-inf, 0) 0 | |
42+
[ 0, 1) 0 | |
43+
[ 1, 2) 0 | |
44+
[ 2, 3) 0 | |
45+
[ 3, 4) 0 | |
46+
[ 4, inf) 0 | |
47+
+--------------------------------------------------------------+
48+
"""
49+
)
50+
51+
assert (
52+
repr(h.axis(0))
53+
== 'regular(4, 0, 4, metadata="None", options=underflow | overflow)'
54+
)
55+
56+
57+
def test_axis_reprs():
58+
ax = bhc.axis.regular(4, 0, 4)
59+
assert repr(ax) == 'regular(4, 0, 4, metadata="None", options=underflow | overflow)'
60+
assert repr(type(ax)) == "<class 'boost_histogram.cpp.axis.regular'>"
61+
62+
63+
def test_storage_repr():
64+
pass # TODO: Not implemented yet
65+
66+
67+
def test_transform_repr():
68+
pass # TODO: Not implemented yet

0 commit comments

Comments
 (0)