How to fix "SyntaxError: positional argument follows keyword argument" in Python
Tags: python, syntaxerror, programming
Published: 2023-02-01 16:10:21



> ✋ **Update:** This post was originally published on my blog [decodingweb.dev](https://www.decodingweb.dev/solved-syntaxerror-unterminated-triple-quoted-string-literal-python) as part of the [Python Syntax Errors](https://www.decodingweb.dev/category/python-syntaxerror) series. You can read the latest version on my blog for a 💯 user experience.

Python raises the “SyntaxError: positional argument follows keyword argument” error if you place one or more keyword arguments (e.g., `age=35, name=John`) before your positional arguments (e.g., `35, John`) in a function call.

Based on Python syntax, keyword arguments must follow positional arguments and not the other way around:

```python
def greet(name, message):
  return f'Hi {name}, {message}!'

# 🚫 SyntaxError
print(greet(name='John', 'Welcome'))
```

Here's what the error looks like:

```
File /dwd/sandbox/test.py, line 5
  print(greet(name='John', 'Welcome!'))
                                      ^
SyntaxError: positional argument follows keyword argument
```

In the above example, the keyword argument `name='John'` shouldn't appear before the positional argument `'Welcome'` when calling the `greet()` function.

## How to fix SyntaxError: positional argument follows keyword argument

To fix this syntax error, you have three options:

<u>1. Pass keyword arguments after positional arguments</u> 
<u>2. Pass all the arguments as positional arguments</u>
<u>3. Pass all the arguments as keyword arguments</u>

Let's explore each approach with some examples.

**1. Pass keyword arguments after positional arguments:** Based on Python syntax, keyword arguments must follow positional arguments:


```python
def greet(name, message):
  return f'Hi {name}, {message}!'

# ✅ Correrct
print(greet('John', message='Welcome'))

# 🚫 Wrong
print(greet(name='John', 'Welcome'))
```

Even if only one keyword argument appears before a positional argument, you'll get the "SyntaxError: positional argument follows keyword argument" error.

**2. Pass all the arguments as positional arguments:** In this approach, we need to make sure we pass the values in the order they appear in the function's definition:

```python
def greet(name, message):
  return f'Hi {name}, {message}!'

# ✅ Correct
print(greet('John', 'Welcome'))
# expected output: Hi John, Welcome!

# 🚫 Wrong
print(greet('Welcome', 'John'))
# unexpected output: Hi Welcome!, John
```

**3. Pass all the arguments as keyword arguments:** Unlike positional arguments, the order doesn't matter when passing keyword arguments. However, names must be correct:

```python
def greet(name, message):
  return f'Hi {name}, {message}!'

# ✅ Correct
print(greet(message='Welcome!', name='John'))
```

A quick refresher on positional and keyword arguments
When calling a function, we can either pass the arguments as positional or keyword arguments - or a combination of both.

Here are a few examples:

```python
# 2 positional arguments
greet('John', 'Welcome!')

# 2 keyword arguments
greet(message='Welcome!', name='John')

# 1 positional argument, 1 keyword argument
greet('John', message='Welcome!')
```

If we pass arguments as positional arguments, we need to be aware of their order because Python will map the values to variables in the order they appear in the function's definition.

```python
def greet(name, message):
   return f'Hi {name}, {message}!'

# ✅ Correct
print(greet('John', 'welcome!'))
```

The order doesn't matter with keyword arguments, though.

However, you need to provide the parameter name as it appears in the function's definition.

If you want to use keyword arguments, remember to place them after the positional ones. Otherwise, Python's interpreter raises the "SyntaxError: positional argument follows keyword argument" error.

You can also have your function accept positional-only arguments. You can do that by placing a `/` after your parameters:

```python
# ✅ Correct
def greet(name, message, /):
   return f'Hi {name}, {message}!'
```

As a result, if you invoke the function with a keyword argument, Python raises a TypeError.

This is good practice when making APIs; Using [positional-only](https://peps.python.org/pep-0570/) arguments in APIs helps you avoid breaking changes if a parameter name is modified in the future.

Alternatively, you can make your arguments [keyword-only](https://peps.python.org/pep-3102/) by placing a `*` before them. 

```python
# ✅ Correct
def greet(name, *, message):
   return f'Hi {name}, {message}!'
```

You can also combine the two to make some arguments positional-only, some keyword-only, and some both of them (the standard form):

```python
# ✅ Correct
def greet(name, /, age *, message):
   return f'Hi {name}, {message}!'
```

In the above example, the name parameter must be passed as a positional argument (must be the first argument passed), and age is a standard parameter, meaning it can be a positional or keyword argument. And message must be a keyword argument since it's preceded by a `*`.

Here's the [blueprint from Python.org](https://peps.python.org/pep-0570/#how-to-teach-this)


```
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
      -----------    ----------     ----------
        |             |                  |
        |        Positional or keyword   |
        |                                - Keyword only
         -- Positional only
```

How do I know when to use positional arguments, and when to use keyword arguments? You may ask.

Here's the rule of thumb:

You can use positional arguments when the order of the parameters matters when calling the function. 

Keyword-only arguments are helpful when the argument names are meaningful, and the function's behavior is easier to understand with explicit names, or when you want to avoid people depending on the order of the arguments.

And that's how you'd handle the "SyntaxError: positional argument follows keyword argument" error in Python.

Alright, I think it does it. I hope this quick guide helped you solve your problem.

Thanks for reading.