|
1 | 1 | import re
|
2 | 2 | from enum import Enum, auto
|
3 |
| -from typing import Annotated, Any, Literal, Union |
| 3 | +from typing import Annotated, Any, ClassVar, Literal, Union, get_origin |
4 | 4 |
|
5 | 5 | import pytest
|
6 | 6 | from pydantic import BaseModel, Field, StringConstraints, ValidationError, computed_field, conint, constr
|
@@ -807,3 +807,81 @@ def image_url(self) -> str:
|
807 | 807 |
|
808 | 808 | assert not hasattr(old_instance, "image_url")
|
809 | 809 | assert "image_url" not in old_instance.model_dump()
|
| 810 | + |
| 811 | + |
| 812 | +def test__schema_with_classvar__should_be_recreated_in_older_version(create_runtime_schemas: CreateRuntimeSchemas): |
| 813 | + class SchemaWithClassVar(BaseModel): |
| 814 | + regular_field: str |
| 815 | + class_level_config: ClassVar[str] = "default_config" |
| 816 | + |
| 817 | + schemas = create_runtime_schemas(version_change()) |
| 818 | + |
| 819 | + latest_model = schemas["2001-01-01"][SchemaWithClassVar] |
| 820 | + old_model = schemas["2000-01-01"][SchemaWithClassVar] |
| 821 | + |
| 822 | + latest_instance = latest_model(regular_field="test") |
| 823 | + old_instance = old_model(regular_field="test") |
| 824 | + |
| 825 | + assert latest_model.class_level_config == "default_config" |
| 826 | + assert old_model.class_level_config == "default_config" |
| 827 | + |
| 828 | + assert "class_level_config" not in latest_instance.model_dump() |
| 829 | + assert "class_level_config" not in old_instance.model_dump() |
| 830 | + |
| 831 | + assert latest_instance.regular_field == "test" |
| 832 | + assert old_instance.regular_field == "test" |
| 833 | + |
| 834 | + assert "class_level_config" in latest_model.__annotations__ |
| 835 | + assert "class_level_config" in old_model.__annotations__ |
| 836 | + |
| 837 | + assert get_origin(latest_model.__annotations__["class_level_config"]) is ClassVar |
| 838 | + assert get_origin(old_model.__annotations__["class_level_config"]) is ClassVar |
| 839 | + |
| 840 | + |
| 841 | +def test__schema_with_classvar__remove_classvar(create_runtime_schemas: CreateRuntimeSchemas): |
| 842 | + class SchemaWithClassVar(BaseModel): |
| 843 | + regular_field: str |
| 844 | + class_level_config: ClassVar[str] = "default_config" |
| 845 | + |
| 846 | + schemas = create_runtime_schemas(version_change(schema(SchemaWithClassVar).field("class_level_config").didnt_exist)) |
| 847 | + |
| 848 | + latest_model = schemas["2001-01-01"][SchemaWithClassVar] |
| 849 | + latest_instance = latest_model(regular_field="test") |
| 850 | + |
| 851 | + assert latest_model.class_level_config == "default_config" |
| 852 | + assert "class_level_config" not in latest_instance.model_dump() |
| 853 | + |
| 854 | + old_model = schemas["2000-01-01"][SchemaWithClassVar] |
| 855 | + old_instance = old_model(regular_field="test") |
| 856 | + |
| 857 | + assert not hasattr(old_model, "class_level_config") |
| 858 | + assert "class_level_config" not in old_instance.model_dump() |
| 859 | + |
| 860 | + assert latest_instance.regular_field == "test" |
| 861 | + assert old_instance.regular_field == "test" |
| 862 | + |
| 863 | + |
| 864 | +def test__schema_with_classvar__add_classvar_field(create_runtime_schemas: CreateRuntimeSchemas): |
| 865 | + class SchemaWithoutClassVar(BaseModel): |
| 866 | + regular_field: str |
| 867 | + |
| 868 | + schemas = create_runtime_schemas( |
| 869 | + version_change(), |
| 870 | + version_change( |
| 871 | + schema(SchemaWithoutClassVar) |
| 872 | + .field("new_config") |
| 873 | + .existed_as(type=ClassVar[str], info=Field(default="added_config")), |
| 874 | + schema(SchemaWithoutClassVar).field("new_config_without_value").existed_as(type=ClassVar[str]), |
| 875 | + ), |
| 876 | + ) |
| 877 | + latest_model = schemas["2002-01-01"][SchemaWithoutClassVar] |
| 878 | + mid_model = schemas["2001-01-01"][SchemaWithoutClassVar] |
| 879 | + old_model = schemas["2000-01-01"][SchemaWithoutClassVar] |
| 880 | + |
| 881 | + assert not hasattr(latest_model, "new_config") |
| 882 | + assert mid_model.new_config == "added_config" |
| 883 | + assert old_model.new_config == "added_config" |
| 884 | + |
| 885 | + assert not hasattr(latest_model, "new_config_without_value") |
| 886 | + assert not hasattr(mid_model, "new_config_without_value") |
| 887 | + assert not hasattr(old_model, "new_config_without_value") |
0 commit comments