From 104a7bcc28f96c6192815e82971d660c9910c16b Mon Sep 17 00:00:00 2001 From: Thomas Wouters Date: Thu, 24 Aug 2000 20:14:10 +0000 Subject: [PATCH] Support for augmented assignment in the UserList, UserDict, UserString and rfc822 (Addresslist) modules. Also a preliminary testcase for augmented assignment, which should actually be merged with the test_class testcase I added last week. --- Lib/UserList.py | 11 ++ Lib/UserString.py | 11 ++ Lib/dis.py | 12 +- Lib/rfc822.py | 14 ++ Lib/test/output/test_augassign | 48 +++++++ Lib/test/test_augassign.py | 232 +++++++++++++++++++++++++++++++++ 6 files changed, 327 insertions(+), 1 deletion(-) create mode 100644 Lib/test/output/test_augassign create mode 100644 Lib/test/test_augassign.py diff --git a/Lib/UserList.py b/Lib/UserList.py index d4a8d2f6e4e..114606098ce 100644 --- a/Lib/UserList.py +++ b/Lib/UserList.py @@ -51,9 +51,20 @@ class UserList: return self.__class__(other + self.data) else: return self.__class__(list(other) + self.data) + def __iadd__(self, other): + if isinstance(other, UserList): + self.data += other.data + elif isinstance(other, type(self.data)): + self.data += other + else: + self.data += list(other) + return self def __mul__(self, n): return self.__class__(self.data*n) __rmul__ = __mul__ + def __imul__(self, n): + self.data *= n + return self def append(self, item): self.data.append(item) def insert(self, i, item): self.data.insert(i, item) def pop(self, i=-1): return self.data.pop(i) diff --git a/Lib/UserString.py b/Lib/UserString.py index 070b3e1fd1d..34f3216cfe0 100755 --- a/Lib/UserString.py +++ b/Lib/UserString.py @@ -50,9 +50,20 @@ class UserString: return self.__class__(other + self.data) else: return self.__class__(str(other) + self.data) + def __iadd__(self, other): + if isinstance(other, UserString): + self.data += other.data + elif isinstance(other, StringType) or isinstance(other, UnicodeType): + self.data += other + else + self.data += str(other) + return self def __mul__(self, n): return self.__class__(self.data*n) __rmul__ = __mul__ + def __imull__(self, n): + self.data += n + return self # the following methods are defined in alphabetical order: def capitalize(self): return self.__class__(self.data.capitalize()) diff --git a/Lib/dis.py b/Lib/dis.py index 9fc9d300594..713d7aa6820 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -182,6 +182,11 @@ def_op('DELETE_SLICE+1', 51) def_op('DELETE_SLICE+2', 52) def_op('DELETE_SLICE+3', 53) +def_op('INPLACE_ADD', 55) +def_op('INPLACE_SUBTRACT', 56) +def_op('INPLACE_MULTIPLY', 57) +def_op('INPLACE_DIVIDE', 58) +def_op('INPLACE_MODULO', 59) def_op('STORE_SUBSCR', 60) def_op('DELETE_SUBSCR', 61) @@ -190,13 +195,18 @@ def_op('BINARY_RSHIFT', 63) def_op('BINARY_AND', 64) def_op('BINARY_XOR', 65) def_op('BINARY_OR', 66) +def_op('INPLACE_POWER', 67) def_op('PRINT_EXPR', 70) def_op('PRINT_ITEM', 71) def_op('PRINT_NEWLINE', 72) def_op('PRINT_ITEM_TO', 73) def_op('PRINT_NEWLINE_TO', 74) - +def_op('INPLACE_LSHIFT', 75) +def_op('INPLACE_RSHIFT', 76) +def_op('INPLACE_AND', 77) +def_op('INPLACE_XOR', 78) +def_op('INPLACE_OR', 79) def_op('BREAK_LOOP', 80) def_op('LOAD_LOCALS', 82) diff --git a/Lib/rfc822.py b/Lib/rfc822.py index 64731494d9a..42aac1c403f 100644 --- a/Lib/rfc822.py +++ b/Lib/rfc822.py @@ -763,6 +763,13 @@ class AddressList(AddrlistClass): newaddr.addresslist.append(x) return newaddr + def __iadd__(self, other): + # Set union, in-place + for x in other.addresslist: + if not x in self.addresslist: + self.addresslist.append(x) + return self + def __sub__(self, other): # Set difference newaddr = AddressList(None) @@ -771,6 +778,13 @@ class AddressList(AddrlistClass): newaddr.addresslist.append(x) return newaddr + def __isub__(self, other): + # Set difference, in-place + for x in other.addresslist: + if x in self.addresslist: + self.addresslist.remove(x) + return self + def __getitem__(self, index): # Make indexing, slices, and 'in' work return self.addresslist[index] diff --git a/Lib/test/output/test_augassign b/Lib/test/output/test_augassign new file mode 100644 index 00000000000..ceffd59610e --- /dev/null +++ b/Lib/test/output/test_augassign @@ -0,0 +1,48 @@ +test_augassign +6 +[6] +6 +[1, 2, 3, 4, 1, 2, 3, 4] +[1, 2, 1, 2, 3] +1 +1 +1 +11 +1 +12 +1 +1 +13 +__add__ called +__radd__ called +__iadd__ called +__sub__ called +__rsub__ called +__isub__ called +__mul__ called +__rmul__ called +__imul__ called +__div__ called +__rdiv__ called +__idiv__ called +__mod__ called +__rmod__ called +__imod__ called +__pow__ called +__rpow__ called +__ipow__ called +__or__ called +__ror__ called +__ior__ called +__and__ called +__rand__ called +__iand__ called +__xor__ called +__rxor__ called +__ixor__ called +__rshift__ called +__rrshift__ called +__irshift__ called +__lshift__ called +__rlshift__ called +__ilshift__ called diff --git a/Lib/test/test_augassign.py b/Lib/test/test_augassign.py new file mode 100644 index 00000000000..a01195eae08 --- /dev/null +++ b/Lib/test/test_augassign.py @@ -0,0 +1,232 @@ + +# Augmented assignment test. + +x = 2 +x += 1 +x *= 2 +x **= 2 +x -= 8 +x /= 2 +x %= 12 +x &= 2 +x |= 5 +x ^= 1 + +print x + +x = [2] +x[0] += 1 +x[0] *= 2 +x[0] **= 2 +x[0] -= 8 +x[0] /= 2 +x[0] %= 12 +x[0] &= 2 +x[0] |= 5 +x[0] ^= 1 + +print x + +x = {0: 2} +x[0] += 1 +x[0] *= 2 +x[0] **= 2 +x[0] -= 8 +x[0] /= 2 +x[0] %= 12 +x[0] &= 2 +x[0] |= 5 +x[0] ^= 1 + +print x[0] + +x = [1,2] +x += [3,4] +x *= 2 + +print x + +x = [1, 2, 3] +y = x +x[1:2] *= 2 +y[1:2] += [1] + +print x +print x is y + +class aug_test: + def __init__(self, value): + self.val = value + def __radd__(self, val): + return self.val + val + def __add__(self, val): + return aug_test(self.val + val) + + +class aug_test2(aug_test): + def __iadd__(self, val): + self.val = self.val + val + return self + +class aug_test3(aug_test): + def __iadd__(self, val): + return aug_test3(self.val + val) + +x = aug_test(1) +y = x +x += 10 + +print isinstance(x, aug_test) +print y is not x +print x.val + +x = aug_test2(2) +y = x +x += 10 + +print y is x +print x.val + +x = aug_test3(3) +y = x +x += 10 + +print isinstance(x, aug_test3) +print y is not x +print x.val + +class testall: + + def __add__(self, val): + print "__add__ called" + def __radd__(self, val): + print "__radd__ called" + def __iadd__(self, val): + print "__iadd__ called" + return self + + def __sub__(self, val): + print "__sub__ called" + def __rsub__(self, val): + print "__rsub__ called" + def __isub__(self, val): + print "__isub__ called" + return self + + def __mul__(self, val): + print "__mul__ called" + def __rmul__(self, val): + print "__rmul__ called" + def __imul__(self, val): + print "__imul__ called" + return self + + def __div__(self, val): + print "__div__ called" + def __rdiv__(self, val): + print "__rdiv__ called" + def __idiv__(self, val): + print "__idiv__ called" + return self + + def __mod__(self, val): + print "__mod__ called" + def __rmod__(self, val): + print "__rmod__ called" + def __imod__(self, val): + print "__imod__ called" + return self + + def __pow__(self, val): + print "__pow__ called" + def __rpow__(self, val): + print "__rpow__ called" + def __ipow__(self, val): + print "__ipow__ called" + return self + + def __or__(self, val): + print "__or__ called" + def __ror__(self, val): + print "__ror__ called" + def __ior__(self, val): + print "__ior__ called" + return self + + def __and__(self, val): + print "__and__ called" + def __rand__(self, val): + print "__rand__ called" + def __iand__(self, val): + print "__iand__ called" + return self + + def __xor__(self, val): + print "__xor__ called" + def __rxor__(self, val): + print "__rxor__ called" + def __ixor__(self, val): + print "__ixor__ called" + return self + + def __rshift__(self, val): + print "__rshift__ called" + def __rrshift__(self, val): + print "__rrshift__ called" + def __irshift__(self, val): + print "__irshift__ called" + return self + + def __lshift__(self, val): + print "__lshift__ called" + def __rlshift__(self, val): + print "__rlshift__ called" + def __ilshift__(self, val): + print "__ilshift__ called" + return self + +x = testall() +x + 1 +1 + x +x += 1 + +x - 1 +1 - x +x -= 1 + +x * 1 +1 * x +x *= 1 + +x / 1 +1 / x +x /= 1 + +x % 1 +1 % x +x %= 1 + +x ** 1 +1 ** x +x **= 1 + +x | 1 +1 | x +x |= 1 + +x & 1 +1 & x +x &= 1 + +x ^ 1 +1 ^ x +x ^= 1 + +x >> 1 +1 >> x +x >>= 1 + +x << 1 +1 << x +x <<= 1 +