mirror of
https://github.com/python/cpython.git
synced 2025-08-25 11:15:02 +00:00
bpo-37115: Support annotations in positional-only arguments (GH-13698)
This commit is contained in:
parent
2f58a84104
commit
a0c01bf136
3 changed files with 57 additions and 4 deletions
|
@ -620,14 +620,22 @@ class GrammarTests(unittest.TestCase):
|
||||||
self.assertEqual(f.__annotations__, {'return': list})
|
self.assertEqual(f.__annotations__, {'return': list})
|
||||||
def f(x: int): pass
|
def f(x: int): pass
|
||||||
self.assertEqual(f.__annotations__, {'x': int})
|
self.assertEqual(f.__annotations__, {'x': int})
|
||||||
|
def f(x: int, /): pass
|
||||||
|
self.assertEqual(f.__annotations__, {'x': int})
|
||||||
|
def f(x: int = 34, /): pass
|
||||||
|
self.assertEqual(f.__annotations__, {'x': int})
|
||||||
def f(*x: str): pass
|
def f(*x: str): pass
|
||||||
self.assertEqual(f.__annotations__, {'x': str})
|
self.assertEqual(f.__annotations__, {'x': str})
|
||||||
def f(**x: float): pass
|
def f(**x: float): pass
|
||||||
self.assertEqual(f.__annotations__, {'x': float})
|
self.assertEqual(f.__annotations__, {'x': float})
|
||||||
def f(x, y: 1+2): pass
|
def f(x, y: 1+2): pass
|
||||||
self.assertEqual(f.__annotations__, {'y': 3})
|
self.assertEqual(f.__annotations__, {'y': 3})
|
||||||
|
def f(x, y: 1+2, /): pass
|
||||||
|
self.assertEqual(f.__annotations__, {'y': 3})
|
||||||
def f(a, b: 1, c: 2, d): pass
|
def f(a, b: 1, c: 2, d): pass
|
||||||
self.assertEqual(f.__annotations__, {'b': 1, 'c': 2})
|
self.assertEqual(f.__annotations__, {'b': 1, 'c': 2})
|
||||||
|
def f(a, b: 1, /, c: 2, d): pass
|
||||||
|
self.assertEqual(f.__annotations__, {'b': 1, 'c': 2})
|
||||||
def f(a, b: 1, c: 2, d, e: 3 = 4, f=5, *g: 6): pass
|
def f(a, b: 1, c: 2, d, e: 3 = 4, f=5, *g: 6): pass
|
||||||
self.assertEqual(f.__annotations__,
|
self.assertEqual(f.__annotations__,
|
||||||
{'b': 1, 'c': 2, 'e': 3, 'g': 6})
|
{'b': 1, 'c': 2, 'e': 3, 'g': 6})
|
||||||
|
@ -636,6 +644,11 @@ class GrammarTests(unittest.TestCase):
|
||||||
self.assertEqual(f.__annotations__,
|
self.assertEqual(f.__annotations__,
|
||||||
{'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9,
|
{'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9,
|
||||||
'k': 11, 'return': 12})
|
'k': 11, 'return': 12})
|
||||||
|
def f(a, b: 1, c: 2, d, e: 3 = 4, f: int = 5, /, *g: 6, h: 7, i=8, j: 9 = 10,
|
||||||
|
**k: 11) -> 12: pass
|
||||||
|
self.assertEqual(f.__annotations__,
|
||||||
|
{'b': 1, 'c': 2, 'e': 3, 'f': int, 'g': 6, 'h': 7, 'j': 9,
|
||||||
|
'k': 11, 'return': 12})
|
||||||
# Check for issue #20625 -- annotations mangling
|
# Check for issue #20625 -- annotations mangling
|
||||||
class Spam:
|
class Spam:
|
||||||
def f(self, *, __kw: 1):
|
def f(self, *, __kw: 1):
|
||||||
|
|
|
@ -99,12 +99,25 @@ def fa(
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def fa(
|
||||||
|
a = 1, # type: A
|
||||||
|
/
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
def fab(
|
def fab(
|
||||||
a, # type: A
|
a, # type: A
|
||||||
b, # type: B
|
b, # type: B
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def fab(
|
||||||
|
a, # type: A
|
||||||
|
/,
|
||||||
|
b, # type: B
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
def fab(
|
def fab(
|
||||||
a, # type: A
|
a, # type: A
|
||||||
b # type: B
|
b # type: B
|
||||||
|
@ -149,6 +162,13 @@ def fav(
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def fav(
|
||||||
|
a, # type: A
|
||||||
|
/,
|
||||||
|
*v, # type: V
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
def fav(
|
def fav(
|
||||||
a, # type: A
|
a, # type: A
|
||||||
*v # type: V
|
*v # type: V
|
||||||
|
@ -161,6 +181,13 @@ def fak(
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def fak(
|
||||||
|
a, # type: A
|
||||||
|
/,
|
||||||
|
**k, # type: K
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
def fak(
|
def fak(
|
||||||
a, # type: A
|
a, # type: A
|
||||||
**k # type: K
|
**k # type: K
|
||||||
|
@ -174,6 +201,14 @@ def favk(
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def favk(
|
||||||
|
a, # type: A
|
||||||
|
/,
|
||||||
|
*v, # type: V
|
||||||
|
**k, # type: K
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
def favk(
|
def favk(
|
||||||
a, # type: A
|
a, # type: A
|
||||||
*v, # type: V
|
*v, # type: V
|
||||||
|
@ -290,18 +325,21 @@ class TypeCommentTests(unittest.TestCase):
|
||||||
for t in tree.body:
|
for t in tree.body:
|
||||||
# The expected args are encoded in the function name
|
# The expected args are encoded in the function name
|
||||||
todo = set(t.name[1:])
|
todo = set(t.name[1:])
|
||||||
self.assertEqual(len(t.args.args),
|
self.assertEqual(len(t.args.args) + len(t.args.posonlyargs),
|
||||||
len(todo) - bool(t.args.vararg) - bool(t.args.kwarg))
|
len(todo) - bool(t.args.vararg) - bool(t.args.kwarg))
|
||||||
self.assertTrue(t.name.startswith('f'), t.name)
|
self.assertTrue(t.name.startswith('f'), t.name)
|
||||||
for c in t.name[1:]:
|
for index, c in enumerate(t.name[1:]):
|
||||||
todo.remove(c)
|
todo.remove(c)
|
||||||
if c == 'v':
|
if c == 'v':
|
||||||
arg = t.args.vararg
|
arg = t.args.vararg
|
||||||
elif c == 'k':
|
elif c == 'k':
|
||||||
arg = t.args.kwarg
|
arg = t.args.kwarg
|
||||||
else:
|
else:
|
||||||
assert 0 <= ord(c) - ord('a') < len(t.args.args)
|
assert 0 <= ord(c) - ord('a') < len(t.args.posonlyargs + t.args.args)
|
||||||
arg = t.args.args[ord(c) - ord('a')]
|
if index < len(t.args.posonlyargs):
|
||||||
|
arg = t.args.posonlyargs[ord(c) - ord('a')]
|
||||||
|
else:
|
||||||
|
arg = t.args.args[ord(c) - ord('a') - len(t.args.posonlyargs)]
|
||||||
self.assertEqual(arg.arg, c) # That's the argument name
|
self.assertEqual(arg.arg, c) # That's the argument name
|
||||||
self.assertEqual(arg.type_comment, arg.arg.upper())
|
self.assertEqual(arg.type_comment, arg.arg.upper())
|
||||||
assert not todo
|
assert not todo
|
||||||
|
|
|
@ -1991,6 +1991,8 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args,
|
||||||
|
|
||||||
if (!compiler_visit_argannotations(c, args->args, names))
|
if (!compiler_visit_argannotations(c, args->args, names))
|
||||||
goto error;
|
goto error;
|
||||||
|
if (!compiler_visit_argannotations(c, args->posonlyargs, names))
|
||||||
|
goto error;
|
||||||
if (args->vararg && args->vararg->annotation &&
|
if (args->vararg && args->vararg->annotation &&
|
||||||
!compiler_visit_argannotation(c, args->vararg->arg,
|
!compiler_visit_argannotation(c, args->vararg->arg,
|
||||||
args->vararg->annotation, names))
|
args->vararg->annotation, names))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue