This is the relevant bit from the grammar:
arglist: (argument ',')* (argument [',']
|'*' test (',' argument)* [',' '**' test]
|'**' test)
The first line here allows putting a comma after the last parameter when not using varargs/kwargs (this is why your first example works). However, you are not allowed to place a comma after the kwargs parameter if it is specified, as shown in the second and third lines.
By the way, here is an interesting thing shown by the grammar:
These are both legal:
f(a=1, b=2, c=3,)
f(*v, a=1, b=2, c=3)
but this is not:
f(*v, a=1, b=2, c=3,)
It makes sense not to allow a comma after **kwargs
, since it must always be the last parameter. I don't know why the language designers chose not to allow my last example though - maybe an oversight?