Code review changes · pydantic/pydantic@404b8b7 (original) (raw)
`@@ -86,10 +86,10 @@ def _model_field_setattr_handler(model: BaseModel, name: str, val: Any) -> None:
`
86
86
`model.pydantic_fields_set.add(name)
`
87
87
``
88
88
``
89
``
`-
SIMPLE_SETATTR_HANDLERS: Mapping[str, Callable[[BaseModel, str, Any], None]] = {
`
``
89
`+
_SIMPLE_SETATTR_HANDLERS: Mapping[str, Callable[[BaseModel, str, Any], None]] = {
`
90
90
`'model_field': _model_field_setattr_handler,
`
91
``
`-
'validate_assignment': lambda model, name, val: model.pydantic_validator.validate_assignment(model, name, val), # type: ignore
`
92
``
`-
'private': lambda model, name, val: model.pydantic_private.setitem(name, val), # type: ignore
`
``
91
`+
'validate_assignment': lambda model, name, val: model.pydantic_validator.validate_assignment(model, name, val), # pyright: ignore[reportAssignmentType]
`
``
92
`+
'private': lambda model, name, val: model.pydantic_private.setitem(name, val), # pyright: ignore[reportOptionalMemberAccess]
`
93
93
`'cached_property': lambda model, name, val: model.dict.setitem(name, val),
`
94
94
`'extra_known': lambda model, name, val: _object_setattr(model, name, val),
`
95
95
`}
`
`@@ -909,16 +909,18 @@ def getattr(self, item: str) -> Any:
`
909
909
`def setattr(self, name: str, value: Any) -> None:
`
910
910
`if (setattr_handler := self.pydantic_setattr_handlers.get(name)) is not None:
`
911
911
`setattr_handler(self, name, value)
`
``
912
`+
if None is returned from _setattr_handler, the attribute was set directly
`
912
913
`elif (setattr_handler := self._setattr_handler(name, value)) is not None:
`
913
914
`setattr_handler(self, name, value) # call here to not memo on possibly unknown fields
`
914
915
`self.pydantic_setattr_handlers[name] = setattr_handler # memoize the handler for faster access
`
915
916
``
916
``
`-
def _setattr_handler(self, name: str, value: Any) -> Callable[[BaseModel, Any, Any], None] | None:
`
``
917
`+
def _setattr_handler(self, name: str, value: Any) -> Callable[[BaseModel, str, Any], None] | None:
`
917
918
`"""Get a handler for setting an attribute on the model instance.
`
918
919
``
919
920
` Returns:
`
920
921
` A handler for setting an attribute on the model instance. Used for memoization of the handler.
`
921
``
`-
Gives None when memoization is not safe, then the attribute is set directly.
`
``
922
`` +
Memoizing the handlers leads to a dramatic performance improvement in __setattr__
``
``
923
`` +
Returns None
when memoization is not safe, then the attribute is set directly.
``
922
924
` """
`
923
925
`cls = self.class
`
924
926
`if name in cls.class_vars:
`
`@@ -931,7 +933,7 @@ def _setattr_handler(self, name: str, value: Any) -> Callable[[BaseModel, Any, A
`
931
933
`if hasattr(attribute, 'set'):
`
932
934
`return lambda model, _name, val: attribute.set(model, val)
`
933
935
`else:
`
934
``
`-
return SIMPLE_SETATTR_HANDLERS['private']
`
``
936
`+
return _SIMPLE_SETATTR_HANDLERS['private']
`
935
937
`else:
`
936
938
`_object_setattr(self, name, value)
`
937
939
`return None # Can not return memoized handler with possibly freeform attr names
`
`@@ -946,9 +948,9 @@ def _setattr_handler(self, name: str, value: Any) -> Callable[[BaseModel, Any, A
`
946
948
`if isinstance(attr, property):
`
947
949
`return lambda model, _name, val: attr.set(model, val)
`
948
950
`elif isinstance(attr, cached_property):
`
949
``
`-
return SIMPLE_SETATTR_HANDLERS['cached_property']
`
``
951
`+
return _SIMPLE_SETATTR_HANDLERS['cached_property']
`
950
952
`elif cls.model_config.get('validate_assignment'):
`
951
``
`-
return SIMPLE_SETATTR_HANDLERS['validate_assignment']
`
``
953
`+
return _SIMPLE_SETATTR_HANDLERS['validate_assignment']
`
952
954
`elif name not in cls.pydantic_fields:
`
953
955
`if cls.model_config.get('extra') != 'allow':
`
954
956
`# TODO - matching error
`
`@@ -959,10 +961,9 @@ def _setattr_handler(self, name: str, value: Any) -> Callable[[BaseModel, Any, A
`
959
961
`return None # Can not return memoized handler with possibly freeform attr names
`
960
962
`else:
`
961
963
`# attribute does exist, and was not in extra, so update it
`
962
``
`-
return SIMPLE_SETATTR_HANDLERS['extra_known']
`
``
964
`+
return _SIMPLE_SETATTR_HANDLERS['extra_known']
`
963
965
`else:
`
964
``
`-
Normal model field
`
965
``
`-
return SIMPLE_SETATTR_HANDLERS['model_field']
`
``
966
`+
return _SIMPLE_SETATTR_HANDLERS['model_field']
`
966
967
``
967
968
`def delattr(self, item: str) -> Any:
`
968
969
`if item in self.private_attributes:
`