Skip to content

Commit cfbd1d6

Browse files
authored
Object equality fixes (cloudtools#2200)
- Add __hash__ to the Parameter class - Disable validation when doing BaseAWSObject object comparison __eq__
1 parent 55599ec commit cfbd1d6

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

tests/test_basic.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
cloudformation,
2121
depends_on_helper,
2222
)
23+
from troposphere.cloudformation import Stack
2324
from troposphere.ec2 import Instance, NetworkInterface, Route, SecurityGroupRule
2425
from troposphere.elasticloadbalancing import HealthCheck
2526
from troposphere.s3 import Bucket, PublicRead
@@ -117,6 +118,10 @@ def test___ne__(self):
117118
assert GenericHelperFn("foobar") != TypeComparator(AWSObject)
118119
assert TypeComparator(AWSObject) != GenericHelperFn("foobar")
119120

121+
# Testing __ne__ for objects missing required properties
122+
assert Parameter("param1") != Parameter("param2")
123+
assert Stack("stack1") != Stack("stack2")
124+
120125
def test_badproperty(self):
121126
with self.assertRaises(AttributeError):
122127
Instance(

troposphere/__init__.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,8 @@ def no_validation(self: __BaseAWSObjectTypeVar) -> __BaseAWSObjectTypeVar:
335335
self.do_validation = False
336336
return self
337337

338-
def to_dict(self) -> Dict[str, Any]:
339-
if self.do_validation:
338+
def to_dict(self, validation: bool = True) -> Dict[str, Any]:
339+
if validation and self.do_validation:
340340
self._validate_props()
341341
self.validate()
342342

@@ -351,9 +351,13 @@ def to_dict(self) -> Dict[str, Any]:
351351
else:
352352
return {}
353353

354-
def to_json(self, *, indent: int = 4, sort_keys: bool = True) -> str:
354+
def to_json(
355+
self, *, indent: int = 4, sort_keys: bool = True, validation: bool = True
356+
) -> str:
355357
"""Object as JSON."""
356-
return json.dumps(self.to_dict(), indent=indent, sort_keys=sort_keys)
358+
return json.dumps(
359+
self.to_dict(validation=validation), indent=indent, sort_keys=sort_keys
360+
)
357361

358362
@classmethod
359363
def _from_dict(
@@ -417,7 +421,9 @@ def _validate_props(self) -> None:
417421

418422
def __eq__(self, other: object) -> bool:
419423
if isinstance(other, self.__class__):
420-
return self.title == other.title and self.to_json() == other.to_json()
424+
return self.title == other.title and self.to_json(
425+
validation=False
426+
) == other.to_json(validation=False)
421427
if isinstance(other, dict):
422428
return {"title": self.title, **self.to_dict()} == other
423429
return NotImplemented
@@ -1109,3 +1115,6 @@ def check_type(t: type, v: Any) -> bool:
11091115
"%s can only be used with parameters of "
11101116
"the CommaDelimitedList type." % p
11111117
)
1118+
1119+
def __hash__(self) -> int:
1120+
return hash(json.dumps({"title": self.title, **self.to_dict()}, indent=0))

0 commit comments

Comments
 (0)