@@ -958,8 +958,7 @@ def add_init(self):
958
958
self ._cache_hash ,
959
959
self ._base_attr_map ,
960
960
self ._is_exc ,
961
- self ._on_setattr is not None
962
- and self ._on_setattr is not setters .NO_OP ,
961
+ self ._on_setattr ,
963
962
attrs_init = False ,
964
963
)
965
964
)
@@ -978,8 +977,7 @@ def add_attrs_init(self):
978
977
self ._cache_hash ,
979
978
self ._base_attr_map ,
980
979
self ._is_exc ,
981
- self ._on_setattr is not None
982
- and self ._on_setattr is not setters .NO_OP ,
980
+ self ._on_setattr ,
983
981
attrs_init = True ,
984
982
)
985
983
)
@@ -2008,13 +2006,19 @@ def _make_init(
2008
2006
cache_hash ,
2009
2007
base_attr_map ,
2010
2008
is_exc ,
2011
- has_global_on_setattr ,
2009
+ global_on_setattr ,
2012
2010
attrs_init ,
2013
2011
):
2012
+ has_global_on_setattr = (
2013
+ global_on_setattr is not None
2014
+ and global_on_setattr is not setters .NO_OP
2015
+ )
2016
+
2014
2017
if frozen and has_global_on_setattr :
2015
2018
raise ValueError ("Frozen classes can't use on_setattr." )
2016
2019
2017
2020
needs_cached_setattr = cache_hash or frozen
2021
+ has_validator = False
2018
2022
filtered_attrs = []
2019
2023
attr_dict = {}
2020
2024
for a in attrs :
@@ -2023,6 +2027,7 @@ def _make_init(
2023
2027
2024
2028
filtered_attrs .append (a )
2025
2029
attr_dict [a .name ] = a
2030
+ has_validator = has_validator or a .validator is not None
2026
2031
2027
2032
if a .on_setattr is not None :
2028
2033
if frozen is True :
@@ -2034,6 +2039,20 @@ def _make_init(
2034
2039
) or _is_slot_attr (a .name , base_attr_map ):
2035
2040
needs_cached_setattr = True
2036
2041
2042
+ # The default in define/mutable is a global on_setattr=setters.validate,
2043
+ # however it's quite likely, that no attribute has actually a validator.
2044
+ # Therefore, in the one case where on_setattr is validate and NO attribute
2045
+ # has a validator defined, we pretend as if no class-level on_setattr is
2046
+ # set.
2047
+ if (
2048
+ not frozen
2049
+ and not has_validator
2050
+ and global_on_setattr == setters .validate
2051
+ ):
2052
+ needs_cached_setattr = False
2053
+ has_global_on_setattr = False
2054
+ global_on_setattr = setters .NO_OP
2055
+
2037
2056
unique_filename = _generate_unique_filename (cls , "init" )
2038
2057
2039
2058
script , globs , annotations = _attrs_to_init_script (
0 commit comments