hi everyone, how do you properly type this go stru...
# getting-started
b
hi everyone, how do you properly type this go struct in python?
Copy code
type Team struct {
  Name         string `yaml:"name"`
  Description  string `yaml:"description"`
  Slug         string   `yaml:"slug"`
  ParentTeamId int
  Teams        []Team   `yaml:"teams"`
}
here is what i have:
Copy code
@dataclass
class Team:
    name: str
    slug: str
    description: str
    ...
    subteams: Optional[list[Team]] 
    parent_team_id: Optional[int] = None
the team data is read from a yaml file here are several issues: 1. in order to use
.
refence , you have to do
Team(**team)
to create the object, where
team
is a python dict read from YAML. however, this will be flagged by type checker:
Arguments missing for parameters "name", "slug", "description
2. there is a nested field
subteams
, when reading from yaml, it's not automatically deserialized, so you have to create the object again
Team(**sub_team)
to use
.
reference 3. since not every team entry has
subteam
field, you have to assign empty list as default value. but when you iterate over the entries in yaml, you will have type error
Object of type "None" cannot be used as iterable value
when you do
parent_team.subteams
cc: @shy-arm-32391 thanks for you blog post, this is really helpful! i am implementing something similar in python and having these typing issues, not sure if you have any idea on this?
p
I think you might be interested in pydantic (https://pydantic-docs.helpmanual.io)
๐Ÿ™Œ 1
๐Ÿ‘ 1
I use it in most of my python project, including pulumi.
Copy code
class Team(BaseModel):
  name: str
  slug: str
  description: str
  parent_team_id: Optional[int]
  subteams: Optional[List["Team"]]

team = Team.parse_obj(your_python_dict)
+ small suggestion (ofc that depends on your usecase), sometimes itโ€™s easier to deal with empty list instead of optional lists:
Copy code
subteams: List["Team"] = []
vs
Copy code
subteams: Optional[List["Team"]]
Ensure that you really want to have an optional here ๐Ÿ™‚.
+ think about joining #python channel on this Slack
b
Just curious. From OP post there is nothing about Pulumi itself and even Python code does not look like resources in Pulumi. Why the question is here?
p
hah, youโ€™re right ๐Ÿ˜„
I assumed OP wanted to read some structured stack config and needed to find a robust solution in python. At least, thatโ€™s where I use pydantic in my pulumi projects.
๐Ÿ™Œ 1
b
thanks very much!
pydantic
solved my problem nicely!!๐Ÿ‘
yeah, using empty list makes things easier but dataclass has limitation that you can't assign an mutable empty list to a field. but now i don't worry about it since i switch to use pydantic
hi `sergei`: one key benefit of pulumi is to have proper typing and ide prompt. something that's easy in golang or typescript, may need some extra research/work in python. asking here since i was wondering how other folks workaround in their pulumi project. #python is definitely a good place to ask!
p
@bored-monitor-99026 technically, you can assign empty list to a dataclass field, itโ€™s just not that straightforward (because itโ€™s mutable as you said):
Copy code
@dataclass
class Team:
    subteams: List["Team"] = field(default_factory=lambda: [])
    ...
๐Ÿ‘ 1
Iโ€™m glad pydantic did the job for you!
๐Ÿ™ 1
๐Ÿ™Œ 1
s
hi friends - just got back from holiday and I'm so glad you all found something that works! ๐ŸŽ‰
๐Ÿ™Œ 1