Пример #1
0
    def test_caching_code(self):
        "Caching: '_code'"

        b,c = Block('a=2'), {}
        b._code
        b.ast = Block('a=3').ast
        b.execute(c)
        self.assertEqual(c['a'], 3)

        b,c = Block('a=2'), {}
        b._code
        b.sub_blocks = [Block('a=3')]
        b.execute(c)
        self.assertEqual(c['a'], 3)

        b,c = Block('a=3; a=2'), {}
        b._code
        b.sub_blocks.pop()
        b.execute(c)
        self.assertEqual(c['a'], 3)

        b,c = Block(''), {}
        b._code
        b.sub_blocks.append(Block('a=3'))
        b.sub_blocks = [Block('a=3')]
        b.execute(c)
        assert 'a' in c
    def test_caching_code(self):
        "Caching: '_code'"

        b, c = Block('a=2'), {}
        b._code
        b.ast = Block('a=3').ast
        b.execute(c)
        self.assertEqual(c['a'], 3)

        b, c = Block('a=2'), {}
        b._code
        b.sub_blocks = [Block('a=3')]
        b.execute(c)
        self.assertEqual(c['a'], 3)

        b, c = Block('a=3; a=2'), {}
        b._code
        b.sub_blocks.pop()
        b.execute(c)
        self.assertEqual(c['a'], 3)

        b, c = Block(''), {}
        b._code
        b.sub_blocks.append(Block('a=3'))
        b.sub_blocks = [Block('a=3')]
        b.execute(c)
        assert 'a' in c
    def test_sub_block_manipulation(self):
        'Sub-block manipulation'

        # A block's structure responds to changes in the 'sub_blocks' list
        b = Block('a; b')
        b.sub_blocks.append(Block('c'))
        self.assertSimilar(b, Block('a; b; c'))
        del b.sub_blocks[1]
        self.assertSimilar(b, Block('a; c'))
        b.sub_blocks.reverse()
        self.assertSimilar(b, Block('c; a'))
        b.sub_blocks[0] = Block('b')
        self.assertSimilar(b, Block('b; a'))
        b.sub_blocks = []
        self.assertSimilar(b, Block())
        b.sub_blocks = []
        self.assertSimilar(b, Block())

        # But if we end up with a block that doesn't decompose, 'sub_blocks'
        # goes away!
        b = Block('a; b; c')
        b.sub_blocks.pop()
        self.assertSimilar(b, Block('a; b'))
        self.assertEqual(len(b.sub_blocks), 2)
        b.sub_blocks.pop()
        self.assertSimilar(b, Block('a'))
        self.assertEqual(len(b.sub_blocks), 1)
        b.sub_blocks = [Block('b')]
        self.assertSimilar(b, Block('b'))
        self.assertEqual(len(b.sub_blocks), 1)
        b.sub_blocks = [Block('a'), Block('b')]
        self.assertSimilar(b, Block('a; b'))
        self.assertEqual(len(b.sub_blocks), 2)

        # Note that some seemingly large things don't (currently) decompose:
        block = Block('for x in l:\n  a = f(x)\n  b = g(a)\n  if t: h()')
        self.assertEqual(len(block.sub_blocks), 1)
Пример #4
0
    def test_sub_block_manipulation(self):
        'Sub-block manipulation'

        # A block's structure responds to changes in the 'sub_blocks' list
        b = Block('a; b')
        b.sub_blocks.append(Block('c'))
        self.assertSimilar(b, Block('a; b; c'))
        del b.sub_blocks[1]
        self.assertSimilar(b, Block('a; c'))
        b.sub_blocks.reverse()
        self.assertSimilar(b, Block('c; a'))
        b.sub_blocks[0] = Block('b')
        self.assertSimilar(b, Block('b; a'))
        b.sub_blocks = []
        self.assertSimilar(b, Block())
        b.sub_blocks = []
        self.assertSimilar(b, Block())

        # But if we end up with a block that doesn't decompose, 'sub_blocks'
        # goes away!
        b = Block('a; b; c')
        b.sub_blocks.pop()
        self.assertSimilar(b, Block('a; b'))
        self.assertEqual(len(b.sub_blocks), 2)
        b.sub_blocks.pop()
        self.assertSimilar(b, Block('a'))
        self.assertEqual(len(b.sub_blocks), 1)
        b.sub_blocks = [Block('b')]
        self.assertSimilar(b, Block('b'))
        self.assertEqual(len(b.sub_blocks), 1)
        b.sub_blocks = [Block('a'), Block('b')]
        self.assertSimilar(b, Block('a; b'))
        self.assertEqual(len(b.sub_blocks), 2)

        # Note that some seemingly large things don't (currently) decompose:
        block = Block('for x in l:\n  a = f(x)\n  b = g(a)\n  if t: h()')
        self.assertEqual(len(block.sub_blocks), 1)
    def test_caching_dep_graph_restrict(self):
        "Caching: '_dep_graph', 'restrict'"

        # '_dep_graph' determines the behavior of 'restrict', so we can test
        # them together.

        b = Block('a=2; b=a; z=a')
        self.assertSimilar(b.restrict(outputs='z'), Block('a=2; z=a'))
        b.sub_blocks = [Block('z=0')]
        self.assertSimilar(b.restrict(outputs='z'), Block('z=0'))

        b = Block('a=2; b=a; z=a')
        self.assertSimilar(b.restrict(outputs='z'), Block('a=2; z=a'))
        b.ast = Block('z=0').ast
        self.assertSimilar(b.restrict(outputs='z'), Block('z=0'))
Пример #6
0
    def test_caching_dep_graph_restrict(self):
        "Caching: '_dep_graph', 'restrict'"

        # '_dep_graph' determines the behavior of 'restrict', so we can test
        # them together.

        b = Block('a=2; b=a; z=a')
        self.assertSimilar(b.restrict(outputs='z'), Block('a=2; z=a'))
        b.sub_blocks = [Block('z=0')]
        self.assertSimilar(b.restrict(outputs='z'), Block('z=0'))

        b = Block('a=2; b=a; z=a')
        self.assertSimilar(b.restrict(outputs='z'), Block('a=2; z=a'))
        b.ast = Block('z=0').ast
        self.assertSimilar(b.restrict(outputs='z'), Block('z=0'))
    def test_tracebacks(self):
        'Tracebacks have correct file names and line numbers'

        # If we want tracebacks to make sense, then the reported file names and
        # line numbers need to associate with the code being executed
        # regardless which block represents and executes the code.

        def test(tb, lineno, filename):
            self.assertEqual(tb.tb_lineno, lineno + 1)
            self.assertEqual(tb.tb_frame.f_code.co_filename, filename)

        def tracebacks():
            "A list of the current exception's traceback objects."
            tb = sys.exc_info()[2]
            l = [tb]
            while tb.tb_next is not None:
                tb = tb.tb_next
                l.append(tb)
            return l

        class File(StringIO, object):
            "Extend StringIO with a 'name' attribute."

            def __init__(self, name, *args, **kw):
                super(File, self).__init__(*args, **kw)
                self.name = name

        a = Block(File('foo/a.py', 'y = x'))
        try:
            a.execute({})
        except NameError as e:
            test(tracebacks()[-1], 1, 'foo/a.py')
        del a

        a = Block(File('foo/a.py', 'import sys\ny = x'))
        try:
            a.execute({})
        except NameError as e:
            test(tracebacks()[-1], 2, 'foo/a.py')
        #del a # (use below in 'Compose')

        b = Block(
            File('foo/b.py',
                 "import re\nl=re.findall('a(.*?)a', 'abacada')\nx = l[2]"))
        try:
            b.execute({})
        except IndexError as e:
            test(tracebacks()[-1], 3, 'foo/b.py')
        #del b # (use below in 'Compose')

        # Compose
        c = Block((a, b))
        try:
            c.execute({})
        except NameError as e:
            test(tracebacks()[-1], 2, 'foo/a.py')
        try:
            c.execute({'x': 0})
        except IndexError as e:
            test(tracebacks()[-1], 3, 'foo/b.py')
        del a, b, c

        # Restrict
        a = Block(File('foo/a.py', 'a = 0\nb = 1\nc = 2/a'))
        try:
            a.restrict(outputs='c').execute({})
        except ZeroDivisionError as e:
            test(tracebacks()[-1], 3, 'foo/a.py')
        del a

        # Throw out a sub-block
        a = Block(File('foo/a.py', 'a = 0\nb = 1\nc = 2/a'))
        a.sub_blocks.pop(1)
        try:
            a.execute({})
        except ZeroDivisionError as e:
            test(tracebacks()[-1], 3, 'foo/a.py')
        del a

        # Swap sub-blocks between blocks
        a = Block(File('foo/a.py', 'a = 0\nb = 1'))
        b = Block(File('foo/b.py', 'c = 2\nd = x'))
        a.sub_blocks = b.sub_blocks
        try:
            a.execute({})
        except NameError as e:
            test(tracebacks()[-1], 2, 'foo/b.py')
        a.sub_blocks = b.sub_blocks[:]
        try:
            a.execute({})
        except NameError as e:
            test(tracebacks()[-1], 2, 'foo/b.py')
        del a, b
Пример #8
0
            test(tracebacks()[-1], 3, 'foo/a.py')
        del a

        # Throw out a sub-block
        a = Block(File('foo/a.py', 'a = 0\nb = 1\nc = 2/a'))
        a.sub_blocks.pop(1)
        try:
            a.execute({})
        except ZeroDivisionError, e:
            test(tracebacks()[-1], 3, 'foo/a.py')
        del a

        # Swap sub-blocks between blocks
        a = Block(File('foo/a.py', 'a = 0\nb = 1'))
        b = Block(File('foo/b.py', 'c = 2\nd = x'))
        a.sub_blocks = b.sub_blocks
        try:
            a.execute({})
        except NameError, e:
            test(tracebacks()[-1], 2, 'foo/b.py')
        a.sub_blocks = b.sub_blocks[:]
        try:
            a.execute({})
        except NameError, e:
            test(tracebacks()[-1], 2, 'foo/b.py')
        del a,b

    def test_construction(self):
        'Construction'
        pass # TODO