예제 #1
0
    def test_name_conflict(self):
        # Shouldn't cause any problems
        foobar1 = MultiMethod('foobar', identity)
        foobar2 = MultiMethod('foobar', identity)

        @foobar1.method(1)
        def foobar1(x):
            return "foobar1"

        @foobar2.method(2)
        def foobar2(selfx):
            return "foobar2"

        self.assertEqual(foobar1(1), "foobar1")
        self.assertEqual(foobar2(2), "foobar2")
예제 #2
0
    def test_basics(self):
        speaksum = MultiMethod('speaksum', lambda *a: sum(a))

        @speaksum.method(2)
        def _speaksum2(x, y, z):
            return "Two"

        @speaksum.method(5)
        def _speaksum5(x, y):
            return "Five"

        @speaksum.method(0)
        def _speaksum0(x, y):
            return "Zero"

        @speaksum.method(Default)
        def _speaksum_d(x, y, z):
            return "Another"

        self.assertEqual(speaksum(1, 1, 0), "Two")
        self.assertEqual(speaksum(3, 2), "Five")
        self.assertEqual(speaksum(9, 8, 2), "Another")
        self.assertEqual(speaksum(3, 5, 6), "Another")
        self.assertEqual(speaksum(-1, 1), "Zero")

        # Too many arguments to method
        self.assertRaises(TypeError, lambda: speaksum(2, 3, 0, 0, 0))
예제 #3
0
    def test_addmethod(self):
        foomethod = MultiMethod('foomethod', identity)

        foomethod.add_method(42, lambda x: "The Answer")
        foomethod.add_method(1024, lambda x: "2^10")
        foomethod.add_method(Default, lambda x: "Nothing")

        self.assertEqual(foomethod(42), "The Answer")
        self.assertEqual(foomethod(1024), "2^10")
        self.assertEqual(foomethod(Default), "Nothing")
예제 #4
0
 def test_unbound_function(self):
     '''
     The value of  pass_self is completely irrelevant for 'unbound' free-functions
     '''
     mm = MultiMethod('mm', type_dispatch, pass_self=True)
     
     @mm.method(Default)
     def mm_default(value):
         return value
     self.assertEqual(mm('hello world'), 'hello world')
예제 #5
0
    def test_falsey_values(self):
        foobar3 = MultiMethod('foobar3', identity)

        @foobar3.method(0)
        def foobar30(x):
            return "zero"

        @foobar3.method(None)
        def foobar3n(x):
            return "none"

        self.assertEqual(foobar3(0), "zero")
        self.assertEqual(foobar3(False), "zero")  # in python False == 0
        self.assertEqual(foobar3(None), "none")
예제 #6
0
    def test_prefer_not_needed_on_same_method(self):
        bar = MultiMethod('bar', type_dispatch)

        @bar.method((object, str))
        @bar.method((str, object))
        def barstr(x, y):
            return "os " + str(x) + str(y)

        @bar.method((int, int))
        def other(x, y):
            return 5

        self.assertEqual(bar("sdf", "dgf"), "os sdfdgf")
        self.assertEqual(bar(3, 6), 5)
예제 #7
0
class Dispatch(unittest.TestCase):

    discount = MultiMethod('tests.Dispatch.discount', lambda name, item: (len(name), type(item)))

    @discount.method((5, ExpensiveItem))
    def dis_25(name, item):
        return 25

    @discount.method((10, ExpensiveItem))
    def dis_30(name, item):
        return 30

    @discount.method((Anything, ExpensiveItem))
    def dis_15(name, item):
        return 15

    @discount.method((5, Item))
    def dis_5(name, item):
        return 5

    discount.prefer((Anything, ExpensiveItem), (5, Item))

    @discount.method(Default)
    def default(name, item):
        return 0

    myitem = BoxedItem()

    def test_hierarchy(self):
        self.assertEqual(self.discount("steve", ExpensiveItem()), 25)
        self.assertEqual(self.discount("chrisjones", ExpensiveItem()), 30)
        self.assertEqual(self.discount("steve", BoxedItem()), 5)
        self.assertEqual(self.discount("joe", Item()), 0)

    def test_anything(self):
        self.assertEqual(self.discount("joe", ExpensiveItem()), 15)

    def test_cache(self):
        self.assertEqual(self.discount("steve", self.myitem), 5)
        #self.assertEqual(self.discount("myverylongname", self.myitem), 30)
        self.assertIn((5, BoxedItem), self.discount.cache)
예제 #8
0
class IsA(unittest.TestCase):
    class Version(object):
        def __init__(self, version):
            self.version = version

        def __str__(self):
            return "<Version %s>" % str(self.version)

    something = MultiMethod('tests.isA.something', lambda v: IsA.Version(v))

    @something.method(Version(25))
    def something_25(foo):
        return 25

    @something.method(Version(30))
    def something_30(foo):
        return 30

    @something.method(Version(15))
    def something_15(foo):
        return 15

    @something.method(Version(5))
    def something_5(foo):
        return 5

    @something.method(Default)
    def default(foo):
        return 0

    @is_a.method((Version, Version))
    def _is_a_version(x, y):
        return x.version >= y.version

    def test_is_a(self):
        self.assertEqual(self.something(31), 30)
        self.assertEqual(self.something(6), 5)
        self.assertEqual(self.something(-10), 0)
        self.assertEqual(self.something(25), 25)
예제 #9
0
class PassSelfMultiMethod(unittest.TestCase):

    mm = MultiMethod('mm', type_dispatch, pass_self=True)

    @mm.method(Default)
    def mm_default(self, value):
        return self, 'default', value

    @mm.method((dict,))
    def mm_int(self, value):
        return self, 'dict', value

    @mm.method((str,))
    def mm_str(self, value):
        return self, 'str', value

    @mm.method((float,))
    def mm_str(self, value):
        return self, 'float', value

    def test_pass_self(self):
        self.assertEqual(self.mm({}), (self, 'dict', {}))
        self.assertEqual(self.mm(12345), (self, 'default', 12345))
        self.assertEqual(self.mm(123.45), (self, 'float', 123.45))
        self.assertEqual(self.mm('foo'), (self, 'str', 'foo'))

    def test_unbound_function(self):
        '''
        The value of  pass_self is completely irrelevant for 'unbound' free-functions
        '''
        mm = MultiMethod('mm', type_dispatch, pass_self=True)
        
        @mm.method(Default)
        def mm_default(value):
            return value
        self.assertEqual(mm('hello world'), 'hello world')
예제 #10
0
    def test_removemethod(self):
        barmethod = MultiMethod('barmethod', identity)

        @barmethod.method(1)
        def barmethod1(x):
            return 123

        self.assertEqual(barmethod(1), 123)

        barmethod.remove_method(1)
        self.assertRaises(Exception, lambda: barmethod(1))

        @barmethod.method(Default)
        def barmethod_d(x):
            return 42

        self.assertEqual(barmethod("whatever"), 42)
        self.assertEqual(barmethod("something"), 42)

        barmethod.remove_method(Default)
        self.assertRaises(Exception, lambda: barmethod("whatever"))
        self.assertRaises(Exception, lambda: barmethod(1))
예제 #11
0
class Prefer(unittest.TestCase):

    pref = MultiMethod('pref', type_dispatch)

    class MyList(list):
        pass

    @pref.method(Default)
    def pd(x, y):
        return "default"

    @pref.method((Iterable, object))
    def pio(x, y):
        return "io"

    @pref.method((object, Iterable))
    def poi(x, y):
        return "oi"

    @pref.method((list, object))
    def plo(x, y):
        return "lo"

    @pref.method((object, list))
    def pol(x, y):
        return "ol"

    @pref.method((Iterable, list))
    def pil(x, y):
        return "il"

    @pref.method((list, Iterable))
    def pli(x, y):
        return "li"

    @pref.method((str, object))
    def pso(x, y):
        return "so"

    @pref.method((object, str))
    def pos(x, y):
        return "os"

    #pref.prefer((str, object), (object, str))
    pref.prefer((object, Iterable), (Iterable, object))

    def test_ambiguous(self):
        self.assertEqual(self.pref(5, 6), "default")
        self.assertRaises(DispatchException, self.pref, "sdf", "dgf")

    # def test_prefer(self):
    #     self.assertEqual(self.pref(Prefer.MyList(), Prefer.MyList()), "lo")

    def test_prefer_not_needed_on_same_method(self):
        bar = MultiMethod('bar', type_dispatch)

        @bar.method((object, str))
        @bar.method((str, object))
        def barstr(x, y):
            return "os " + str(x) + str(y)

        @bar.method((int, int))
        def other(x, y):
            return 5

        self.assertEqual(bar("sdf", "dgf"), "os sdfdgf")
        self.assertEqual(bar(3, 6), 5)