Type annotation for dict arguments

Viewed 6119

Can I indicate a specific dictionary shape/form for an argument to a function in python?

Like in typescript I'd indicate that the info argument should be an object with a string name and a number age:

function parseInfo(info: {name: string, age: number}) { /* ... */ }

Is there a way to do this with a python function that's otherwise:

def parseInfo(info: dict):
  # function body

Or is that perhaps not Pythonic and I should use named keywords or something like that?

2 Answers

In Python 3.8+ you could use the alternative syntax to create a TypedDict:

from typing import TypedDict

Info = TypedDict('Info', {'name': str, 'age': int})


def parse_info(info: Info):
    pass

From the documentation on TypedDict:

TypedDict declares a dictionary type that expects all of its instances to have a certain set of keys, where each key is associated with a value of a consistent type. This expectation is not checked at runtime but is only enforced by type checkers.

Perhaps you could do the following:

def assertTypes(obj, type_obj):
    for t in type_obj:
        if not(t in obj and type(obj[t]) == type_obj[t]):
            return False
    return True

def parseInfo(info):
    if not assertTypes(info, {"name": str, "age": int}):
        print("INVALID OBJECT FORMAT")
        return
    #continue

>>> parseInfo({"name": "AJ", "age": 8})
>>> parseInfo({"name": "AJ", "age": 'hi'})
INVALID OBJECT FORMAT
>>> parseInfo({"name": "AJ"})
INVALID OBJECT FORMAT
>>> parseInfo({"name": 1, "age": 100})
INVALID OBJECT FORMAT
>>> parseInfo({"name": "Donald", "age": 100})
>>> 
Related