def get_identifier(self, instance): if ISerializable.providedBy(instance): return instance.type_name, id(instance) return id(instance)
def _assertEqualButDifferent(self, value, expected, idx, valids, expids): '''idx is used to identify every values uniquely to be able to verify references are made to the same value, valids and expids are dictionaries with instance id() for key and idx for value. Types and interfaces are assumed to be immutable atoms.''' # Only check references for type that can be referenced. # Let the immutable type do what they want, sometime strings # are interned sometime no, we don't care. if not isinstance(expected, (int, long, float, bool, str, unicode, type(None))): # Get unique instance identifiers expid = id(expected) valid = id(value) if expid in expids: # Expected value is a reference, check the other value is too self.assertTrue(valid in valids) # Check the two reference the same value inside the structure self.assertEqual(valids[valid], expids[expid]) return idx # Check the other value is not a reference if it wasn't expected self.assertFalse(valid in valids) # Store the instance identifiers for later checks expids[expid] = idx valids[valid] = idx if expected is None: self.assertEqual(expected, value) elif isinstance(expected, (list, tuple)): if expected != (): # Special case for tuple singleton self.assertIsNot(expected, value) self.assertEqual(len(expected), len(value)) for exp, val in zip(expected, value): idx = self._assertEqualButDifferent(val, exp, idx + 1, valids, expids) elif isinstance(expected, set): self.assertEqual(len(expected), len(value)) for exp in expected: self.assertTrue(exp in value) val = [v for v in value if v == exp][0] idx = self._assertEqualButDifferent(val, exp, idx + 1, valids, expids) elif isinstance(expected, dict): self.assertEqual(len(expected), len(value)) for exp_key, exp_val in expected.items(): self.assertTrue(exp_key in value) val_key = [k for k in value if k == exp_key][0] val_val = value[val_key] idx = self._assertEqualButDifferent(val_key, exp_key, idx + 1, valids, expids) idx = self._assertEqualButDifferent(val_val, exp_val, idx + 1, valids, expids) elif isinstance(value, float): self.assertAlmostEqual(value, expected) elif isinstance(value, (int, long, bool, str, unicode, type, InterfaceClass)): self.assertEqual(value, expected) else: self.assertIsNot(expected, value) if ISerializable.providedBy(expected): self.assertTrue(ISerializable.providedBy(value)) idx = self._assertEqualButDifferent(value.__dict__, expected.__dict__, idx + 1, valids, expids) return idx