command-not-found fails when user-installed python3 is in PATH

Bug #1480388 reported by Matthew Bergkoetter
14
This bug affects 3 people
Affects Status Importance Assigned to Milestone
command-not-found
New
Undecided
Unassigned

Bug Description

I have a second installation of python3 (from Anaconda) and it's first in my user path:

$ which python3
/home/matt/Programs/anaconda3/bin/python3

This seems to be causing a problem with command-not-found. When I enter an invalid command in the terminal:

$ fake_command
Failed to import the site module
Traceback (most recent call last):
  File "/usr/lib/python3.4/site.py", line 586, in <module>
    main()
  File "/usr/lib/python3.4/site.py", line 572, in main
    known_paths = addusersitepackages(known_paths)
  File "/usr/lib/python3.4/site.py", line 287, in addusersitepackages
    user_site = getusersitepackages()
  File "/usr/lib/python3.4/site.py", line 263, in getusersitepackages
    user_base = getuserbase() # this will also set USER_BASE
  File "/usr/lib/python3.4/site.py", line 253, in getuserbase
    USER_BASE = get_config_var('userbase')
  File "/usr/lib/python3.4/sysconfig.py", line 597, in get_config_var
    return get_config_vars().get(name)
  File "/usr/lib/python3.4/sysconfig.py", line 540, in get_config_vars
    _init_posix(_CONFIG_VARS)
  File "/usr/lib/python3.4/sysconfig.py", line 412, in _init_posix
    from _sysconfigdata import build_time_vars
  File "/usr/lib/python3.4/_sysconfigdata.py", line 6, in <module>
    from _sysconfigdata_m import *
ImportError: No module named '_sysconfigdata_m'

I can get the expected behavior by removing the line in .bashrc that adds anaconda to the path:

$ fake_command
fake_command: command not found

The source of the problem appears to be a line in /usr/lib/command-not-found where it's trying to re-run itself in python3 if it's being run in python2 (which is currently what /usr/bin/python points to):

    if sys.version < '3':
        # We might end up being executed with Python 2 due to an old
        # /etc/bash.bashrc.
        import os
        if "COMMAND_NOT_FOUND_FORCE_PYTHON2" not in os.environ:
            os.execvp("python3", [sys.argv[0]] + sys.argv)

Notice that it calls the command 'python3', which will resolve to the user-installed version of python3 if it's first in the path. That won't work because the anaconda installation doesn't have the modules the script needs to run. I can make the command work by being explicit about which installation of python3 to use:

$ /usr/bin/python3 /usr/lib/command-not-found fake_command
fake_command: command not found

Instead of:

 $ /home/matt/Programs/anaconda3/bin/python3 /usr/lib/command-not-found fake_command
Traceback (most recent call last):
  File "/usr/lib/command-not-found", line 27, in <module>
    from CommandNotFound.util import crash_guard
ImportError: No module named 'CommandNotFound'

Now, I don't know why the stack trace in the original error looks like it's coming from the system installation of python3.4, but I know that the user installation is the real wrench in the works, because the problem doesn't occur when that's not on the path. A simple solution is to make command-not-found be explicit about which installation it uses. Changing the line to:

os.execvp("/usr/bin/python3", [sys.argv[0]] + sys.argv)

solves the problem on my system. I suppose the original intent was to use the system installation anyway, since the script relies on modules that are included with ubuntu but not in the python standard library.

Revision history for this message
Matthew Bergkoetter (mbergkoetter) wrote :
Revision history for this message
Matthew Bergkoetter (mbergkoetter) wrote :
Revision history for this message
Graham (ooddiittyy) wrote :

Fix recommended by OP worked for me as well.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.