Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: unhashable type: 'SecurityGroup' #2204

Closed
bogdankatishev opened this issue Nov 9, 2023 · 3 comments
Closed

TypeError: unhashable type: 'SecurityGroup' #2204

bogdankatishev opened this issue Nov 9, 2023 · 3 comments

Comments

@bogdankatishev
Copy link

Hello, maybe also slightly related to #2196, since upgrading from 4.4.x to 4.5.0/4.5.1, we are receiving this compile error:

TypeError: unhashable type: 'SecurityGroup'

Minimal code to reproduce:

from troposphere.ec2 import SecurityGroup

test_sg = SecurityGroup(
    "TestSg",
    VpcId="myVPC",
    GroupDescription="Test Security Group",
)

{ test_sg }

We also have been relying multiple years on the SecurityGroup as keys to dict.

What to do now?

@markpeek
Copy link
Member

markpeek commented Nov 9, 2023

Try this patch that moves the __hash__ function to BaseAWSObject:

$ git diff
diff --git a/tests/test_basic.py b/tests/test_basic.py
index f5714b1..7a03842 100644
--- a/tests/test_basic.py
+++ b/tests/test_basic.py
@@ -122,6 +122,17 @@ class TestBasic(unittest.TestCase):
         assert Parameter("param1") != Parameter("param2")
         assert Stack("stack1") != Stack("stack2")

+    def test___hash__(self):
+        """Test __hash__."""
+        from troposphere.ec2 import SecurityGroup
+
+        test_sg = SecurityGroup(
+            "TestSg",
+            VpcId="myVPC",
+            GroupDescription="Test Security Group",
+        )
+        _ = hash(test_sg)
+
     def test_badproperty(self):
         with self.assertRaises(AttributeError):
             Instance(
diff --git a/troposphere/__init__.py b/troposphere/__init__.py
index 1f214e2..da86b49 100644
--- a/troposphere/__init__.py
+++ b/troposphere/__init__.py
@@ -431,6 +431,9 @@ class BaseAWSObject:
     def __ne__(self, other: object) -> bool:
         return not self == other

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

 class AWSObject(BaseAWSObject):
     dictname = "Properties"
@@ -1115,6 +1118,3 @@ class Parameter(AWSDeclaration):
                         "%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))
$ cat sghash.py
from troposphere.ec2 import SecurityGroup

test_sg = SecurityGroup(
    "TestSg",
    VpcId="myVPC",
    GroupDescription="Test Security Group",
)

{ test_sg }
$ python sghash.py
$

@zipkid
Copy link

zipkid commented Nov 10, 2023

@markpeek I have used your diff and for me it seems to work.
I have tested the minimal code & 24 random scripts from our repo and they all build without error.

@markpeek
Copy link
Member

Fix is in Release 4.5.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants