python dataclasses with optional attributes

from dataclasses import dataclass

@dataclass
class CampingEquipment:
    knife: bool
    fork: bool
    missing_flask_size: ? # removed field() per answers below.
    
kennys_stuff = {
    'knife':True,
    'fork': True
}

print(CampingEquipment(**kennys_stuff))

gives me:

TypeError: CampingEquipment.__init__() missing 1 required positional argument: 'missing_flask_size'

How do you make Optional attr's of a dataclass?

Edit

What I meant by optional wasn't clear. By Optional I mean __dict__ may contain the key "missing_flask_size" or not. If I set a default value then the key will be there and it shouldn't be in some cases. I want to check it's type if it is there. I tried moving the field(init=False) to the type location (after the colon) so I could make it more explicit as to the thing I wanted optional would be the key and not the value. That was just confusing for everyone, including me, so it's removed.

So I want this test to pass:

with pytest.raises(AttributeError):
    ce = CampingEquipment(**kennys_stuff)
    print(ce.missing_flask_size)

Solution 1:

A field object is supposed to be used with =, like a default value, not : like an annotation.

Specifying init=False for a field means the caller can't pass in a value for it at all. init=False fields are supposed to be set in __post_init__, like this:

@dataclass
class Example:
    a: int
    b: int
    c: int = field(init=False)

    def __post_init__(self):
        self.c = self.a + self.b

print(Example(1, 2).c) # prints 3

If you want to make it optional for the caller to provide a value, you can set a default value. If the caller doesn't provide a value, the default will be used instead:

@dataclass
class Example:
    a: int
    b: int
    c: int = -1

print(Example(1, 2).c) # prints -1
print(Example(1, 2, 3).c) # prints 3