nodes: 0, module; 1, function_definition; 2, function_name:union; 3, parameters; 4, block; 5, identifier:self; 6, identifier:other; 7, default_parameter; 8, expression_statement; 9, expression_statement; 10, expression_statement; 11, expression_statement; 12, if_statement; 13, if_statement; 14, comment:# TODO: is_dtype_union_equal is a hack around; 15, comment:# 1. buggy set ops with duplicates (GH #13432); 16, comment:# 2. CategoricalIndex lacking setops (GH #10186); 17, comment:# Once those are fixed, this workaround can be removed; 18, if_statement; 19, comment:# TODO(EA): setops-refactor, clean all this up; 20, if_statement; 21, if_statement; 22, if_statement; 23, comment:# for subclasses; 24, return_statement; 25, identifier:sort; 26, None; 27, comment:"""
          Form the union of two Index objects.
  
          Parameters
          ----------
          other : Index or array-like
          sort : bool or None, default None
              Whether to sort the resulting Index.
  
              * None : Sort the result, except when
  
                1. `self` and `other` are equal.
                2. `self` or `other` has length 0.
                3. Some values in `self` or `other` cannot be compared.
                   A RuntimeWarning is issued in this case.
  
              * False : do not sort the result.
  
              .. versionadded:: 0.24.0
  
              .. versionchanged:: 0.24.1
  
                 Changed the default value from ``True`` to ``None``
                 (without change in behaviour).
  
          Returns
          -------
          union : Index
  
          Examples
          --------
  
          >>> idx1 = pd.Index([1, 2, 3, 4])
          >>> idx2 = pd.Index([3, 4, 5, 6])
          >>> idx1.union(idx2)
          Int64Index([1, 2, 3, 4, 5, 6], dtype='int64')
          """; 28, call; 29, call; 30, assignment; 31, boolean_operator; 32, block; 33, comparison_operator:len(self) == 0; 34, block; 35, not_operator; 36, block; 37, boolean_operator; 38, block; 39, else_clause; 40, boolean_operator; 41, block; 42, else_clause; 43, boolean_operator; 44, block; 45, else_clause; 46, call; 47, attribute; 48, argument_list; 49, attribute; 50, argument_list; 51, identifier:other; 52, call; 53, comparison_operator:len(other) == 0; 54, call; 55, return_statement; 56, call; 57, integer:0; 58, return_statement; 59, call; 60, expression_statement; 61, expression_statement; 62, return_statement; 63, call; 64, call; 65, expression_statement; 66, block; 67, call; 68, call; 69, expression_statement; 70, block; 71, boolean_operator; 72, attribute; 73, try_statement; 74, block; 75, attribute; 76, argument_list; 77, identifier:self; 78, identifier:_validate_sort_keyword; 79, identifier:sort; 80, identifier:self; 81, identifier:_assert_can_do_setop; 82, identifier:other; 83, identifier:ensure_index; 84, argument_list; 85, call; 86, integer:0; 87, attribute; 88, argument_list; 89, call; 90, identifier:len; 91, argument_list; 92, call; 93, identifier:is_dtype_union_equal; 94, argument_list; 95, assignment; 96, assignment; 97, call; 98, identifier:is_period_dtype; 99, argument_list; 100, identifier:is_datetime64tz_dtype; 101, argument_list; 102, assignment; 103, expression_statement; 104, identifier:is_period_dtype; 105, argument_list; 106, identifier:is_datetime64tz_dtype; 107, argument_list; 108, assignment; 109, expression_statement; 110, comparison_operator:sort is None; 111, attribute; 112, identifier:other; 113, identifier:is_monotonic; 114, block; 115, except_clause; 116, expression_statement; 117, expression_statement; 118, if_statement; 119, if_statement; 120, identifier:self; 121, identifier:_wrap_setop_result; 122, identifier:other; 123, identifier:result; 124, identifier:other; 125, identifier:len; 126, argument_list; 127, identifier:self; 128, identifier:equals; 129, identifier:other; 130, attribute; 131, argument_list; 132, identifier:self; 133, attribute; 134, argument_list; 135, attribute; 136, attribute; 137, identifier:this; 138, call; 139, identifier:other; 140, call; 141, attribute; 142, argument_list; 143, identifier:self; 144, identifier:self; 145, identifier:lvals; 146, attribute; 147, assignment; 148, identifier:other; 149, identifier:other; 150, identifier:rvals; 151, attribute; 152, assignment; 153, identifier:sort; 154, None; 155, identifier:self; 156, identifier:is_monotonic; 157, expression_statement; 158, identifier:TypeError; 159, comment:# incomparable objects; 160, block; 161, assignment; 162, assignment; 163, comparison_operator:len(indexer) > 0; 164, block; 165, else_clause; 166, comparison_operator:sort is None; 167, block; 168, identifier:other; 169, identifier:self; 170, identifier:_get_reconciled_name_object; 171, identifier:other; 172, identifier:other; 173, identifier:_get_reconciled_name_object; 174, identifier:self; 175, identifier:self; 176, identifier:dtype; 177, identifier:other; 178, identifier:dtype; 179, attribute; 180, argument_list; 181, attribute; 182, argument_list; 183, identifier:this; 184, identifier:union; 185, identifier:other; 186, keyword_argument; 187, identifier:self; 188, identifier:_ndarray_values; 189, identifier:lvals; 190, attribute; 191, identifier:other; 192, identifier:_ndarray_values; 193, identifier:rvals; 194, attribute; 195, assignment; 196, expression_statement; 197, comment:# worth making this faster? a very unusual case; 198, expression_statement; 199, expression_statement; 200, identifier:indexer; 201, call; 202, pattern_list; 203, call; 204, call; 205, integer:0; 206, expression_statement; 207, expression_statement; 208, block; 209, identifier:sort; 210, None; 211, try_statement; 212, identifier:self; 213, identifier:astype; 214, string; 215, identifier:other; 216, identifier:astype; 217, string; 218, identifier:sort; 219, identifier:sort; 220, identifier:self; 221, identifier:_values; 222, identifier:other; 223, identifier:_values; 224, identifier:result; 225, subscript; 226, assignment; 227, assignment; 228, call; 229, attribute; 230, argument_list; 231, identifier:indexer; 232, attribute; 233, argument_list; 234, identifier:len; 235, argument_list; 236, assignment; 237, assignment; 238, expression_statement; 239, block; 240, except_clause; 241, string_content:O; 242, string_content:O; 243, call; 244, integer:0; 245, identifier:result; 246, call; 247, identifier:value_set; 248, call; 249, attribute; 250, argument_list; 251, identifier:self; 252, identifier:get_indexer; 253, identifier:other; 254, parenthesized_expression; 255, identifier:nonzero; 256, identifier:indexer; 257, identifier:other_diff; 258, call; 259, identifier:result; 260, call; 261, assignment; 262, expression_statement; 263, as_pattern; 264, block; 265, attribute; 266, argument_list; 267, identifier:list; 268, argument_list; 269, identifier:set; 270, argument_list; 271, identifier:result; 272, identifier:extend; 273, list_comprehension; 274, comparison_operator:indexer == -1; 275, attribute; 276, argument_list; 277, attribute; 278, argument_list; 279, identifier:result; 280, identifier:lvals; 281, assignment; 282, identifier:TypeError; 283, as_pattern_target; 284, expression_statement; 285, identifier:self; 286, identifier:_outer_indexer; 287, identifier:lvals; 288, identifier:rvals; 289, identifier:lvals; 290, identifier:lvals; 291, identifier:x; 292, for_in_clause; 293, if_clause; 294, identifier:indexer; 295, unary_operator; 296, identifier:algos; 297, identifier:take_nd; 298, identifier:rvals; 299, identifier:indexer; 300, keyword_argument; 301, identifier:_concat; 302, identifier:_concat_compat; 303, tuple; 304, identifier:result; 305, call; 306, identifier:e; 307, call; 308, identifier:x; 309, identifier:rvals; 310, comparison_operator:x not in value_set; 311, integer:1; 312, identifier:allow_fill; 313, False; 314, identifier:lvals; 315, identifier:other_diff; 316, attribute; 317, argument_list; 318, attribute; 319, argument_list; 320, identifier:x; 321, identifier:value_set; 322, identifier:sorting; 323, identifier:safe_sort; 324, identifier:result; 325, identifier:warnings; 326, identifier:warn; 327, call; 328, identifier:RuntimeWarning; 329, keyword_argument; 330, attribute; 331, argument_list; 332, identifier:stacklevel; 333, integer:3; 334, concatenated_string; 335, identifier:format; 336, identifier:e; 337, string:"{}, sort order is undefined for "; 338, string:"incomparable objects"
code: def union(self, other, sort=None):
          """
          Form the union of two Index objects.
  
          Parameters
          ----------
          other : Index or array-like
          sort : bool or None, default None
              Whether to sort the resulting Index.
  
              * None : Sort the result, except when
  
                1. `self` and `other` are equal.
                2. `self` or `other` has length 0.
                3. Some values in `self` or `other` cannot be compared.
                   A RuntimeWarning is issued in this case.
  
              * False : do not sort the result.
  
              .. versionadded:: 0.24.0
  
              .. versionchanged:: 0.24.1
  
                 Changed the default value from ``True`` to ``None``
                 (without change in behaviour).
  
          Returns
          -------
          union : Index
  
          Examples
          --------
  
          >>> idx1 = pd.Index([1, 2, 3, 4])
          >>> idx2 = pd.Index([3, 4, 5, 6])
          >>> idx1.union(idx2)
          Int64Index([1, 2, 3, 4, 5, 6], dtype='int64')
          """
          self._validate_sort_keyword(sort)
          self._assert_can_do_setop(other)
          other = ensure_index(other)
  
          if len(other) == 0 or self.equals(other):
              return self._get_reconciled_name_object(other)
  
          if len(self) == 0:
              return other._get_reconciled_name_object(self)
  
          # TODO: is_dtype_union_equal is a hack around
          # 1. buggy set ops with duplicates (GH #13432)
          # 2. CategoricalIndex lacking setops (GH #10186)
          # Once those are fixed, this workaround can be removed
          if not is_dtype_union_equal(self.dtype, other.dtype):
              this = self.astype('O')
              other = other.astype('O')
              return this.union(other, sort=sort)
  
          # TODO(EA): setops-refactor, clean all this up
          if is_period_dtype(self) or is_datetime64tz_dtype(self):
              lvals = self._ndarray_values
          else:
              lvals = self._values
          if is_period_dtype(other) or is_datetime64tz_dtype(other):
              rvals = other._ndarray_values
          else:
              rvals = other._values
  
          if sort is None and self.is_monotonic and other.is_monotonic:
              try:
                  result = self._outer_indexer(lvals, rvals)[0]
              except TypeError:
                  # incomparable objects
                  result = list(lvals)
  
                  # worth making this faster? a very unusual case
                  value_set = set(lvals)
                  result.extend([x for x in rvals if x not in value_set])
          else:
              indexer = self.get_indexer(other)
              indexer, = (indexer == -1).nonzero()
  
              if len(indexer) > 0:
                  other_diff = algos.take_nd(rvals, indexer,
                                             allow_fill=False)
                  result = _concat._concat_compat((lvals, other_diff))
  
              else:
                  result = lvals
  
              if sort is None:
                  try:
                      result = sorting.safe_sort(result)
                  except TypeError as e:
                      warnings.warn("{}, sort order is undefined for "
                                    "incomparable objects".format(e),
                                    RuntimeWarning, stacklevel=3)
  
          # for subclasses
          return self._wrap_setop_result(other, result)