def test_builtin_members():
    code = textwrap.dedent('''
    import pytest
    with pytest.raises(NameError):
      __class__
  ''')
    dynamic_exec(code, {})
def test_super():
    code = textwrap.dedent('''
    def main():
      class Test(object):
        def __init__(self):
          super(Test, self).__init__()
      Test()
    main()

    class Test(object):
      def __init__(self):
        super(Test, self).__init__()
    Test()
  ''')
    dynamic_exec(code, {})

    if sys.version_info[0] >= 3:
        code = textwrap.dedent('''
      def main():
        class Test(object):
          def __init__(self):
            assert __class__ == Test
            super().__init__()
        Test()
      main()

      class Test(object):
        def __init__(self):
          assert __class__ == Test
          super().__init__()
      Test()
    ''')
        dynamic_exec(code, {})
def test_exception_handler():
    code = textwrap.dedent('''
    import sys
    import pytest
    def main():
      try:
        raise Exception
      except Exception as e:
        assert isinstance(e, Exception)
    main()
    with pytest.raises(NameError):
      e

    try:
      raise Exception
    except Exception as e:
      assert isinstance(e, Exception)

    if sys.version_info[0] == 3:
      with pytest.raises(NameError):
        e
    elif sys.version_info[0] == 2:
      assert isinstance(e, Exception)
    else:
      assert False, "Oh boy"
  ''')

    scope = {}
    dynamic_exec(code, scope)
    if sys.version_info[0] == 3:
        assert 'e' not in scope
    elif sys.version_info[0] == 2:
        assert 'e' in scope
    else:
        assert False, "Oh boy"
def test_class_members():
    code = textwrap.dedent('''
    a = 42
    class Test:
      a = 99
      assert a == 99
      def __init__(self):
        assert a == 42
        assert self.a == 99
    assert a == 42
    assert Test.a == 99
  ''')
    dynamic_exec(code, {})
def test_recursion():
    code = textwrap.dedent('''
    def main():
      def rec(n):
        if n > 0:
          rec(n-1)
      rec(5)
    main()

    def rec(n):
      if n > 0:
        rec(n-1)
    rec(5)
  ''')

    dynamic_exec(code, {})
def test_shadowed_deletion():
    code = textwrap.dedent('''
    import pytest
    a = 42
    del a
    with pytest.raises(NameError):
      a
  ''')

    scope = {}

    def resolve(x):
        return scope[x]

    assign = scope.__setitem__
    delete = None

    dynamic_exec(code, LambdaDict(resolve, assign, delete))
    assert 'a' in scope
def test_dynamic_exec():
    assignments = {}
    assignments['assignments'] = lambda: assignments

    def resolve(x):
        return assignments[x]

    assign = assignments.__setitem__
    delete = assignments.__delitem__

    code = textwrap.dedent('''
    from __future__ import print_function
    import pytest
    import os
    import os.path
    import sys
    a, b = 0, 0
    def main(param1):
      global a
      a = 42
      b = 99
      class Foo:
        a = 9999
        b = 9999
      alocal = 'ham'
      tbd = 'delete me!'
      del tbd
      with pytest.raises(NameError):
        tbd
      print("Hello, World from", os.getcwd(), 'a, b', (a, b))
      assert a == 42
      assert b == 99
      assert assignments()['a'] == 42
      assert assignments()['b'] == 0
      for i in range(10):
        pass
      assert 'i' not in assignments(), 'i in assignments'
      assert i == 9
      for j in range(10):
        j = j*2
      assert 'j' not in assignments(), 'j in assignments'
      assert j == 18
      class Test:
        def __init__(self):
          queue = [('ham', 'egg')]
          c, b = queue.pop()
          assert (c, b) == ('ham', 'egg')
          assert alocal == 'ham'
      assert 'Test' not in assignments(), 'Test in assignments'
      assert '__init__' not in assignments(), '__init__ in assignments'
      Test()
      assert (lambda x: x)(42) == 42
      [x for x in range(10)]
      if sys.version_info[0] == 3:
        with pytest.raises(NameError):
          x
      else:
        x
      class ContextManager(object):
        def __enter__(self):
          return 'ContextManager!'
        def __exit__(self,*a):
          pass
      with ContextManager() as value:
        assert value == 'ContextManager!'
      assert value == 'ContextManager!'
      assert 'value' not in assignments()
    main('hello')
    assert a == 42
    assert b == 0
    del a
    with pytest.raises(NameError):
      a
  ''')

    dynamic_exec(code, LambdaDict(resolve, assign, delete))

    for key in ('os', 'b', 'main'):
        assert key in assignments, key

    assert assignments['b'] == 0