Skip to content

Commit 4f90780

Browse files
authored
Fix: IS_IN_SET with multiple values (#742)
* Fix: IS_IN_SET with multiple values strkeys is a map object (a lazy iterator in Python 3, unlike Python 2 where it returned a list). This means If you try to check membership with **in**, it exhausts the iterator progressively, this leads to very funny errors and sometimes the validator would seem to work correctly depending on the order. * chore: add tests to make sure IS_IN_SET multiple stays fixed
1 parent 06433f5 commit 4f90780

File tree

2 files changed

+4
-1
lines changed

2 files changed

+4
-1
lines changed

pydal/validators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ def validate(self, value, record_id=None):
590590
raise ValidationError(self.translator(self.error_message))
591591
else:
592592
values = [value]
593-
strkeys = map(str, valuemap)
593+
strkeys = set(map(str, valuemap))
594594
failures = [x for x in values if not str(x) in strkeys]
595595
if failures and self.theset:
596596
raise ValidationError(self.translator(self.error_message))

tests/validators.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ def test_IS_IN_SET(self):
180180
self.assertEqual(rtn, ("massimo", "Value not allowed"))
181181
rtn = IS_IN_SET(["max", "john"], multiple=True)(("max", "john"))
182182
self.assertEqual(rtn, (("max", "john"), None))
183+
# order reversed should still be fine
184+
rtn = IS_IN_SET(["max", "john"], multiple=True)(("john", "max"))
185+
self.assertEqual(rtn, (("john", "max"), None))
183186
rtn = IS_IN_SET(["max", "john"], multiple=True)(("bill", "john"))
184187
self.assertEqual(rtn, (("bill", "john"), "Value not allowed"))
185188
rtn = IS_IN_SET(("id1", "id2"), ["first label", "second label"])(

0 commit comments

Comments
 (0)