@@ -330,11 +330,21 @@ def _set_new_value(self, parent, parent_to_obj_elem, parent_to_obj_action,
330330 Set the element value on an object and if necessary convert the object to the proper mutable type
331331 """
332332 if isinstance (obj , tuple ):
333- # convert this object back to a tuple later
334- obj = self ._coerce_obj (
335- parent , obj , path , parent_to_obj_elem ,
336- parent_to_obj_action , elements ,
337- to_type = list , from_type = tuple )
333+ # Check if it's a NamedTuple and use _replace() to generate a new copy with the change
334+ if hasattr (obj , '_fields' ) and hasattr (obj , '_replace' ):
335+ if action == GETATTR :
336+ obj = obj ._replace (** {elem : new_value })
337+ if parent :
338+ self ._simple_set_elem_value (obj = parent , path_for_err_reporting = path ,
339+ elem = parent_to_obj_elem , value = obj ,
340+ action = parent_to_obj_action )
341+ return
342+ else :
343+ # Regular tuple - convert this object back to a tuple later
344+ obj = self ._coerce_obj (
345+ parent , obj , path , parent_to_obj_elem ,
346+ parent_to_obj_action , elements ,
347+ to_type = list , from_type = tuple )
338348 if elem != 0 and self .force and isinstance (obj , list ) and len (obj ) == 0 :
339349 # it must have been a dictionary
340350 obj = {}
@@ -709,7 +719,12 @@ def _do_set_or_frozenset_item(self, items, func):
709719 obj = self ._get_elem_and_compare_to_old_value (
710720 parent , path_for_err_reporting = path , expected_old_value = None , elem = elem , action = action , forced_old_value = set ())
711721 new_value = getattr (obj , func )(value )
712- self ._simple_set_elem_value (parent , path_for_err_reporting = path , elem = elem , value = new_value , action = action )
722+ if hasattr (parent , '_fields' ) and hasattr (parent , '_replace' ):
723+ # Handle parent NamedTuple by creating a new instance with _replace(). Will not work with nested objects.
724+ new_parent = parent ._replace (** {elem : new_value })
725+ self .root = new_parent
726+ else :
727+ self ._simple_set_elem_value (parent , path_for_err_reporting = path , elem = elem , value = new_value , action = action )
713728
714729 def _do_ignore_order_get_old (self , obj , remove_indexes_per_path , fixed_indexes_values , path_for_err_reporting ):
715730 """
0 commit comments