Skip to content

Commit 7af6a63

Browse files
authored
Merge pull request #1119 from effigies/fix/padded-int-arrays
fix: Allow numpy arrays to treat PaddedInt like int
2 parents 85eacf2 + 0aa2977 commit 7af6a63

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

src/bids/layout/tests/test_utils.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
import os
44

5+
import numpy as np
56
import pytest
7+
import pandas as pd
68
import bids
79
from bids.exceptions import ConfigError
810

911
from ..models import Entity, Config
10-
from ..utils import BIDSMetadata, parse_file_entities, add_config_paths
12+
from ..utils import BIDSMetadata, PaddedInt, parse_file_entities, add_config_paths
1113

1214

1315
def test_bidsmetadata_class():
@@ -73,3 +75,31 @@ def test_add_config_paths():
7375
add_config_paths(dummy=bids_json)
7476
config = Config.load('dummy')
7577
assert 'subject' in config.entities
78+
79+
80+
def test_PaddedInt_array_comparisons():
81+
# Array comparisons should work, not raise exceptions
82+
arr = np.array([5, 5, 5])
83+
assert np.all(arr == PaddedInt(5))
84+
assert np.all(arr == PaddedInt("05"))
85+
assert np.all(PaddedInt(5) == arr)
86+
assert np.all(PaddedInt("05") == arr)
87+
88+
# If the value gets put into an array, it should be considered an int
89+
# We lose the padding, but it's unlikely we would try to recover it
90+
# from an array.
91+
assert np.array([PaddedInt(5)]).dtype == np.int64
92+
93+
# Verify that we do get some False results
94+
assert np.array_equal(np.array([4, 5, 6]) == PaddedInt(5), [False, True, False])
95+
96+
97+
def test_PaddedInt_dataframe_behavior():
98+
# Verify that pandas dataframes are not more special than numpy arrays,
99+
# as far as PaddedInt is concerned
100+
df = pd.DataFrame({'a': [5, 5, 5]})
101+
pidf = pd.DataFrame({'a': [PaddedInt(5)] * 3})
102+
assert np.all(df['a'] == PaddedInt(5))
103+
assert np.all(df == pidf)
104+
105+
assert pidf['a'].dtype is np.dtype('int64')

src/bids/layout/utils.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,13 @@ def __init__(self, val):
6565
self.sval = str(val)
6666

6767
def __eq__(self, val):
68-
return val == self.sval or super().__eq__(val)
68+
try:
69+
return val == self.sval or super().__eq__(val)
70+
except ValueError:
71+
# `or` triggers `__bool__`. If this fails, it is almost
72+
# certainly an array type. Do not attempt string comparisons
73+
# and allow val to determine the return type
74+
return val == self
6975

7076
def __str__(self):
7177
return self.sval

0 commit comments

Comments
 (0)