Consider this python 3 snippet, where when an import exception is raised, a string 'e' is created that says: "No module named ' packageName'".

The goal is to simply say on exit, that the import error can perhaps be solved by installing a package of the same name. I came up with this, and it works but I'd like to make it better, if anyone has some tips.

except ImportError as e:
     e = e.replace("No module named '", "")
     e = e.replace("'", "")
     sys.exit("'Error: Try sudo pip install %s'" % e)

Example output:

Error: Try sudo pip install Crypto

  • \$\begingroup\$ As a side-note, here is a project of mine that I haven't worked on for a long time and designed to add suggestion to error messages : github.com/SylvainDe/DidYouMean-Python . Many things are still to be done (pip installable, more suggestions, usable with -m option, etc) but you might find it interesting. \$\endgroup\$
    – SylvainD
    Feb 14, 2016 at 10:13

2 Answers 2


An ImportError instance doesn't have a replace method.

You can use e.name instead of messy string replacements.

Instead of '%s' % x, it's recommended to use '{}'.format(x).

The example output is not what you posted, but actually this:

'Error: Try sudo pip install Crypto'

That is, it's surrounded by single quotes, because you wrote as "'some text'". Probably you want to remove those single quotes inside the string.

What does the message even mean?

This would make a lot more sense:

Error: could not import 'Crypto'. Try installing with: pip install --user Crypto

Last, but most importantly, please don't recommend to install Python packages system-wide. This is a more sensible recommendation:

pip install --user the_package

This doesn't need sudo, as it will install the package in the user's home directory, not system-wide.

Putting it together:

    import somename
except ImportError as e:
    sys.exit("Error: could not import '{0}'. Try installing with: pip install --user {0}".format(e.name))
  • \$\begingroup\$ linux thing to do sudo \$\endgroup\$
    – j0h
    Feb 14, 2016 at 13:49
  • 9
    \$\begingroup\$ @j0h no, doing sudo is not a "linux thing" at all. sudo is not to be taken lightly. It's not meant to run commands willy-nilly. \$\endgroup\$
    – janos
    Feb 14, 2016 at 13:57

First of all, this code doesn't work. e is an ImportError instance, not a string, and so it doesn't have a replace method; you want to operate on e.msg instead.

Secondly, the messages generated this way will be wrong a non-negligible number of times, as modules aren't always available in PyPI packages of the same name. The bs4 module is in the beautifulsoup4 package, yaml is in PyYAML, png is in PurePNG, etc. If you want these error messages to actually be useful, you'll have to explicitly code a different try ... except for every foreign import.

Moving on to more stylistic issues, there is technically no guarantee that an ImportError's message will always be of the form "No module named '%s'", and even if it were guaranteed, using a regex would probably be a better way to extract the name of the unimportable module. However, since Python 3.3, you don't need to mess around with the error message, as the name of the module is available as the e.name attribute of the ImportError.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.