Skip to content

Commit d9967a9

Browse files
Merge 6579d90 into d199905
2 parents d199905 + 6579d90 commit d9967a9

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

mutable_primitives.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,33 @@
11
''' Mutable Primitives '''
2-
#from types import FunctionType
2+
from types import FunctionType
3+
import sys
34

45

56
EQUALITY_FUNCTIONS = [
67
'__eq__',
78
'__ne__',
89
]
910

11+
MATH_FUNCTIONS = [
12+
('add', '+'),
13+
('sub', '-'),
14+
('mul', '*'),
15+
# Division is handled differently in python2 and python3
16+
]
17+
if sys.version_info[0] < 3:
18+
MATH_FUNCTIONS.append(('div', '/'))
19+
else:
20+
MATH_FUNCTIONS.extend([
21+
('floordiv', '//'),
22+
('truediv', '/'),
23+
])
24+
25+
26+
FORMATS = {
27+
'': 'return self.val {} other',
28+
'r': 'return other {} self.val',
29+
'i': 'self.val {}= other',
30+
}
1031

1132

1233
class Mutable(object): # pylint: disable=useless-object-inheritance
@@ -35,15 +56,21 @@ def __repr__(self):
3556
return '<{}>'.format(self)
3657

3758

38-
3959
class Bool(Mutable):
4060
''' Mutable version of float '''
4161

4262

43-
4463
class MutableNumeric(Mutable):
4564
''' Base class for mutable numeric primitives '''
4665

66+
for fmt, basecode in FORMATS.items():
67+
for (basename, op) in MATH_FUNCTIONS:
68+
name = '__{}{}__'.format(fmt, basename)
69+
code = 'def {}(self, other): {}'.format(name, basecode.format(op))
70+
code = compile(code, "<string>", "exec")
71+
locals()[name] = FunctionType(code.co_consts[0], globals(), name)
72+
del code, name, op
73+
4774

4875
class Int(MutableNumeric):
4976
''' Mutable version of int '''

test_mutable_primitives.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import sys
12
import unittest
23

34
from mutable_primitives import (
@@ -13,3 +14,14 @@ def test_eq(self):
1314

1415
assert Int(5) != 6
1516
assert 6 != Int(5)
17+
18+
assert Int(6) + 5 == 11
19+
assert 5 + Int(6) == 11
20+
assert 5 - Int(6) == -1
21+
22+
assert 5 - Int(6) == 5 - 6
23+
assert 5 * Int(6) == 5 * 6
24+
25+
assert 18 / Int(5) == 18 / 5
26+
if sys.version_info[0] >= 3:
27+
assert 18 / Int(5) == 18 / 5

0 commit comments

Comments
 (0)