code: def _add_attr_values_from_insert_to_original(original_code, insert_code, insert_code_list, attribute_name, op_list):
      
      orig_value = getattr(original_code, attribute_name)
      insert_value = getattr(insert_code, attribute_name)
      orig_names_len = len(orig_value)
      code_with_new_values = list(insert_code_list)
      offset = 0
      while offset < len(code_with_new_values):
          op = code_with_new_values[offset]
          if op in op_list:
              new_val = code_with_new_values[offset + 1] + orig_names_len
              if new_val > MAX_BYTE:
                  code_with_new_values[offset + 1] = new_val & MAX_BYTE
                  code_with_new_values = code_with_new_values[:offset] + [EXTENDED_ARG, new_val >> 8] + \
                                         code_with_new_values[offset:]
                  offset += 2
              else:
                  code_with_new_values[offset + 1] = new_val
          offset += 2
      new_values = orig_value + insert_value
      return bytes(code_with_new_values), new_values
docs: This function appends values of the attribute `attribute_name` of the inserted code to the original values,
       and changes indexes inside inserted code. If some bytecode instruction in the inserted code used to call argument
       number i, after modification it calls argument n + i, where n - length of the values in the original code.
       So it helps to avoid variables mixing between two pieces of code.
  
      :param original_code: code to modify
      :param insert_code: code to insert
      :param insert_code_obj: bytes sequence of inserted code, which should be modified too
      :param attribute_name: name of attribute to modify ('co_names', 'co_consts' or 'co_varnames')
      :param op_list: sequence of bytecodes whose arguments should be changed
      :return: modified bytes sequence of the code to insert and new values of the attribute `attribute_name` for
      original code