def test_xor(self): self.assertEqual(1 ^ Bit(0), 1) self.assertEqual(1 ^ Bit(1), 0) self.assertEqual(0b0110 ^ Bit(0b1100), 0b1010) self.assertEqual(Bit(1) ^ Bit(0), 1) self.assertEqual(Bit(1) ^ Bit(1), 0) self.assertEqual(Bit(0b0110) ^ Bit(0b1100), 0b1010)
def test_or(self): self.assertEqual(1 | Bit(0), 1) self.assertEqual(1 | Bit(1), 1) self.assertEqual(0b0110 | Bit(0b1100), 0b1110) self.assertEqual(Bit(1) | Bit(0), 1) self.assertEqual(Bit(1) | Bit(1), 1) self.assertEqual(Bit(0b0110) | Bit(0b1100), 0b1110)
def test_and(self): self.assertEqual(1 & Bit(0), 0) self.assertEqual(1 & Bit(1), 1) self.assertEqual(0b0110 & Bit(0b1100), 0b0100) self.assertEqual(Bit(1) & Bit(0), 0) self.assertEqual(Bit(1) & Bit(1), 1) self.assertEqual(Bit(0b0110) & Bit(0b1100), 0b0100)
def test_int(self): bit = Bit(0) self.assertEqual(int(bit), 0) self.assertEqual(bool(bit), False) self.assertTrue(not bit) self.assertEqual(str(bit), '0') self.assertEqual(repr(bit), '<Bit: 0>') bit = Bit(0b1100) self.assertEqual(int(bit), 0b1100) self.assertEqual(bool(bit), True) self.assertFalse(not bit) self.assertEqual(str(bit), '1100') self.assertEqual(repr(bit), '<Bit: 1100>')
def __init__(self, field, choices): self._names = [] self._verbose_names = [] self._bits = [] for i, choice in enumerate(choices): name, verbose = choice bit = Bit(2**i, field) self._names.append(name) self._verbose_names.append(verbose) self._bits.append(bit) self._field = field self._max_value = (2**(i + 1)) - 1
def __get__(self, obj, cls=None): if obj is not None: if self.cache_attr not in obj.__dict__: obj.__dict__[self.cache_attr] = Bit( self.field.join_value(obj.__dict__[attr] for attr in self.attrs), self.field, ) return obj.__dict__[self.cache_attr] elif cls is not None: return self.flags else: return self
def __set__(self, obj, value): if obj is None: msg = '`{0}` must be accessed via instance.' raise AttributeError(msg.format(self.field.name)) if isinstance(value, six.integer_types): if self.first_attr not in obj.__dict__: # This is intended for quickly load values from database. obj.__dict__[self.first_attr] = value else: raise TypeError('Bit fields do not accept integer values.') else: value = self.flags.get_value(value) pieces = self.field.split_value(value) for i, attr in enumerate(self.attrs): if i < len(pieces): obj.__dict__[attr] = pieces[i] else: obj.__dict__[attr] = 0 obj.__dict__[self.cache_attr] = Bit(value, self.field)
def test_invert(self): self.assertEqual(~Bit(1), 0) self.assertEqual(~Bit(0), 1) self.assertEqual(~Bit(0b100110), 0b011001)
def test_comparison(self): self.assertEqual(Bit(0), Bit(0)) self.assertNotEqual(Bit(1), Bit(0)) self.assertEqual(Bit(0), 0) self.assertNotEqual(Bit(1), 0)
def to_python(self, value): return Bit(value)