pythonpython-typingtypeddict

How do I type hint a function using TypedDict that mutates a dictionary in Python?


I am defining a function that takes a dictionary as an input, and does some operations on it that creates a new key/value pair and modifies one existing value's type.

I have a TypedDict for both the input and output of the function:

from typing import TypedDict

class MyDict(TypedDict):
    field_1: int
    field_2: str
    field_3: float

class InputDict(MyDict):
    field_4: str

class OutputDict(MyDict):
    field_4: bytes
    field_5: bytes

def transform_dict(input: list[InputDict]) -> list[OutputDict]:
    output = input.copy()
    for x in output:
        x["field_4"] = x["field_4"].encode()
        x["field_5"] = "some_stuff".encode()
    return output

My linter is complaining about the lines where I do the transformation of field_4 and field_5, which makes sense because output is a copy of a type list[InputDict]. What is the best / type-safe way to do this? I understand why it's complaining but I'm can't figure out how to fix it.


Solution

  • Actually, this is kind of unsafe. You are mutating the input dictionaries because list.copy is a shallow copy. This will be unexpected for a caller as their InputDict elements will suddenly become OutputDict.

    Your best and safest bet will be to make new objects:

    output: list[OutputDict] = []
    for x in input:
        output.append({
            **x,
            "field_4": x["field_4"].encode(),
            ...
        })
    return output
    

    or more concisely as a comprehension:

    return [{**x, "field_4": x["field_4"].encode(), ...} for x in input]