content: # -*- coding: utf-8 -*-
  
  
  import numpy as np
  import pandas as pd
  import pandas.util.testing as tm
  from pandas import (CategoricalIndex, DatetimeIndex, MultiIndex, PeriodIndex,
                      Series, TimedeltaIndex)
  
  
  def test_setops_errorcases(idx):
      # # non-iterable input
      cases = [0.5, 'xxx']
      methods = [idx.intersection, idx.union, idx.difference,
                 idx.symmetric_difference]
  
      for method in methods:
          for case in cases:
              tm.assert_raises_regex(TypeError,
                                     "Input must be Index "
                                     "or array-like",
                                     method, case)
  
  
  def test_intersection_base(idx):
      first = idx[:5]
      second = idx[:3]
      intersect = first.intersection(second)
  
      if isinstance(idx, CategoricalIndex):
          pass
      else:
          assert tm.equalContents(intersect, second)
  
      # GH 10149
      cases = [klass(second.values)
               for klass in [np.array, Series, list]]
      for case in cases:
          if isinstance(idx, PeriodIndex):
              msg = "can only call with other PeriodIndex-ed objects"
              with tm.assert_raises_regex(ValueError, msg):
                  result = first.intersection(case)
          elif isinstance(idx, CategoricalIndex):
              pass
          else:
              result = first.intersection(case)
              assert tm.equalContents(result, second)
  
      if isinstance(idx, MultiIndex):
          msg = "other must be a MultiIndex or a list of tuples"
          with tm.assert_raises_regex(TypeError, msg):
              result = first.intersection([1, 2, 3])
  
  
  def test_union_base(idx):
      first = idx[3:]
      second = idx[:5]
      everything = idx
      union = first.union(second)
      assert tm.equalContents(union, everything)
  
      # GH 10149
      cases = [klass(second.values)
               for klass in [np.array, Series, list]]
      for case in cases:
          if isinstance(idx, PeriodIndex):
              msg = "can only call with other PeriodIndex-ed objects"
              with tm.assert_raises_regex(ValueError, msg):
                  result = first.union(case)
          elif isinstance(idx, CategoricalIndex):
              pass
          else:
              result = first.union(case)
              assert tm.equalContents(result, everything)
  
      if isinstance(idx, MultiIndex):
          msg = "other must be a MultiIndex or a list of tuples"
          with tm.assert_raises_regex(TypeError, msg):
              result = first.union([1, 2, 3])
  
  
  def test_difference_base(idx):
      first = idx[2:]
      second = idx[:4]
      answer = idx[4:]
      result = first.difference(second)
  
      if isinstance(idx, CategoricalIndex):
          pass
      else:
          assert tm.equalContents(result, answer)
  
      # GH 10149
      cases = [klass(second.values)
               for klass in [np.array, Series, list]]
      for case in cases:
          if isinstance(idx, PeriodIndex):
              msg = "can only call with other PeriodIndex-ed objects"
              with tm.assert_raises_regex(ValueError, msg):
                  result = first.difference(case)
          elif isinstance(idx, CategoricalIndex):
              pass
          elif isinstance(idx, (DatetimeIndex, TimedeltaIndex)):
              assert result.__class__ == answer.__class__
              tm.assert_numpy_array_equal(result.sort_values().asi8,
                                          answer.sort_values().asi8)
          else:
              result = first.difference(case)
              assert tm.equalContents(result, answer)
  
      if isinstance(idx, MultiIndex):
          msg = "other must be a MultiIndex or a list of tuples"
          with tm.assert_raises_regex(TypeError, msg):
              result = first.difference([1, 2, 3])
  
  
  def test_symmetric_difference(idx):
      first = idx[1:]
      second = idx[:-1]
      if isinstance(idx, CategoricalIndex):
          pass
      else:
          answer = idx[[0, -1]]
          result = first.symmetric_difference(second)
          assert tm.equalContents(result, answer)
  
      # GH 10149
      cases = [klass(second.values)
               for klass in [np.array, Series, list]]
      for case in cases:
          if isinstance(idx, PeriodIndex):
              msg = "can only call with other PeriodIndex-ed objects"
              with tm.assert_raises_regex(ValueError, msg):
                  result = first.symmetric_difference(case)
          elif isinstance(idx, CategoricalIndex):
              pass
          else:
              result = first.symmetric_difference(case)
              assert tm.equalContents(result, answer)
  
      if isinstance(idx, MultiIndex):
          msg = "other must be a MultiIndex or a list of tuples"
          with tm.assert_raises_regex(TypeError, msg):
              first.symmetric_difference([1, 2, 3])
  
  
  def test_empty(idx):
      # GH 15270
      assert not idx.empty
      assert idx[:0].empty
  
  
  def test_difference(idx):
  
      first = idx
      result = first.difference(idx[-3:])
      expected = MultiIndex.from_tuples(sorted(idx[:-3].values),
                                        sortorder=0,
                                        names=idx.names)
  
      assert isinstance(result, MultiIndex)
      assert result.equals(expected)
      assert result.names == idx.names
  
      # empty difference: reflexive
      result = idx.difference(idx)
      expected = idx[:0]
      assert result.equals(expected)
      assert result.names == idx.names
  
      # empty difference: superset
      result = idx[-3:].difference(idx)
      expected = idx[:0]
      assert result.equals(expected)
      assert result.names == idx.names
  
      # empty difference: degenerate
      result = idx[:0].difference(idx)
      expected = idx[:0]
      assert result.equals(expected)
      assert result.names == idx.names
  
      # names not the same
      chunklet = idx[-3:]
      chunklet.names = ['foo', 'baz']
      result = first.difference(chunklet)
      assert result.names == (None, None)
  
      # empty, but non-equal
      result = idx.difference(idx.sortlevel(1)[0])
      assert len(result) == 0
  
      # raise Exception called with non-MultiIndex
      result = first.difference(first.values)
      assert result.equals(first[:0])
  
      # name from empty array
      result = first.difference([])
      assert first.equals(result)
      assert first.names == result.names
  
      # name from non-empty array
      result = first.difference([('foo', 'one')])
      expected = pd.MultiIndex.from_tuples([('bar', 'one'), ('baz', 'two'), (
          'foo', 'two'), ('qux', 'one'), ('qux', 'two')])
      expected.names = first.names
      assert first.names == result.names
      tm.assert_raises_regex(TypeError, "other must be a MultiIndex "
                             "or a list of tuples",
                             first.difference, [1, 2, 3, 4, 5])
  
  
  def test_union(idx):
      piece1 = idx[:5][::-1]
      piece2 = idx[3:]
  
      the_union = piece1 | piece2
  
      tups = sorted(idx.values)
      expected = MultiIndex.from_tuples(tups)
  
      assert the_union.equals(expected)
  
      # corner case, pass self or empty thing:
      the_union = idx.union(idx)
      assert the_union is idx
  
      the_union = idx.union(idx[:0])
      assert the_union is idx
  
      # won't work in python 3
      # tuples = _index.values
      # result = _index[:4] | tuples[4:]
      # assert result.equals(tuples)
  
      # not valid for python 3
      # def test_union_with_regular_index(self):
      #     other = Index(['A', 'B', 'C'])
  
      #     result = other.union(idx)
      #     assert ('foo', 'one') in result
      #     assert 'B' in result
  
      #     result2 = _index.union(other)
      #     assert result.equals(result2)
  
  
  def test_intersection(idx):
      piece1 = idx[:5][::-1]
      piece2 = idx[3:]
  
      the_int = piece1 & piece2
      tups = sorted(idx[3:5].values)
      expected = MultiIndex.from_tuples(tups)
      assert the_int.equals(expected)
  
      # corner case, pass self
      the_int = idx.intersection(idx)
      assert the_int is idx
  
      # empty intersection: disjoint
      empty = idx[:2] & idx[2:]
      expected = idx[:0]
      assert empty.equals(expected)
  
      # can't do in python 3
      # tuples = _index.values
      # result = _index & tuples
      # assert result.equals(tuples)
  