PEP 3107 - Function Annotations thanks to Tony Lownds
diff --git a/Lib/test/output/test_tokenize b/Lib/test/output/test_tokenize
index 4a3d58c..a46824d 100644
--- a/Lib/test/output/test_tokenize
+++ b/Lib/test/output/test_tokenize
@@ -682,4 +682,20 @@
 177,11-177,15:	NAME	'pass'
 177,15-177,16:	NEWLINE	'\n'
 178,0-178,1:	NL	'\n'
-179,0-179,0:	ENDMARKER	''
+179,0-179,1:	OP	'@'
+179,1-179,13:	NAME	'staticmethod'
+179,13-179,14:	NEWLINE	'\n'
+180,0-180,3:	NAME	'def'
+180,4-180,7:	NAME	'foo'
+180,7-180,8:	OP	'('
+180,8-180,9:	NAME	'x'
+180,9-180,10:	OP	':'
+180,10-180,11:	NUMBER	'1'
+180,11-180,12:	OP	')'
+180,12-180,14:	OP	'->'
+180,14-180,15:	NUMBER	'1'
+180,15-180,16:	OP	':'
+180,17-180,21:	NAME	'pass'
+180,21-180,22:	NEWLINE	'\n'
+181,0-181,1:	NL	'\n'
+182,0-182,0:	ENDMARKER	''
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index 11623ec..914f1d9 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -151,9 +151,9 @@
 
 #### EVERYTHING BELOW IS GENERATED #####
 exec_results = [
-('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], None, [], []), [('Pass', (1, 9))], [])]),
+('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, [], None, None, [], []), [('Pass', (1, 9))], [], None)]),
 ('Module', [('ClassDef', (1, 0), 'C', [], [('Pass', (1, 8))])]),
-('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], None, [], []), [('Return', (1, 8), ('Num', (1, 15), 1))], [])]),
+('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, [], None, None, [], []), [('Return', (1, 8), ('Num', (1, 15), 1))], [], None)]),
 ('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]),
 ('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]),
 ('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Num', (1, 5), 1))]),
@@ -180,13 +180,13 @@
 ('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])),
 ('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))),
 ('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))),
-('Expression', ('Lambda', (1, 0), ('arguments', [], None, [], None, [], []), ('Name', (1, 7), 'None', ('Load',)))),
+('Expression', ('Lambda', (1, 0), ('arguments', [], None, None, [], None, None, [], []), ('Name', (1, 7), 'None', ('Load',)))),
 ('Expression', ('Dict', (1, 0), [('Num', (1, 2), 1)], [('Num', (1, 4), 2)])),
 ('Expression', ('ListComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])),
 ('Expression', ('GeneratorExp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])),
 ('Expression', ('Compare', (1, 0), ('Num', (1, 0), 1), [('Lt',), ('Lt',)], [('Num', (1, 4), 2), ('Num', (1, 8), 3)])),
 ('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Num', (1, 2), 1), ('Num', (1, 4), 2)], [('keyword', 'c', ('Num', (1, 8), 3))], ('Name', (1, 11), 'd', ('Load',)), ('Name', (1, 15), 'e', ('Load',)))),
-('Expression', ('Num', (1, 0), 10L)),
+('Expression', ('Num', (1, 0), 10)),
 ('Expression', ('Str', (1, 0), 'string')),
 ('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))),
 ('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))),
diff --git a/Lib/test/test_compiler.py b/Lib/test/test_compiler.py
index 783a34c..2ecd093 100644
--- a/Lib/test/test_compiler.py
+++ b/Lib/test/test_compiler.py
@@ -115,6 +115,24 @@
         dct = {}
         exec(c, dct)
         self.assertEquals(dct.get('result'), 3)
+        c = compiler.compile('def g(a):\n'
+                             '    def f(): return a + 2\n'
+                             '    return f()\n'
+                             'result = g(1)',
+                             '<string>',
+                             'exec')
+        dct = {}
+        exec(c, dct)
+        self.assertEquals(dct.get('result'), 3)
+        c = compiler.compile('def g((a, b)):\n'
+                             '    def f(): return a + b\n'
+                             '    return f()\n'
+                             'result = g((1, 2))',
+                             '<string>',
+                             'exec')
+        dct = {}
+        exec(c, dct)
+        self.assertEquals(dct.get('result'), 3)
 
     def testGenExp(self):
         c = compiler.compile('list((i,j) for i in range(3) if i < 3'
@@ -123,6 +141,22 @@
                              'eval')
         self.assertEquals(eval(c), [(0, 3), (1, 3), (2, 3)])
 
+    def testFuncAnnotations(self):
+        testdata = [
+            ('def f(a: 1): pass', {'a': 1}),
+            ('''def f(a, (b:1, c:2, d), e:3=4, f=5,
+                    *g:6, h:7, i=8, j:9=10, **k:11) -> 12: pass
+             ''', {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9,
+                   'k': 11, 'return': 12}),
+        ]
+        for sourcecode, expected in testdata:
+            # avoid IndentationError: unexpected indent from trailing lines
+            sourcecode = sourcecode.rstrip()+'\n'
+            c = compiler.compile(sourcecode, '<string>', 'exec')
+            dct = {}
+            exec(c, dct)
+            self.assertEquals(dct['f'].func_annotations, expected)
+
 
 NOLINENO = (compiler.ast.Module, compiler.ast.Stmt, compiler.ast.Discard)
 
@@ -167,10 +201,11 @@
 
 ###############################################################################
 
-def test_main():
+def test_main(all=False):
     global TEST_ALL
-    TEST_ALL = test.test_support.is_resource_enabled("compiler")
+    TEST_ALL = all or test.test_support.is_resource_enabled("compiler")
     test.test_support.run_unittest(CompilerTest)
 
 if __name__ == "__main__":
-    test_main()
+    import sys
+    test_main('all' in sys.argv)
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index f4a0478..34c550e 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -138,16 +138,22 @@
         x = eval('1, 0 or 1')
 
     def testFuncdef(self):
-        ### 'def' NAME parameters ':' suite
-        ### parameters: '(' [varargslist] ')'
-        ### varargslist: (fpdef ['=' test] ',')*
-        ###           ('*' (NAME|',' fpdef ['=' test]) [',' ('**'|'*' '*') NAME]
-        ###            | ('**'|'*' '*') NAME)
-        ###            | fpdef ['=' test] (',' fpdef ['=' test])* [',']
-        ### fpdef: NAME | '(' fplist ')'
-        ### fplist: fpdef (',' fpdef)* [',']
-        ### arglist: (argument ',')* (argument | *' test [',' '**' test] | '**' test)
-        ### argument: [test '='] test   # Really [keyword '='] test
+        ### [decorators] 'def' NAME parameters ['->' test] ':' suite
+        ### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
+        ### decorators: decorator+
+        ### parameters: '(' [typedargslist] ')'
+        ### typedargslist: ((tfpdef ['=' test] ',')*
+        ###                ('*' [tname] (',' tname ['=' test])* [',' '**' tname] | '**' tname)
+        ###                | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
+        ### tname: NAME [':' test]
+        ### tfpdef: tname | '(' tfplist ')'
+        ### tfplist: tfpdef (',' tfpdef)* [',']
+        ### varargslist: ((vfpdef ['=' test] ',')*
+        ###              ('*' [vname] (',' vname ['=' test])*  [',' '**' vname] | '**' vname)
+        ###              | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
+        ### vname: NAME
+        ### vfpdef: vname | '(' vfplist ')'
+        ### vfplist: vfpdef (',' vfpdef)* [',']
         def f1(): pass
         f1()
         f1(*())
@@ -294,6 +300,28 @@
         pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200)
         pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100)
 
+        # argument annotation tests
+        def f(x) -> list: pass
+        self.assertEquals(f.func_annotations, {'return': list})
+        def f(x:int): pass
+        self.assertEquals(f.func_annotations, {'x': int})
+        def f(*x:str): pass
+        self.assertEquals(f.func_annotations, {'x': str})
+        def f(**x:float): pass
+        self.assertEquals(f.func_annotations, {'x': float})
+        def f(x, y:1+2): pass
+        self.assertEquals(f.func_annotations, {'y': 3})
+        def f(a, (b:1, c:2, d)): pass
+        self.assertEquals(f.func_annotations, {'b': 1, 'c': 2})
+        def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6): pass
+        self.assertEquals(f.func_annotations,
+                          {'b': 1, 'c': 2, 'e': 3, 'g': 6})
+        def f(a, (b:1, c:2, d), e:3=4, f=5, *g:6, h:7, i=8, j:9=10,
+              **k:11) -> 12: pass
+        self.assertEquals(f.func_annotations,
+                          {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9,
+                           'k': 11, 'return': 12})
+
     def testLambdef(self):
         ### lambdef: 'lambda' [varargslist] ':' test
         l1 = lambda : 0
diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py
index be6c18d..de6e888 100644
--- a/Lib/test/test_tokenize.py
+++ b/Lib/test/test_tokenize.py
@@ -219,5 +219,15 @@
     if verbose:
         print 'finished'
 
+def test_rarrow():
+    """
+    This function exists solely to test the tokenization of the RARROW
+    operator.
+
+    >>> tokenize(iter(['->']).next)   #doctest: +NORMALIZE_WHITESPACE
+    1,0-1,2:\tOP\t'->'
+    2,0-2,0:\tENDMARKER\t''
+    """
+
 if __name__ == "__main__":
     test_main()
diff --git a/Lib/test/tokenize_tests.txt b/Lib/test/tokenize_tests.txt
index 1facfc1..b1aa020 100644
--- a/Lib/test/tokenize_tests.txt
+++ b/Lib/test/tokenize_tests.txt
@@ -176,3 +176,6 @@
 @staticmethod
 def foo(): pass
 
+@staticmethod
+def foo(x:1)->1: pass
+