1# Test various flavors of legal and illegal future statements
2
3import unittest
4from test import support
5import os
6import re
7
8rx = re.compile(r'\((\S+).py, line (\d+)')
9
10def get_error_location(msg):
11    mo = rx.search(str(msg))
12    return mo.group(1, 2)
13
14class FutureTest(unittest.TestCase):
15
16    def check_syntax_error(self, err, basename, lineno, offset=0):
17        self.assertIn('%s.py, line %d' % (basename, lineno), str(err))
18        self.assertEqual(os.path.basename(err.filename), basename + '.py')
19        self.assertEqual(err.lineno, lineno)
20        self.assertEqual(err.offset, offset)
21
22    def test_future1(self):
23        with support.CleanImport('future_test1'):
24            from test import future_test1
25            self.assertEqual(future_test1.result, 6)
26
27    def test_future2(self):
28        with support.CleanImport('future_test2'):
29            from test import future_test2
30            self.assertEqual(future_test2.result, 6)
31
32    def test_future3(self):
33        with support.CleanImport('test_future3'):
34            from test import test_future3
35
36    def test_badfuture3(self):
37        with self.assertRaises(SyntaxError) as cm:
38            from test import badsyntax_future3
39        self.check_syntax_error(cm.exception, "badsyntax_future3", 3)
40
41    def test_badfuture4(self):
42        with self.assertRaises(SyntaxError) as cm:
43            from test import badsyntax_future4
44        self.check_syntax_error(cm.exception, "badsyntax_future4", 3)
45
46    def test_badfuture5(self):
47        with self.assertRaises(SyntaxError) as cm:
48            from test import badsyntax_future5
49        self.check_syntax_error(cm.exception, "badsyntax_future5", 4)
50
51    def test_badfuture6(self):
52        with self.assertRaises(SyntaxError) as cm:
53            from test import badsyntax_future6
54        self.check_syntax_error(cm.exception, "badsyntax_future6", 3)
55
56    def test_badfuture7(self):
57        with self.assertRaises(SyntaxError) as cm:
58            from test import badsyntax_future7
59        self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 53)
60
61    def test_badfuture8(self):
62        with self.assertRaises(SyntaxError) as cm:
63            from test import badsyntax_future8
64        self.check_syntax_error(cm.exception, "badsyntax_future8", 3)
65
66    def test_badfuture9(self):
67        with self.assertRaises(SyntaxError) as cm:
68            from test import badsyntax_future9
69        self.check_syntax_error(cm.exception, "badsyntax_future9", 3, 0)
70
71    def test_badfuture10(self):
72        with self.assertRaises(SyntaxError) as cm:
73            from test import badsyntax_future10
74        self.check_syntax_error(cm.exception, "badsyntax_future10", 3, 0)
75
76    def test_parserhack(self):
77        # test that the parser.c::future_hack function works as expected
78        # Note: although this test must pass, it's not testing the original
79        #       bug as of 2.6 since the with statement is not optional and
80        #       the parser hack disabled. If a new keyword is introduced in
81        #       2.6, change this to refer to the new future import.
82        try:
83            exec("from __future__ import print_function; print 0")
84        except SyntaxError:
85            pass
86        else:
87            self.fail("syntax error didn't occur")
88
89        try:
90            exec("from __future__ import (print_function); print 0")
91        except SyntaxError:
92            pass
93        else:
94            self.fail("syntax error didn't occur")
95
96    def test_multiple_features(self):
97        with support.CleanImport("test.test_future5"):
98            from test import test_future5
99
100    def test_unicode_literals_exec(self):
101        scope = {}
102        exec("from __future__ import unicode_literals; x = ''", {}, scope)
103        self.assertIsInstance(scope["x"], str)
104
105
106
107if __name__ == "__main__":
108    unittest.main()
109