Troubleshooting Common Python Problems

Leave your reply

Introduction

Learn how to troubleshoot common Python problems.

Requirements

  • Python installed and running
  • Linux server

A Simple Script For Testing Python

For testing purposes, it is best to keep things simple. Use this script to test Python either from the command line or in a browser:

#!/usr/bin/python

print "Content-Type: text/html"
print "\n\n"
print "<p>Hello World</p>"

Save this script in a file called helloworld.py.

Begin troubleshooting by testing your script from the command line:

sudo python helloworld.py

The output should look like this:

Testing Python with a simple hello world script

Decoding a Python Error

When Python finds a problem with the script, it tries its best to tell you what the problem is, and where it is located.

Here is an example of an error produced by removing the : colon at the end of a for statement:

Example Python error message

There are three elements to this error message:

  • The line of the code where the error takes place (line 3 in this example)
  • A ^ pointer which singles out the exact location of the error (to Python's best abilities).
  • The error message itself ("SyntaxError: invalid syntax").

In this example, Python identified the problem precisely. There are some situations - particularly when a quote or an end parenthesis is missing - where Python isn't able to guess the error's location as easily. As such, when you read these errors, keep in mind that the problem could be happening at or before the location Python identifies.

Permission Denied

If you get a "permission denied" error when you attempt to run this Python script from the command line, most likely the permissions are wrong.

Python error message: Permission Denied

The fix for this problem will depend on how you are calling the script.

Permission Denied When Running a Script With the Python Command

Unlike a CGI script, Python scripts do not need to have execute permissions to run when you invoke them with the python command. Python is an interpreted language, which means that if you call the file with python [filename], Python itself handles the execution. The file only needs to be readable by Python.

To set this, use the command:

sudo chmod 644 helloworld.py

To check permissions, list the files in the directory with the command:

sudo ls -la

In this example, you can see that the file helloworld.py has read/write permission for the owner, and read permissions for group and world (chmod 644):

644 file permissions

You will be able to run this test script with the command:

sudo python helloworld.py

Permission Denied When Running a Script From the Shell

The other way to run a Python script is to invoke it directly from the shell:

./helloworld.py

Because of the way the shell interprets this command, the file needs to be executable. To fix the permissions, use the command:

sudo chmod 755 helloworld.py

To check permissions, list the files in the directory with the command:

sudo ls -la

In this example, you can see that the file helloworld.py has read/write/execute permission for the owner, and read/write permissions for group and world (chmod 755):

File with 755 executable permissions

You will be able to run this test script with the command:

./helloworld.py

Bad interpreter: No such file or directory

There is a second quirk of invoking a Python script directly from the shell on the command line: the path to Python needs to be correct. Otherwise, you will receive a "Bad interpreter: No such file or directory" error.

You can find the path to Python from the command line with the command:

which python

Typically the path to Python is /usr/bin/python but this can vary depending on the installation or operating system.

The first line of the script is #! followed by the path to Python on your system. For example, if the path to Python is /usr/bin/python the first line of the script needs to read:

#!/usr/bin/python

IndentationError Messages

Python is sensitive to whitespace (blank spaces at the beginning of a line). Each line needs to be indented correctly, because this is how Python "reads" nested blocks of code. These errors can also happen if you mix tab stops with spaces.

There are three related errors:

  • unexpected indent: There are one or more spaces at the beginning of a line that shouldn't be there.
  • unindent does not match any outer indentation level: There are fewer spaces at the beginning of the line than there should be.
  • expected an indented block: A block of code should have spaces at the beginning of each line, but it doesn't.

For example, if you copy and paste a script from a web page, sometimes you will accidentally paste in whitespace at the beginning of each line.

Python script with extra whitespace

This whitespace will need to be deleted before the script will run correctly.

Python script whitespace removed

The Python error message will often tell you exactly where the extra whitespace is located. In this example, the error message specifies that the problem is on line 4 of the file:

Indent causing problems in Python script

If we open the file, we will see that this is the case:

Location of indent causing problem in Python script

Removing the extra spaces at the beginning of line 4 will allow this script to run correctly.

TypeError Messages

"TypeError" messages mean that you are treating one type of data as if it were another type of data.

When Iterating Over Several Items

One way this happens is when you try to iterate over each item in a list or string. There are a number of variations on this error, including:

"TypeError: range() integer end argument expected, got list."

An example of code that will create this error:

pet = ['Dog', 'Cat', 'Guinea Pig']

for i in range(pet):
    print (pet[i])

"TypeError: list indices must be integers, not str"

An example of code that will create this error:

pet = ['Dog', 'Cat', 'Guinea Pig']

for i in pet:
  print (pet[i])

Fixing Iteration Problems

Here is the simplest way to do this correctly:

pet = ['Dog', 'Cat', 'Guinea Pig']

for i in pet:
  print i

When Handling Data

Another source of "TypeError" messages is treating non-string data as a string.

"TypeError: cannot concatenate 'str' and 'int' objects"

An example of code that will create this error:

widgetCount = 2

print 'I would like ' + widgetCount + ' widgets.'

There are two ways to fix this problem:

1. Change the data type

Putting the value inside quotes will tell Python to treat it like a string:

widgetCount = '2'

print 'I would like ' + widgetCount + ' widgets.'

2. Call the data as an integer

Alternatively, call catCount as an integer, using , commas instead of + plus signs:

widgetCount = 2

print 'I would like ', widgetCount, ' widgets.'

3. Concatenate the data correctly

If you need to concatenate strings and integers into a string, one correct way is to convert the integers into string format first:

widgetCount = 2
first = 'I would like '
last = ' widgets.'

request = first + str(widgetCount) + last

print request

SyntaxError Messages

A "SyntaxError" message means that there is a typo in your code. Some common omissions and mistakes include:

  • Using a single = when you meant ==.
  • Forgetting to put a : at the end of a statement like for, while, if, etc.
  • A missing ] or ) bracket.
  • Using a ; semicolon when you meant a : colon.
  • Accidentally replacing one ( parenthesis or [ square bracket with a { curly bracket.
  • Spelling errors such as fro instead of for.
  • Leaving out a ' quote mark when working with a string, like print('widgets) or print(widgets').

Python Script Doesn't Run in a Browser

If you drop a Python script into a web directory and visit the script in a browser, you will likely get just the text of the script in your browser, instead of the output of the script itself.

Python script printing out in browser

There are two options for running Python scripts in a web browser:

  1. Treat the Python files as CGI scripts and run them out of the cgi-bin directory.
  2. Install a web framework for Python.

Which option you choose will depend on your individual needs and preferences.

Option 1: Run Python Scripts as CGI Scripts

To run a Python script as a CGI script, simply put the script into your web server's /cgi-bin/ directory and make the file executable with the command:

sudo chmod 755 [filename]

For example, to make the helloworld.py file executable, the command would be:

sudo chmod 755 helloworld.py

If your web server does not have a /cgi-bin/ configured, consult our tutorial on setting up a CGI bin.

Option 2: Install a Web Framework for Python

A Python web framework allows developers to write web applications in Python. There are many web frameworks for Python available. Each one has its own advantages and drawbacks which you will need to consider before choosing which one to install.

Some popular Python web frameworks include:

The official Python.org Wiki has a complete list of current (and inactive) Python web frameworks.

As an example, we will install Bottle, which is a lightweight Python web framework which is easy to install and use.

Installing Bottle

Installing Bottle on CentOS 7 and Ubuntu 14.04 is a two-step process. First you must install Pip, which is a package manager for Python. Then you use Pip to install Bottle.

Installing Bottle on CentOS 7

Begin by installing the EPEL repository with the command:

sudo yum install epel-release

Next, install Pip with the command:

sudo yum install python-pip

Finally, use Pip to install Bottle with the command:

sudo pip install bottle

Installing Bottle on Ubuntu 14.04

First, install Pip with the command:

sudo apt-get install python-pip

Then use Pip to install Bottle with the command:

sudo pip install bottle

Example: Using Bottle to run a Simple Python Script

Go to your website's root directory and create a file called helloworld.py with the command:

sudo nano helloworld.py

The first line of the file needs to call Bottle, and import route and run:

from bottle import route, run

Next, we will define route as /helloworld. This is the URL which you will use to access your script:

@route('/helloworld')

The next two lines define the helloworld function, which will print out "Hello World" to the browser:

def helloworld():
    return "Hello World"

The final line of our test script will define the host and the port used to access the script.

  • For the host, use your server's domain name or IP address.
  • For the port, use 8080. If your server is behind a firewall, you may need to allow access to this port before you continue.

    run(host='example.com', port=8080)

Note: You can use any port for your Bottle scripts. Port 8080 is used by common convention for alternate web services. If port 8080 is in use on your server, simply choose a different port which is not in use, so that Bottle can bind to it.

The entire script will read as follows:

from bottle import route, run

@route('/helloworld')
def helloworld():
    return "Hello World"

run(host='example.com', port=8080)

Save and exit the file.

Next, you need to run the script from the command line, and keep it running so that you can access the script in a browser. Start the script with the command:

sudo python helloworld.py

Now that the script is running, switch to a browser and visit the URL:

http://example.com:8080/helloworld

You should see the words "Hello World" in the browser.

Once you have finished, you can use 'CTRL + c` to exit the script and return to the command line.