SteveJ
SteveJ

Reputation: 3313

How to set type hint on field when dynamically creating a class

For reasons beyond the scope of this question, I'd like to create a dynamic Python-Pydantic class. I'm close, but am not aware of how to add the type hint.

Given:

class MyClass(BaseModel):

    class Config:
        extra = Extra.allow

        schema_extra = {
            '$id': "http://my-site.com/production.json",
            '$schema': "https://json-schema.org/draft/2020-12/schema",
            'title': 'pattern="^.+-.*"'
        }


if __name__ == '__main__':

    cls = type('A', (MyClass,), {'__doc__': 'class created by type', 'my_field': Field("test", type='int')})
    p = cls()
    schema = p.schema()
    pprint(schema)

I get this:

{'$id': 'http://my-site.com/production.json',
 '$schema': 'https://json-schema.org/draft/2020-12/schema',
 'description': 'class created by type',
 'properties': {'my_field': {'default': 'test',
                             'title': 'My Field',
                             'type': 'string'}},
 'title': 'pattern="^.+-.*"',
 'type': 'object'}

I would like "properties -> myfield -> type" to be an int instead of string.

Upvotes: 4

Views: 3753

Answers (1)

Wizard.Ritvik
Wizard.Ritvik

Reputation: 11621

Create an __annotations__ dict object and add your type definitions there. This is the same mapping that gets translated when you define it like my_field: int = Field('test').

Note: in below, I only show the parts of the code that were added / modified.

    cls_annotations = {'my_field': int} ## Added

    cls = type('A', (MyClass,), {'__doc__': 'class created by type',
                                 ## Added
                                 '__annotations__': cls_annotations,
                                 ##
                                 'my_field': Field("test")})

Output:

...
 'properties': {'my_field': {'default': 'test',
                             'title': 'My Field',
                             'type': 'integer'}},
...

Upvotes: 7

Related Questions