From 02a2a8b5c010e23fd4c85af44c3cec515b44a94e Mon Sep 17 00:00:00 2001 From: chenyijian <742699506@qq.com> Date: Thu, 11 Aug 2022 18:34:24 +0800 Subject: [PATCH] create_model support generics model (#3946) * create_model support generics model * fix change. Co-authored-by: chenyijian Co-authored-by: Samuel Colvin --- changes/3945-hot123s.md | 1 + pydantic/main.py | 10 +++++++--- tests/test_create_model.py | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 changes/3945-hot123s.md diff --git a/changes/3945-hot123s.md b/changes/3945-hot123s.md new file mode 100644 index 0000000..6405d0a --- /dev/null +++ b/changes/3945-hot123s.md @@ -0,0 +1 @@ +Support generics model with `create_model` \ No newline at end of file diff --git a/pydantic/main.py b/pydantic/main.py index 3228e83..5ce2674 100644 --- a/pydantic/main.py +++ b/pydantic/main.py @@ -4,7 +4,7 @@ from copy import deepcopy from enum import Enum from functools import partial from pathlib import Path -from types import FunctionType +from types import FunctionType, prepare_class, resolve_bases from typing import ( TYPE_CHECKING, AbstractSet, @@ -996,8 +996,12 @@ def create_model( namespace.update(fields) if __config__: namespace['Config'] = inherit_config(__config__, BaseConfig) - - return type(__model_name, __base__, namespace, **__cls_kwargs__) + resolved_bases = resolve_bases(__base__) + meta, ns, kwds = prepare_class(__model_name, resolved_bases, kwds=__cls_kwargs__) + if resolved_bases is not __base__: + ns['__orig_bases__'] = __base__ + namespace.update(ns) + return meta(__model_name, resolved_bases, namespace, **kwds) _missing = object() diff --git a/tests/test_create_model.py b/tests/test_create_model.py index 0cf2641..9a17c5d 100644 --- a/tests/test_create_model.py +++ b/tests/test_create_model.py @@ -1,6 +1,9 @@ +from typing import Generic, TypeVar + import pytest from pydantic import BaseModel, Extra, Field, ValidationError, create_model, errors, validator +from pydantic.generics import GenericModel def test_create_model(): @@ -205,3 +208,17 @@ def test_config_field_info_create_model(): m2 = create_model('M2', __config__=Config, a=(str, Field(...))) assert m2.schema()['properties'] == {'a': {'title': 'A', 'description': 'descr', 'type': 'string'}} + + +def test_generics_model(): + T = TypeVar('T') + + class TestGenericModel(GenericModel): + pass + + AAModel = create_model( + 'AAModel', __base__=(TestGenericModel, Generic[T]), __cls_kwargs__={'orm_mode': True}, aa=(int, Field(0)) + ) + result = AAModel[int](aa=1) + assert result.aa == 1 + assert result.__config__.orm_mode is True