@@ -958,8 +958,7 @@ def add_init(self):
958958 self ._cache_hash ,
959959 self ._base_attr_map ,
960960 self ._is_exc ,
961- self ._on_setattr is not None
962- and self ._on_setattr is not setters .NO_OP ,
961+ self ._on_setattr ,
963962 attrs_init = False ,
964963 )
965964 )
@@ -978,8 +977,7 @@ def add_attrs_init(self):
978977 self ._cache_hash ,
979978 self ._base_attr_map ,
980979 self ._is_exc ,
981- self ._on_setattr is not None
982- and self ._on_setattr is not setters .NO_OP ,
980+ self ._on_setattr ,
983981 attrs_init = True ,
984982 )
985983 )
@@ -2008,13 +2006,19 @@ def _make_init(
20082006 cache_hash ,
20092007 base_attr_map ,
20102008 is_exc ,
2011- has_global_on_setattr ,
2009+ global_on_setattr ,
20122010 attrs_init ,
20132011):
2012+ has_global_on_setattr = (
2013+ global_on_setattr is not None
2014+ and global_on_setattr is not setters .NO_OP
2015+ )
2016+
20142017 if frozen and has_global_on_setattr :
20152018 raise ValueError ("Frozen classes can't use on_setattr." )
20162019
20172020 needs_cached_setattr = cache_hash or frozen
2021+ has_validator = False
20182022 filtered_attrs = []
20192023 attr_dict = {}
20202024 for a in attrs :
@@ -2023,6 +2027,7 @@ def _make_init(
20232027
20242028 filtered_attrs .append (a )
20252029 attr_dict [a .name ] = a
2030+ has_validator = has_validator or a .validator is not None
20262031
20272032 if a .on_setattr is not None :
20282033 if frozen is True :
@@ -2034,6 +2039,20 @@ def _make_init(
20342039 ) or _is_slot_attr (a .name , base_attr_map ):
20352040 needs_cached_setattr = True
20362041
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+
20372056 unique_filename = _generate_unique_filename (cls , "init" )
20382057
20392058 script , globs , annotations = _attrs_to_init_script (
0 commit comments