PEP 764: Inlined typed dictionaries

Working on one of my projects today, I encountered this TypedDict:

class PrivateBinAPIJSON(TypedDict):
    paste: str
    attachment: NotRequired[str | list[str]]
    attachment_name: NotRequired[str | list[str]]

This is actually wrong. the PrivateBin API accepts and returns 3 possible combinations:

  1. A paste with no attachments
  2. A paste with a single attachment
  3. A paste with multiple attachements

This can be correctly typed by PEP 764:

type PrivateBinAPIJSON = (
    TypedDict[{"paste": str}]
    | TypedDict[{"paste": str, "attachment": str, "attachment_name": str}]
    | TypedDict[{"paste": str, "attachment": list[str], "attachment_name": list[str]}]
)

I can achieve this today with 3 TypedDicts but that’s simply too verbose too bother with.

3 Likes

Couldn’t you pack attachment and attachment_name into a tuple of two elements (str, str), then do something like this?

type AttachmentData = tuple[str, str]
# Or another TypedDict for AttachmentData

class PrivateBinAPIJSON(TypedDict):
    paste: str
    attachment_data: tuple[AttachmentData, ...]

It would also stop usage of the class with say 3 attachments but 5 attachment-names. Maybe even a dictionary for name to attachment would work (unless names can be repeated).

I think for this case, and probably many others, a bit of redesigning can be helpful.

I don’t think it’s fair to assume that people have the ability to redesign external JSON APIs (which seems like what’s being used here) just for the sake of simplifying typing them in Python.

3 Likes

I don’t control the PrivateBin API. It only accepts and returns one of those 3 shapes.

1 Like