0

So I'm investigating how to Type large JSON objects I get back from devices. I found the TypedDict type in Python 3.8 and think it's pretty cool.

But then I started going down the rabbit hole of nested dictionaries and wasn't sure if there was a better way.

Question: Is there a way to define nested typed Dicts using the class notation?

I have the following dictionary

object = {
    'name': 'My Name',
    'somekey': {
        'subkey1': 1,
        'subkey2': {
            'subsubkey1': 2,
            'subsubkey2': 'nested'
        }
    }
}

I import the following library from typing import TypedDict

Using the assignment annotation I was able to come up with this but it's ugly and hard to read.

MyObjAssignmentNotation = TypedDict('Obj', {'name': str, 'somekey': TypedDict('SubObj_1', {'subkey1': int, 'subkey2': TypedDict(
    'SubObj_2', {'subsubkey1': int, 'subsubkey2': str})})}

Using the class notation I came up with this, but the types are all separated and it's not easy to read what the combined type should be since you have to read from the bottom up.

class SubObj_Layer2(TypedDict):
    subsubkey1: int
    subsubkey2: str


class SubObj_Layer1(TypedDict):
    subkey1: int
    subkey2: SubObj_Layer2


class MyObjClassNotation(TypedDict):
    name: str
    somekey: SubObj_Layer1

Then i got a bit creative and put the two together and it's a little better, but not much.

class MyObjClassAndAssignmentNotation(TypedDict):
    name: str
    somekey: TypedDict('SubObj_1', {'subkey1': int, 'subkey2': TypedDict(
        'SubObj_2', {'subsubkey1': int, 'subsubkey2': str})})

Any suggestions on improving the above syntax?

Joe Jacobs
  • 291
  • 3
  • 9
  • Does this answer your question? [What are data classes and how are they different from common classes?](https://stackoverflow.com/questions/47955263/what-are-data-classes-and-how-are-they-different-from-common-classes) – mkrieger1 May 29 '20 at 19:16
  • Also https://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python – mkrieger1 May 29 '20 at 19:16
  • No, not really. Data classes are for storing data. The Types are for defining type annotations so static checkers like PyRight in VS code can tell you when your dictionary or other objects don't match. Recently used Typescript and was impressed with the ability to create nested types and was trying to define that here. I'm not looking to make a class or instance of a class, but rather create nested type definitions – Joe Jacobs May 29 '20 at 21:10
  • In typescript i would have defined my type as follows... ```export interface MyObject { name: string; somekey: { subkey1: number; subkey2: { subsubkey1: number; subsubkey2: string; }; }; } ``` Was trying to see if I could do something similar in Python. Should I rephrase my question with this example included? – Joe Jacobs May 29 '20 at 21:15
  • FYI, if you're using the class-based notation you can define your classes in any order you'd like so long as you make sure to use either forward references or Python 3.7+ with `from __future__ import annotations`. Either approach will ensure your type hints are not evaluated at runtime. – Michael0x2a May 30 '20 at 02:42
  • But in any case, IMO this question shouldn't have been closed as "opinion-based" because there's a definitive answer to this question: no, there is not a PEP 484 and PEP 589 compliant way of defining a nested typed dict using a single type declaration an the only option is to provide multiple TypedDict definitions. This includes the assignment expression example in the second code snippet: that expression doesn't actually constitutes a valid type. – Michael0x2a May 30 '20 at 02:55
  • That said, it's possible TypedDicts could be enhanced to support this if somebody were willing to design and champion a suitable enhancement. If this is something you're interested in pursuing, you could maybe try starting a discussion in the typing-sig mailing list. – Michael0x2a May 30 '20 at 02:56
  • It'll work for you: https://pypi.org/project/validated-dc/ – Evgeniy_Burdin Jul 13 '20 at 08:09

0 Answers0