Skip to content

Commit

Permalink
Object equality fixes
Browse files Browse the repository at this point in the history
- Add __hash__ to the Parameter class
- Disable validation when doing BaseAWSObject object comparison __eq__
  • Loading branch information
markpeek committed Oct 26, 2023
1 parent 55599ec commit b72637c
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
5 changes: 5 additions & 0 deletions tests/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
cloudformation,
depends_on_helper,
)
from troposphere.cloudformation import Stack
from troposphere.ec2 import Instance, NetworkInterface, Route, SecurityGroupRule
from troposphere.elasticloadbalancing import HealthCheck
from troposphere.s3 import Bucket, PublicRead
Expand Down Expand Up @@ -117,6 +118,10 @@ def test___ne__(self):
assert GenericHelperFn("foobar") != TypeComparator(AWSObject)
assert TypeComparator(AWSObject) != GenericHelperFn("foobar")

# Testing __ne__ for objects missing required properties
assert Parameter("param1") != Parameter("param2")
assert Stack("stack1") != Stack("stack2")

def test_badproperty(self):
with self.assertRaises(AttributeError):
Instance(
Expand Down
19 changes: 14 additions & 5 deletions troposphere/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,8 @@ def no_validation(self: __BaseAWSObjectTypeVar) -> __BaseAWSObjectTypeVar:
self.do_validation = False
return self

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

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

def to_json(self, *, indent: int = 4, sort_keys: bool = True) -> str:
def to_json(
self, *, indent: int = 4, sort_keys: bool = True, validation: bool = True
) -> str:
"""Object as JSON."""
return json.dumps(self.to_dict(), indent=indent, sort_keys=sort_keys)
return json.dumps(
self.to_dict(validation=validation), indent=indent, sort_keys=sort_keys
)

@classmethod
def _from_dict(
Expand Down Expand Up @@ -417,7 +421,9 @@ def _validate_props(self) -> None:

def __eq__(self, other: object) -> bool:
if isinstance(other, self.__class__):
return self.title == other.title and self.to_json() == other.to_json()
return self.title == other.title and self.to_json(
validation=False
) == other.to_json(validation=False)
if isinstance(other, dict):
return {"title": self.title, **self.to_dict()} == other
return NotImplemented
Expand Down Expand Up @@ -1109,3 +1115,6 @@ def check_type(t: type, v: Any) -> bool:
"%s can only be used with parameters of "
"the CommaDelimitedList type." % p
)

def __hash__(self) -> int:
return hash(json.dumps({"title": self.title, **self.to_dict()}, indent=0))

0 comments on commit b72637c

Please sign in to comment.