Every language has a set of rules defining how to properly form valid constructs; this is referred to as the language’s syntax. When you’re just learning how to code, experiencing syntax errors is part of the process. Beginners often struggle to understand the syntax rules and frequently encounter typographical errors and misplaced symbols.
Syntax errors are a common part of everyone’s coding journey, but the sooner you understand why they occur, the sooner you can fix them.
In this article, you’ll learn about different syntax errors in Python and how to avoid them.
Syntax Errors in Python
In any programming language, failing to follow the syntax rules most likely results in a syntax error, and your code can’t run.
In Python, the Python Interpreter reads and executes your Python code, acting as a translator between high-level Python and the low-level machine language your computer understands. If your code doesn’t follow Python’s syntax rules, the interpreter can’t process the code.
When the Python interpreter encounters a syntax error, it halts and displays an error message. This message includes a traceback to the line of code that caused the error, along with an indicator pointing to the earliest point in the line where the error was detected.
The interpreter tries to provide you with as much relevant information as possible to help you diagnose and fix the issue, so make sure you read your error messages carefully.
Syntax errors in Python are all about structure—they occur when a command violates the language’s grammatical rules. For instance, in English, a sentence must always begin with a capital letter and end with a punctuation mark. Similarly, in Python, a statement must always end with a new line and blocks of code (like those in if
statements or loops) that must be indented correctly.
If you’re familiar with runtime errors, you may be wondering how they differ from syntax errors. Syntax errors prevent a program from running. Runtime errors occur after the program has started running.
Exploring Different Types of Syntax Errors
Because Python has a lot of syntax rules, a lot of syntax errors can also occur. In this section, you’ll learn about several common errors and solutions.
Misplaced, Missing, or Mismatched Punctuation
Python uses various punctuation marks to understand the structure of your code. You need to make sure each of these punctuation marks is placed correctly and matched with the corresponding punctuation to avoid syntax errors.
For instance, you should always use parentheses (()), brackets ([]), and braces ({}) in matching pairs. That means if you open one, you must close it.
In the following example, a curly brace is used to define an object, but it isn’t closed:
# Incorrect
proxies = {
'http': proxy_url,
'https': proxy_url
If you try to run this, the interpreter throws a SyntaxError
:
File "python-syntax-errors.py", line 2
proxies = {
^
SyntaxError: '{' was never closed
As mentioned previously, the Python interpreter usually provides a descriptive error message. Here, you’re given the name of the file where the error occurred, the line number where it occurred, and an arrow pointing to where in the code the error was detected. You’re also told that '{' was never closed
.
With all this information, you can easily decipher that you need to close the curly bracket to fix the problem:
# Correct
proxies = {
'http': proxy_url,
'https': proxy_url
} # Closed a curly bracket
Another punctuation mark that often causes issues is quotes (’ or “). Python, like many other programming languages, uses quotes to define strings. You must use the same type of quote to open and close a string:
# Incorrect
host = "brd.superproxy.io'
Mixing up single and double quotes results in a syntax error:
File "python-syntax-errors.py", line 2
host = "brd.superproxy.io'
^
SyntaxError: unterminated string literal (detected at line 2)
Here, the interpreter tells you that you haven’t terminated the string literal in the second line:
# Correct
host = "brd.superproxy.io"
You can use a pair of single quotes to get the same result.
In some scenarios, you may need to use single and double quotes in a string. In that case, you can use triple quotes like this:
quote = """He said, "It's the best proxy service you can find!", and showed me this provider."""
In Python, commas are used to separate items in a list, tuple, or function argument. Missing a comma can lead to unexpected results:
# Incorrect
proxies= [
{"http": "http://123.456.789.1:8080", "https": "https://123.456.789.1:8080"}
{"http": "http://98.765.432.1:3128", "https": "https://98.765.432.1:3128"}
{"http": "http://192.168.1.1:8080", "https": "https://192.168.1.1:8080"}
]
Running this code results in the following error message:
File "python-syntax-errors.py", line 3
{"http": "http://123.456.789.1:8080", "https": "https://123.456.789.1:8080"}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
While error messages are made as helpful as they can be, they might not always suggest perfect solutions. This snippet misses four commas, but the error message picks out only the first instance. To fix this, you should look at the code around the error message and find other places where you might have forgotten to place a comma:
# Correct
proxies = [
{"http": "http://123.456.789.1:8080", "https": "https://123.456.789.1:8080"},
{"http": "http://98.765.432.1:3128", "https": "https://98.765.432.1:3128"},
{"http": "http://192.168.1.1:8080", "https": "https://192.168.1.1:8080"}
]
In contrast to commas, colons are used to start a new block of code (like in an if
statement or for
loop):
import requests
from bs4 import BeautifulSoup
# Incorrect
response = requests.get('https://example.com')
if response.status_code == 200
soup = BeautifulSoup(response.content, 'html.parser')
title = soup.title.text
print(title)
)
Forgetting a colon results in the following syntax error:
if response.status_code == 200
^
SyntaxError: expected ':'
From this error message, it’s easy to determine that there’s a colon missing, and you can add it in the suggested place to fix the issue:
import requests
from bs4 import BeautifulSoup
# Correct
response = requests.get('https://example.com')
if response.status_code == 200:
soup = BeautifulSoup(response.content, 'html.parser')
title = soup.title.text
print(title)
Misspelled, Misplaced, or Missing Python Keywords
Python keywords are special words reserved for specific meanings and uses, and you can’t use them as variable names. If you misspell, misplace, or forget to use a keyword, the interpreter raises an error.
For instance, if you’re trying to import the requests
and pprint
modules into your web scraping project, you may accidentally misspell the import
keyword:
# Incorrect
improt requests
import pprint
This misspelling causes the interpreter to raise the following invalid syntax
error:
File "python-syntax-errors.py", line 2
improt requests
^^^^^^^^
SyntaxError: invalid syntax
Unfortunately, this error message is vague, so you have to do a little work to figure out what went wrong. You can see the arrows in the error message point to requests
; that’s where the interpreter first detected a syntax error. Since misspelling the name of a module doesn’t raise a syntax error, the only other option is that you misspelled the import
keyword.
A simple correction of the word import
fixes the error:
# Correct
import requests
import pprint
It’s also possible to mess up the from ... import …
statement like this:
import BeautifulSoup from bs4
Although it seems okay, running the preceding code results in an error because the from
keyword should go before import
:
File "python-syntax-errors.py", line 2
import BeautifulSoup from bs4
^^^^
SyntaxError: invalid syntax
Switching from
and import
fixes the issue:
from bs4 import BeautifulSoup
Missing a keyword is another issue you’ll probably face when coding in Python. This type of error is a bit more subtle than the other errors mentioned because missing a keyword in Python can throw different errors.
If you forget to include the return
keyword in a function that is supposed to return a value, the function doesn’t behave as expected:
def fetch_data():
response = requests.get('https://example.com')
soup = BeautifulSoup(response.content, 'html.parser')
data = soup.find_all('div', class_='data')
# Missing a return statement here
data = fetch_data()
This does not throw a syntax error, but the function returns None
instead of the expected result. Adding the return
keyword fixes the preceding code:
def fetch_data():
response = requests.get('https://example.com')
soup = BeautifulSoup(response.content, 'html.parser')
data = soup.find_all('div', class_='data')
return data
data = fetch_data()
If you forget the def
keyword when defining a function, you encounter a syntax error:
# Missing the `def` keyword
fetch_data():
response = requests.get('https://example.com')
soup = BeautifulSoup(response.content, 'html.parser')
data = soup.find_all('div', class_='data')
return data
data = fetch_data()
The preceding code raises a syntax error because the interpreter expects a keyword before the function name:
File "python-syntax-errors.py", line 1
fetch_data():
^
SyntaxError: invalid syntax
Adding the def
keyword resolves the error:
def fetch_data():
response = requests.get('https://example.com')
soup = BeautifulSoup(response.content, 'html.parser')
data = soup.find_all('div', class_='data')
return data
data = fetch_data()
If you forget the if
keyword in a conditional statement, the interpreter raises an error because the interpreter expects a keyword before the condition:
import requests
from bs4 import BeautifulSoup
response = requests.get('https://example.com')
# Missing the if keyword
response.status_code == 200:
soup = BeautifulSoup(response.content, 'html.parser')
title = soup.title.text
print(title)
File "python-syntax-errors.py", line 6
response.status_code == 200:
^
SyntaxError: invalid syntax
You just need to include the if
keyword to fix this issue:
import requests
from bs4 import BeautifulSoup
response = requests.get('https://example.com')
if response.status_code == 200:
soup = BeautifulSoup(response.content, 'html.parser')
title = soup.title.text
print(title)
Note that these are just a few examples of missing keywords in Python. Missing keywords can throw other kinds of errors, too, so be extra careful.
Incorrect Use of the Assignment Operator
In Python, the =
symbol is used for assignments, and ==
is used for comparisons. Mixing these two symbols up can lead to a syntax error:
import requests
from bs4 import BeautifulSoup
# Incorrect
response = requests.get('https://example.com', proxies=proxies)
if response = requests.get('https://example.com/data', proxies=proxies):
soup = BeautifulSoup(response.content, 'html.parser')
data = soup.find_all('div', class_='data')
for item in data:
print(item.text)
else:
print("Failed to retrieve data")
In the previous code, the interpreter correctly detects what caused the problem:
File "python-syntax-errors.py", line 5
if response = requests.get('https://example.com/data', proxies=proxies)
^^^^^^
In this instance, you’re trying to verify that your response is the same as the response to the request.get()
method. That means you need to replace the assignment operator in the if
statement with the comparison operator:
import requests
from bs4 import BeautifulSoup
# Correct
response = requests.get('https://example.com', proxies=proxies)
# Change in the following line
if response == requests.get('https://example.com/data', proxies=proxies):
soup = BeautifulSoup(response.content, 'html.parser')
data = soup.find_all('div', class_='data')
for item in data:
print(item.text)
else:
print("Failed to retrieve data")
Indentation Errors
Python uses indentation to define blocks of code. If your code is not indented correctly, the interpreter can’t distinguish the content of the code block and raises an IndentationError
:
# Incorrect
async with async_playwright() as playwright:
await run(playwright)
As you can see in the previous code, there’s no indentation after the definition of a block (colon), so when you run this, you get the following error message:
File "python-syntax-errors.py", line 2
await run(playwright)
^
IndentationError: expected an indented block after the with statement on line 1
To fix this problem, follow Python’s syntax rules and indent the code block correctly:
# Correct
async with async_playwright() as playwright:
await run(playwright)
Issues with Variable Declarations
Variable names in Python must start with a letter or an underscore, and they can contain only letters, numbers, and underscores. Additionally, Python is case-sensitive, so myvariable
, myVariable
, and MYVARIABLE
are all different variables.
Your variable names can never start with anything except a letter or an underscore. The following variable name starts with 1
, which does not comply with Python’s syntax rules:
# Incorrect
1st_port = 22225
When you run the preceding code, the interpreter raises a SyntaxError
:
File "python-syntax-errors.py", line 2
1st_port = 1
^
SyntaxError: invalid decimal literal
To fix this, you must start the variable name with a letter or an underscore. Any of the following options can work:
# Correct
first_port = 22225
port_no_1 = 22225
Function Definition and Call Errors
When defining a function, you must use the def
keyword, followed by the function name, parentheses, and a colon. When calling a function, you must use its name followed by parentheses. Forgetting any of these elements raises a syntax error:
import requests
from bs4 import BeautifulSoup
# Incorrect
def fetch_data
response = requests.get('https://example.com')
soup = BeautifulSoup(response.content, 'html.parser')
data = soup.find_all('div', class_='data')
return data
# Incorrect
data = fetch_data
Here, three elements are missing, and each of them causes a separate syntax error. To fix these errors, you need to add parentheses and a colon after the function name fetch_data
. You also need to add parentheses after the function call on the last line of the code block, like this:
import requests
from bs4 import BeautifulSoup
# Corrected
def fetch_data():
response = requests.get('https://example.com')
soup = BeautifulSoup(response.content, 'html.parser')
data = soup.find_all('div', class_='data')
return data
# Corrected
data = fetch_data()
Note that missing parentheses and colons in the function definition always causes a syntax error. However, the interpreter doesn’t pick up whether you forgot the parentheses when calling a function (fetch_data()
). In that case, it doesn’t necessarily throw an exception, which can lead to unexpected behavior.
Best Practices to Help You Avoid Syntax Errors
Writing error-free code is a skill that comes with practice. Understanding and implementing the following best practices can help you avoid common syntax errors.
Proactive Strategies
The best way to deal with syntax errors is to try and prevent them in the first place.
Before you start working on a project, you should be familiar with the most common syntax rules of the language you’re coding in.
Use a Code Editor with Syntax Highlighting and Indentation Checking
A good code editor is a great partner when it comes to avoiding syntax errors. Most modern code editors offer features like syntax highlighting and indentation checking, which can help you spot errors before you run your code.
For example, in the following illustration, there’s a red mark at the end of the if response.status_code == 200
line that suggests that there’s an error since there’s no colon:
Follow Consistent Coding Style Guidelines
As with most things, consistency is key when it comes to writing clean, error-free code. Aim to follow a consistent coding style. This makes your code easier to read and understand, which in turn makes it easier to spot and fix errors.
In Python, the PEP 8 Style Guide is widely accepted as the standard for coding style. It provides guidelines for things like variable naming, indentation, and the use of white space.
Write Code in Small, Well-Defined Functions
Breaking your code down into small, well-defined functions can make it easier to manage and debug.
Each function should have a single, clear purpose. If a function does too many things, it can become difficult to understand and debug. For example, take a look at the following scrape_and_analyze()
function:
import requests
from bs4 import BeautifulSoup
from textblob import TextBlob
def scrape_and_analyze():
url = "https://example.com/articles"
response = requests.get(url)
soup = BeautifulSoup(response.content, "html.parser")
titles = soup.find_all("h2", class_="article-title")
sentiments = []
for title in titles:
title_text = title.get_text()
blob = TextBlob(title_text)
sentiment = blob.sentiment.polarity
sentiments.append(sentiment)
return sentiments
print(scrape_and_analyze())
In this example, it would be more readable to break down this function into multiple smaller ones, each executing a smaller, more manageable portion of code:
import requests
from bs4 import BeautifulSoup
from textblob import TextBlob
def scrape_titles(url):
"""Scrape article titles from a given URL."""
response = requests.get(url)
soup = BeautifulSoup(response.content, "html.parser")
titles = soup.find_all("h2", class_="article-title")
return [title.get_text() for title in titles]
def analyze_sentiment(text):
"""Analyze sentiment of a given text."""
blob = TextBlob(text)
return blob.sentiment.polarity
def analyze_titles_sentiment(titles):
"""Analyze sentiment of a list of titles."""
return [analyze_sentiment(title) for title in titles]
def scrape_and_analyze(url):
"""Scrape titles from a website and analyze their sentiment."""
titles = scrape_titles(url)
sentiments = analyze_titles_sentiment(titles)
return sentiments
url = "https://example.com/articles"
print(scrape_and_analyze(url))
Reactive Strategies
No matter how hard you try to prevent errors, a few can always sneak through. The following strategies focus on dealing with these errors.
Read Error Messages Carefully
As previously mentioned, Python usually gives you an error message that includes information about the nature of the error and its location.
Carefully reading these error messages can give you valuable clues about what went wrong and how to fix it.
Use Print Statements Strategically
Using print()
statements is a quick and effective way to debug small projects or simple issues where you need to trace the flow of execution or inspect variable values at specific points. It’s particularly useful for rapid development and when you have a good understanding of where the problem might lie.
Print debugging can be less intrusive and faster to implement, making it a go-to method for quick fixes and straightforward bugs. However, always be aware that it’s for temporary use only, and make sure not to use it in the production code since printing data shown to end users can lead to catastrophic data leaks and performance issues.
For when you have more complex issues, have larger codebases, or need to inspect the state of the program more deeply (such as variable states across multiple function calls or iterations), using a debugger is more appropriate. Debuggers allow you to set break points, step through code line-by-line, and inspect the state of the application at any point, providing a more controlled and comprehensive debugging environment.
Leverage Online Resources and Communities
If you’re stuck on a particularly tricky error, don’t hesitate to seek help. There are numerous online resources (Python Docs and Real Python) and communities (r/Python and r/LearnPython subreddits, Stack Overflow, and Python Forum) where you can find answers and solutions to your problems.
Conclusion
In this article, you’ve explored the world of Python syntax errors. You learned about a few types of syntax errors, including where they can occur and how to identify and fix them.
You also learned about a few proactive and reactive strategies to help you prevent syntax errors or fix them when they occur.
Bright Data is a leading provider of web scraping tools. Whether you need reliable proxies, automated data collection, ready-to-use datasets, or automation of web scraping tasks, Bright Data offers solutions that can make your web scraping projects more efficient and productive.
Sign up now to find the right product for your needs and start a free trial today!
No credit card required