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