fix init_subclass for pydantic v2, add some missing type hints, format black
This commit is contained in:
parent
80f02753ba
commit
37c360e786
@ -283,7 +283,11 @@ class Component(BaseComponent, ABC):
|
||||
continue
|
||||
|
||||
# unwrap Optional from field_type
|
||||
field_type = typing.get_args(field_type)[0] if types.is_optional(field_type) else field_type
|
||||
field_type = (
|
||||
typing.get_args(field_type)[0]
|
||||
if types.is_optional(field_type)
|
||||
else field_type
|
||||
)
|
||||
|
||||
# Check whether the key is a component prop.
|
||||
if types._issubclass(field_type, Var):
|
||||
|
@ -100,13 +100,9 @@ class RadixThemesComponent(Component):
|
||||
"""
|
||||
component = super().create(*children, **props)
|
||||
if component.library is None:
|
||||
<<<<<<< HEAD
|
||||
component.library = RadixThemesComponent.model_fields["library"].default
|
||||
=======
|
||||
component.library = RadixThemesComponent.model_fields[
|
||||
"library"
|
||||
].default
|
||||
>>>>>>> f7035d9b (optionalize some Component props)
|
||||
component.alias = "RadixThemes" + (
|
||||
component.tag or component.__class__.__name__
|
||||
)
|
||||
|
@ -113,7 +113,9 @@ class DropdownMenuContent(RadixThemesComponent):
|
||||
avoid_collisions: Optional[Var[bool]] = None
|
||||
|
||||
# The distance in pixels from the boundary edges where collision detection should occur. Accepts a number (same for all sides), or a partial padding object, for example: { "top": 20, "left": 20 }. Defaults to 0.
|
||||
collision_padding: Optional[Var[Union[float, int, Dict[str, Union[float, int]]]]] = None
|
||||
collision_padding: Optional[
|
||||
Var[Union[float, int, Dict[str, Union[float, int]]]]
|
||||
] = None
|
||||
|
||||
# The padding between the arrow and the edges of the content. If your content has border-radius, this will prevent it from overflowing the corners. Defaults to 0.
|
||||
arrow_padding: Optional[Var[Union[float, int]]] = None
|
||||
@ -204,7 +206,9 @@ class DropdownMenuSubContent(RadixThemesComponent):
|
||||
avoid_collisions: Optional[Var[bool]] = None
|
||||
|
||||
# The distance in pixels from the boundary edges where collision detection should occur. Accepts a number (same for all sides), or a partial padding object, for example: { "top": 20, "left": 20 }. Defaults to 0.
|
||||
collision_padding: Optional[Var[Union[float, int, Dict[str, Union[float, int]]]]] = None
|
||||
collision_padding: Optional[
|
||||
Var[Union[float, int, Dict[str, Union[float, int]]]]
|
||||
] = None
|
||||
|
||||
# The padding between the arrow and the edges of the content. If your content has border-radius, this will prevent it from overflowing the corners. Defaults to 0.
|
||||
arrow_padding: Optional[Var[Union[float, int]]] = None
|
||||
|
@ -60,7 +60,9 @@ class Tooltip(RadixThemesComponent):
|
||||
avoid_collisions: Optional[Var[bool]] = None
|
||||
|
||||
# The distance in pixels from the boundary edges where collision detection should occur. Accepts a number (same for all sides), or a partial padding object, for example: { "top": 20, "left": 20 }. Defaults to 0.
|
||||
collision_padding: Optional[Var[Union[float, int, Dict[str, Union[float, int]]]]] = None
|
||||
collision_padding: Optional[
|
||||
Var[Union[float, int, Dict[str, Union[float, int]]]]
|
||||
] = None
|
||||
|
||||
# The padding between the arrow and the edges of the content. If your content has border-radius, this will prevent it from overflowing the corners. Defaults to 0.
|
||||
arrow_padding: Optional[Var[Union[float, int]]] = None
|
||||
|
@ -195,7 +195,7 @@ def _split_substate_key(substate_key: str) -> tuple[str, str]:
|
||||
return token, state_name
|
||||
|
||||
|
||||
class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
class BaseState(Base, ABC, extra="allow"):
|
||||
"""The state of the app."""
|
||||
|
||||
# A map from the var name to the var.
|
||||
@ -288,7 +288,11 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
kwargs["parent_state"] = parent_state
|
||||
|
||||
for prop_name, prop in self.base_vars.items():
|
||||
if prop_name not in kwargs and self.model_fields[prop_name].is_required():
|
||||
if (
|
||||
prop_name not in kwargs
|
||||
and prop_name in self.model_fields
|
||||
and self.model_fields[prop_name].is_required()
|
||||
):
|
||||
kwargs[prop_name] = prop.get_default_value()
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
@ -362,7 +366,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
def __pydantic_init_subclass__(cls, **kwargs: Any) -> None:
|
||||
"""Do some magic for the subclass initialization.
|
||||
|
||||
Args:
|
||||
@ -371,7 +375,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
Raises:
|
||||
ValueError: If a substate class shadows another.
|
||||
"""
|
||||
super().__init_subclass__(**kwargs)
|
||||
# super().__init_subclass__(**kwargs)
|
||||
# Event handlers should not shadow builtin state methods.
|
||||
cls._check_overridden_methods()
|
||||
|
||||
@ -486,6 +490,12 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
cls.event_handlers[name] = handler
|
||||
setattr(cls, name, handler)
|
||||
|
||||
# Inherited vars are handled in __getattribute__, not by pydantic
|
||||
for prop in cls.model_fields.copy():
|
||||
if prop in cls.inherited_vars or prop in cls.inherited_backend_vars:
|
||||
del cls.model_fields[prop]
|
||||
cls.model_rebuild(force=True)
|
||||
|
||||
cls._init_var_dependency_dicts()
|
||||
|
||||
@staticmethod
|
||||
@ -994,9 +1004,6 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
# If the state hasn't been initialized yet, return the default value.
|
||||
if not super().__getattribute__("__dict__"):
|
||||
return super().__getattribute__(name)
|
||||
private_attrs = super().__getattribute__("__pydantic_private__")
|
||||
if private_attrs is None:
|
||||
return super().__getattribute__(name)
|
||||
|
||||
inherited_vars = {
|
||||
**super().__getattribute__("inherited_vars"),
|
||||
@ -1009,6 +1016,9 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
if parent_state is not None:
|
||||
return getattr(parent_state, name)
|
||||
|
||||
private_attrs = super().__getattribute__("__pydantic_private__")
|
||||
if private_attrs is None:
|
||||
return super().__getattribute__(name)
|
||||
backend_vars = private_attrs["_backend_vars"]
|
||||
if name in backend_vars:
|
||||
value = backend_vars[name]
|
||||
@ -1088,7 +1098,9 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
# on the browser also resets the values on the backend.
|
||||
fields = self.get_fields()
|
||||
for prop_name in self.base_vars:
|
||||
field = fields[prop_name]
|
||||
if not (field := fields.get(prop_name)):
|
||||
# inherited values are reset in the parent state
|
||||
continue
|
||||
if isinstance(field.default, ClientStorageBase) or (
|
||||
isinstance(field.annotation, type)
|
||||
and issubclass(field.annotation, ClientStorageBase)
|
||||
|
@ -37,7 +37,7 @@ class DictMutationTestState(BaseState):
|
||||
self.details.pop("age")
|
||||
|
||||
# dict in list
|
||||
address: List[Dict[str,str]] = [{"home": "home address"}, {"work": "work address"}]
|
||||
address: List[Dict[str, str]] = [{"home": "home address"}, {"work": "work address"}]
|
||||
|
||||
def remove_home_address(self):
|
||||
"""Remove the home address from dict in the list."""
|
||||
@ -48,7 +48,10 @@ class DictMutationTestState(BaseState):
|
||||
self.address[0]["street"] = "street address"
|
||||
|
||||
# nested dict
|
||||
friend_in_nested_dict: Dict[str, Union[str, Dict[str,str]]] = {"name": "Nikhil", "friend": {"name": "Alek"}}
|
||||
friend_in_nested_dict: Dict[str, Union[str, Dict[str, str]]] = {
|
||||
"name": "Nikhil",
|
||||
"friend": {"name": "Alek"},
|
||||
}
|
||||
|
||||
def change_friend_name(self):
|
||||
"""Change the friend's name in the nested dict."""
|
||||
|
Loading…
Reference in New Issue
Block a user