Skip to content

Commit

Permalink
stop the ordering of variants in a dict from being checked
Browse files Browse the repository at this point in the history
  • Loading branch information
cosmicexplorer committed Feb 7, 2019
1 parent 58b3a5c commit b102e07
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/python/pants/util/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,10 @@ def resolve_for_enum_variant(self, mapping):
NB: The objects in `mapping` should be made into lambdas if lazy execution is desired, as this
will "evaluate" all of the values in `mapping`.
"""
keys = OrderedSet(mapping.keys())
# Equality between a frozenset() and an OrderedSet() is done without respect to ordering,
# which is what we want here. We only maintain an OrderedSet() in self.allowed_values so that
# we can present error messages with the same arguments used in the constructor.
keys = frozenset(mapping.keys())
if keys != self.allowed_values:
raise self.make_type_error(
"pattern matching must have exactly the keys {} (was: {})"
Expand Down
15 changes: 15 additions & 0 deletions tests/python/pants_test/util/test_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from future.utils import PY2, PY3, text_type

from pants.util.collections_abc_backport import OrderedDict
from pants.util.objects import (Collection, EnumVariantSelectionError, Exactly, SubclassesOf,
SuperclassesOf, TypeCheckError,
TypedDatatypeInstanceConstructionError, datatype, enum)
Expand Down Expand Up @@ -661,3 +662,17 @@ def test_enum_resolve_variant(self):
one_enum_instance.resolve_for_enum_variant({
1: 3,
})

# Test that the ordering of the values in the enum constructor is not relevant for testing
# whether all variants are provided.
class OutOfOrderEnum(enum([2, 1, 3])): pass
two_out_of_order_instance = OutOfOrderEnum(2)
# This OrderedDict mapping is in a different order than in the enum constructor. This test means
# we can rely on providing simply a literal dict to resolve_for_enum_variant() and not worry
# that the dict ordering will cause an error.
letter = two_out_of_order_instance.resolve_for_enum_variant(OrderedDict([
(1, 'b'),
(2, 'a'),
(3, 'c'),
]))
self.assertEqual(letter, 'a')

0 comments on commit b102e07

Please sign in to comment.