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.
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]