Repository: scikit-hep/hist

Issue:
[BUG] Repr on hist with empty StrCat kills kernel
```
import hist
from hist import Hist
import numpy as np

hehe = Hist(
    hist.axis.Regular(10, 0 ,10, name="a", label="a"),
    hist.axis.StrCategory("", name="dataset", growth=True),
    hist.storage.Weight(),
)

hehe.fill(dataset="A", a=np.random.normal(3, 2, 1000))
hehe
```
displays properly, whereas 
```
hehe = Hist(
    hist.axis.Regular(10, 0 ,10, name="a", label="a"),
    hist.axis.StrCategory("", name="dataset", growth=True),
    hist.storage.Weight(),
)

hehe
```
results in a dead kernel.

Discussion:
sourcery-ai[bot]: # Sourcery Code Quality Report


✅ &nbsp;Merging this PR will **increase** code quality in the affected files by **0.47%**.

| Quality metrics | Before | After | Change |
| --- | :---: | :---: | :---: |
| [Complexity](https://github.com/sourcery-ai/sourcery/wiki/Quality-Report#complexity) | 7.57 ⭐ | 7.44 ⭐ | -0.13 👍 |
| [Method Length](https://github.com/sourcery-ai/sourcery/wiki/Quality-Report#method-length) | 125.31 😞 | 122.08 😞 | -3.23 👍 |
| [Working memory](https://github.com/sourcery-ai/sourcery/wiki/Quality-Report#working-memory) | 8.48 🙂 | 8.44 🙂 | -0.04 👍 |
| **[Quality](https://github.com/sourcery-ai/sourcery/wiki/Quality-Report#quality-score)** | **59.51%** 🙂| **59.98%** 🙂| **0.47%** 👍 |



| Other metrics | Before | After | Change |
| --- | :---: | :---: | :---: |
| Lines | 1226 | 1246 | 20 |



| Changed files | Quality Before | Quality After | Quality Change |
| --- | :---: | :---: | :---: |
| src/hist/basehist.py | 65.19% 🙂 | 64.99% 🙂 | -0.20% 👎|
| tests/test_general.py | 56.83% 🙂 | 57.66% 🙂 | 0.83% 👍|



Here are some functions in these files that still need a tune-up:

| File | Function | Complexity | Length | Working Memory | Quality | Recommendation |
| --- | --- | :---: | :---: | :---: | :---: | --- |
| tests/test_general.py | test\_general\_fill | 48 ⛔ | 943 ⛔ | 10 😞 | 19.95% ⛔ | Refactor to reduce nesting. Try splitting into smaller methods. Extract out complex expressions |
| src/hist/basehist.py | BaseHist.\_\_init\_\_ | 18 🙂 | 176 😞 | 12 😞 | 40.32% 😞 | Try splitting into smaller methods. Extract out complex expressions |
| tests/test_general.py | test\_general\_project.test\_general\_transform\_proxy | 0 ⭐ | 470 ⛔ | 12 😞 | 46.77% 😞 | Try splitting into smaller methods. Extract out complex expressions |
| src/hist/basehist.py | BaseHist.from\_columns | 14 🙂 | 160 😞 | 11 😞 | 46.77% 😞 | Try splitting into smaller methods. Extract out complex expressions |
| tests/test_general.py | test\_init\_and\_fill | 5 ⭐ | 323 ⛔ | 7 🙂 | 54.18% 🙂 | Try splitting into smaller methods |


## Legend and Explanation

The emojis denote the absolute quality of the code:

 - ⭐ excellent
 - 🙂 good
 - 😞 poor
 - ⛔ very poor


The 👍 and 👎 indicate whether the quality has improved or gotten worse with this pull request.

***

Please see our documentation [here](https://github.com/sourcery-ai/sourcery/wiki/Quality-Report) for details on how these metrics are calculated.

We are actively working on this report - lots more documentation and extra metrics to come!

Help us [improve](https://research.typeform.com/to/j06Spdfr?type=quality_report&github_login=henryiii&base_repo=https%3A%2F%2Fgithub.com%2Fscikit-hep%2Fhist.git&base_remote_ref=refs%2Fpull%2F238%2Fhead&base_ref=henryiii%2Ffix%2Femptydisp&base_sha=ff88a0cf35a61685e764872b47221f06c55000e4&head_repo=https%3A%2F%2Fgithub.com%2Fscikit-hep%2Fhist.git&head_ref=sourcery%2Fhenryiii%2Ffix%2Femptydisp&base_pr_number=238&base_pr_state=open) this quality report!
sourcery-ai[bot]: # Sourcery Code Quality Report


✅ &nbsp;Merging this PR will **increase** code quality in the affected files by **0.62%**.

| Quality metrics | Before | After | Change |
| --- | :---: | :---: | :---: |
| [Complexity](https://github.com/sourcery-ai/sourcery/wiki/Quality-Report#complexity) | 7.57 ⭐ | 7.33 ⭐ | -0.24 👍 |
| [Method Length](https://github.com/sourcery-ai/sourcery/wiki/Quality-Report#method-length) | 125.31 😞 | 122.10 😞 | -3.21 👍 |
| [Working memory](https://github.com/sourcery-ai/sourcery/wiki/Quality-Report#working-memory) | 8.48 🙂 | 8.42 🙂 | -0.06 👍 |
| **[Quality](https://github.com/sourcery-ai/sourcery/wiki/Quality-Report#quality-score)** | **59.51%** 🙂| **60.13%** 🙂| **0.62%** 👍 |



| Other metrics | Before | After | Change |
| --- | :---: | :---: | :---: |
| Lines | 1226 | 1246 | 20 |



| Changed files | Quality Before | Quality After | Quality Change |
| --- | :---: | :---: | :---: |
| src/hist/basehist.py | 65.19% 🙂 | 65.48% 🙂 | 0.29% 👍|
| tests/test_general.py | 56.83% 🙂 | 57.66% 🙂 | 0.83% 👍|



Here are some functions in these files that still need a tune-up:

| File | Function | Complexity | Length | Working Memory | Quality | Recommendation |
| --- | --- | :---: | :---: | :---: | :---: | --- |
| tests/test_general.py | test\_general\_fill | 48 ⛔ | 943 ⛔ | 10 😞 | 19.95% ⛔ | Refactor to reduce nesting. Try splitting into smaller methods. Extract out complex expressions |
| src/hist/basehist.py | BaseHist.\_\_init\_\_ | 18 🙂 | 176 😞 | 12 😞 | 40.32% 😞 | Try splitting into smaller methods. Extract out complex expressions |
| tests/test_general.py | test\_general\_project.test\_general\_transform\_proxy | 0 ⭐ | 470 ⛔ | 12 😞 | 46.77% 😞 | Try splitting into smaller methods. Extract out complex expressions |
| src/hist/basehist.py | BaseHist.from\_columns | 12 🙂 | 160 😞 | 11 😞 | 48.49% 😞 | Try splitting into smaller methods. Extract out complex expressions |
| tests/test_general.py | test\_init\_and\_fill | 5 ⭐ | 323 ⛔ | 7 🙂 | 54.18% 🙂 | Try splitting into smaller methods |


## Legend and Explanation

The emojis denote the absolute quality of the code:

 - ⭐ excellent
 - 🙂 good
 - 😞 poor
 - ⛔ very poor


The 👍 and 👎 indicate whether the quality has improved or gotten worse with this pull request.

***

Please see our documentation [here](https://github.com/sourcery-ai/sourcery/wiki/Quality-Report) for details on how these metrics are calculated.

We are actively working on this report - lots more documentation and extra metrics to come!

Help us [improve](https://research.typeform.com/to/j06Spdfr?type=quality_report&github_login=henryiii&base_repo=https%3A%2F%2Fgithub.com%2Fscikit-hep%2Fhist.git&base_remote_ref=refs%2Fpull%2F238%2Fhead&base_ref=henryiii%2Ffix%2Femptydisp&base_sha=e1596398f51949e5f10d0bf3371722411d073c89&head_repo=https%3A%2F%2Fgithub.com%2Fscikit-hep%2Fhist.git&head_ref=sourcery%2Fhenryiii%2Ffix%2Femptydisp&base_pr_number=238&base_pr_state=open) this quality report!

Patch:
diff --git a/src/hist/basehist.py b/src/hist/basehist.py
index 2eea850..a862c51 100644
--- a/src/hist/basehist.py
+++ b/src/hist/basehist.py
@@ -116,7 +116,9 @@ class BaseHist(bh.Histogram, metaclass=MetaConstructor, family=hist):
         return NamedAxesTuple(self._axis(i) for i in range(self.ndim))
 
     def _repr_html_(self) -> str:
-        if self.ndim == 1:
+        if self.size == 0:
+            return str(self)
+        elif self.ndim == 1:
             if self.axes[0].traits.circular:
                 return str(html_hist(self, svg_hist_1d_c))
             else:
@@ -125,6 +127,7 @@ class BaseHist(bh.Histogram, metaclass=MetaConstructor, family=hist):
             return str(html_hist(self, svg_hist_2d))
         elif self.ndim > 2:
             return str(html_hist(self, svg_hist_nd))
+
         return str(self)
 
     def _name_to_index(self, name: str) -> int:
@@ -160,9 +163,9 @@ class BaseHist(bh.Histogram, metaclass=MetaConstructor, family=hist):
                     raise TypeError(
                         f"{ax} must be all int or strings if axis not given"
                     )
+            elif not ax.name or ax.name not in data:
+                raise TypeError("All axes must have names present in the data")
             else:
-                if not ax.name or ax.name not in data:
-                    raise TypeError("All axes must have names present in the data")
                 axes_list.append(ax)
 
         weight_arr = data[weight] if weight else None
@@ -233,16 +236,16 @@ class BaseHist(bh.Histogram, metaclass=MetaConstructor, family=hist):
         Convert some specific indices to step.
         """
 
-        if isinstance(x, complex):
-            if x.real != 0:
-                raise ValueError("The step should not have real part")
-            elif x.imag % 1 != 0:
-                raise ValueError("The imaginary part should be an integer")
-            else:
-                return bh.rebin(int(x.imag))
-        else:
+        if not isinstance(x, complex):
             return x
 
+        if x.real != 0:
+            raise ValueError("The step should not have real part")
+        elif x.imag % 1 != 0:
+            raise ValueError("The imaginary part should be an integer")
+        else:
+            return bh.rebin(int(x.imag))
+
     def _index_transform(self, index: IndexingExpr) -> bh.IndexingExpr:
         """
         Auxiliary function for __getitem__ and __setitem__.


Test patch:
diff --git a/tests/test_general.py b/tests/test_general.py
index 78ebf48..bd18512 100644
--- a/tests/test_general.py
+++ b/tests/test_general.py
@@ -846,3 +846,24 @@ def test_from_array(named_hist):
             axis.Regular(7, 1, 3, name="B"),
             data=np.ones((11, 9)),
         )
+
+
+def test_sum_empty_axis():
+    hist = bh.Histogram(
+        bh.axis.StrCategory("", growth=True),
+        bh.axis.Regular(10, 0, 1),
+        storage=bh.storage.Weight(),
+    )
+    assert hist.sum().value == 0
+    assert "Str" in repr(hist)
+
+
+def test_sum_empty_axis_hist():
+    h = Hist(
+        axis.StrCategory("", growth=True),
+        axis.Regular(10, 0, 1),
+        storage=storage.Weight(),
+    )
+    assert h.sum().value == 0
+    assert "Str" in repr(h)
+    h._repr_html_()