Example #1
0
 def test_mro_merge(self):
     self.assertEqual([], mro.MROMerge([[], []]))
     self.assertEqual([1], mro.MROMerge([[], [1]]))
     self.assertEqual([1], mro.MROMerge([[1], []]))
     self.assertEqual([1, 2], mro.MROMerge([[1], [2]]))
     self.assertEqual([1, 2], mro.MROMerge([[1, 2], [2]]))
     self.assertEqual([1, 2, 3, 4], mro.MROMerge([[1, 2, 3], [2, 4]]))
     self.assertEqual([1, 2, 3], mro.MROMerge([[1, 2], [1, 2, 3]]))
     self.assertEqual([1, 2], mro.MROMerge([[1, 1], [2, 2]]))
     self.assertEqual([1, 2, 3, 4, 5, 6],
                      mro.MROMerge([[1, 3, 5], [2, 3, 4], [4, 5, 6]]))
     self.assertEqual([1, 2, 3], mro.MROMerge([[1, 2, 1], [2, 3, 2]]))
Example #2
0
    def compute_mro(self):
        """Compute the class precedence list (mro) according to C3."""
        bases = abstract_utils.get_mro_bases(self.bases(), self.vm)
        bases = [[self]] + [list(base.mro) for base in bases] + [list(bases)]
        # If base classes are `ParameterizedClass`, we will use their `base_cls` to
        # calculate the MRO. Bacause of type parameter renaming, we can not compare
        # the `ParameterizedClass`s which contain the same `base_cls`.  See example:
        #   class A(Iterator[T]): ...
        #   class B(Iterator[U], A[V]): ...
        # The inheritance: [B], [Iterator, ...], [A, Iterator, ...], [Iterator, A]
        # So this has MRO order issue, but because the template names of
        # `ParameterizedClass` of `Iterator` are different, they will be treated as
        # different base classes and it will infer the MRO order is correct.
        # TODO(b/159044968): fix this by solving the template rename problem
        base2cls = {}
        newbases = []
        for row in bases:
            baselist = []
            for base in row:
                if base.isinstance_ParameterizedClass():
                    base2cls[base.base_cls] = base
                    baselist.append(base.base_cls)
                else:
                    base2cls[base] = base
                    baselist.append(base)
            newbases.append(baselist)

        # calc MRO and replace them with original base classes
        return tuple(base2cls[base] for base in mro.MROMerge(newbases))
Example #3
0
  def compute_mro(self):
    """Compute the class precedence list (mro) according to C3."""
    bases = abstract_utils.get_mro_bases(self.bases(), self.vm)
    bases = [[self]] + [list(base.mro) for base in bases] + [list(bases)]
    base2cls = {}
    newbases = []
    for row in bases:
      baselist = []
      for base in row:
        if base.isinstance_ParameterizedClass():
          base2cls[base.base_cls] = base
          baselist.append(base.base_cls)
        else:
          base2cls[base] = base
          baselist.append(base)
      newbases.append(baselist)

    # calc MRO and replace them with original base classes
    return tuple(base2cls[base] for base in mro.MROMerge(newbases))