Python defaultdict works not as expected [duplicate]

Please explain and maybe help how to fix defaultdict with a frozen dataclass key.

Example:

"""Reproduce KeyError: defaultdict with dataclass keys"""

import collections
import dataclasses
import unittest


@dataclasses.dataclass(frozen=True)
class ReservationCoverageKey:
    """AWS RDS Reservation dimensions"""

    database_engine: str
    instance_family: str
    region: str


class TestCase(unittest.TestCase):
    """Main test cases"""

    def test_dict_with_dataclass_keys(self):
        """Test normal dict with dataclass key"""
        result = {}
        key = ReservationCoverageKey(
            database_engine="PostgreSQL",
            instance_family="db.t3",
            region="eu-west-1",
        )
        result[key] = 0
        result[key] += 1
        result[key] += 2
        self.assertEqual(result[key], 3)

    def test_defaultdict_with_dataclass_keys(self):
        """Test defaultdict with dataclass key"""
        result = collections.defaultdict(default_factory=int)
        key = ReservationCoverageKey(
            database_engine="PostgreSQL",
            instance_family="db.t3",
            region="eu-west-1",
        )
        result[key] += 1
        result[key] += 2
        self.assertEqual(result[key], 3)


if __name__ == "__main__":
    unittest.main()

Reproduce:

$ python3 defaultdict_keyerror_reproduce.py 
E.
======================================================================
ERROR: test_defaultdict_with_dataclass_keys (__main__.TestCase)
Test defaultdict with dataclass key
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/var/tmp/sscce/defaultdict_keyerror_reproduce.py", line 41, in test_defaultdict_with_dataclass_keys
    result[key] += 1
KeyError: ReservationCoverageKey(database_engine='PostgreSQL', instance_family='db.t3', region='eu-west-1')

----------------------------------------------------------------------
Ran 2 tests in 0.000s

FAILED (errors=1)

The testcase with dict works, but not with the defaultdict.


collections.defaultdict(default_factory=int) creates a default dict with no default value type, and one value (the type int at the key "default_factory") because default_factory can only be passed as positional argument. Any keyword arguments are considered key-value pairs for the dictionary:

defaultdict(None, {'default_factory': int})

You need to do collections.defaultdict(int), which produces defaultdict(int, {})