Repository: conda/conda

Issue:
Error in CommandNotFoundError
Commit 809532b7cc5ec1ea18f1aa565025d7c5599185b3 has broken the class CommandNotFoundError. Examples to trigger both code paths calling CommandNotFoundError():

```
(root) [root@d4cb01a1b5b6 ~]# conda activate
Traceback (most recent call last):
  File "/conda/bin/conda", line 6, in <module>
    sys.exit(conda.cli.main())
  File "/conda/lib/python2.7/site-packages/conda/cli/main.py", line 161, in main
    raise CommandNotFoundError(argv1, message)
TypeError: __init__() takes exactly 2 arguments (3 given)
```

```
(root) [root@d4cb01a1b5b6 ~]# conda -unknown unknown                                                                                                                                                               
An unexpected error has occurred.
Please consider posting the following information to the
conda GitHub issue tracker at:

    https://github.com/conda/conda/issues

Current conda install:

               platform : linux-64
          conda version : 4.3.14
       conda is private : False
      conda-env version : 4.3.14
    conda-build version : not installed
         python version : 2.7.13.final.0
       requests version : 2.12.4
       root environment : /conda  (writable)
    default environment : /conda
       envs directories : /conda/envs
                          /root/.conda/envs
          package cache : /conda/pkgs
                          /root/.conda/pkgs
           channel URLs : https://repo.continuum.io/pkgs/free/linux-64
                          https://repo.continuum.io/pkgs/free/noarch
                          https://repo.continuum.io/pkgs/r/linux-64
                          https://repo.continuum.io/pkgs/r/noarch
                          https://repo.continuum.io/pkgs/pro/linux-64
                          https://repo.continuum.io/pkgs/pro/noarch
            config file : /root/.condarc
           offline mode : False
             user-agent : conda/4.3.14 requests/2.12.4 CPython/2.7.13 Linux/4.8.6-300.fc25.x86_64 CentOS/6.8 glibc/2.12
                UID:GID : 0:0

`$ /conda/bin/conda -unknown unknown`

    Traceback (most recent call last):
      File "/conda/lib/python2.7/site-packages/conda/exceptions.py", line 573, in conda_exception_handler
        return_value = func(*args, **kwargs)
      File "/conda/lib/python2.7/site-packages/conda/cli/main.py", line 119, in _main
        args = p.parse_args(args)
      File "/conda/lib/python2.7/site-packages/conda/cli/conda_argparse.py", line 173, in parse_args
        return super(ArgumentParser, self).parse_args(*args, **kwargs)
      File "/conda/lib/python2.7/argparse.py", line 1701, in parse_args
        args, argv = self.parse_known_args(args, namespace)
      File "/conda/lib/python2.7/argparse.py", line 1740, in parse_known_args
        self.error(str(err))
      File "/conda/lib/python2.7/site-packages/conda/cli/conda_argparse.py", line 146, in error
        raise CommandNotFoundError(cmd, message)
    TypeError: __init__() takes exactly 2 arguments (3 given)
```
Error in CommandNotFoundError
Commit 809532b7cc5ec1ea18f1aa565025d7c5599185b3 has broken the class CommandNotFoundError. Examples to trigger both code paths calling CommandNotFoundError():

```
(root) [root@d4cb01a1b5b6 ~]# conda activate
Traceback (most recent call last):
  File "/conda/bin/conda", line 6, in <module>
    sys.exit(conda.cli.main())
  File "/conda/lib/python2.7/site-packages/conda/cli/main.py", line 161, in main
    raise CommandNotFoundError(argv1, message)
TypeError: __init__() takes exactly 2 arguments (3 given)
```

```
(root) [root@d4cb01a1b5b6 ~]# conda -unknown unknown                                                                                                                                                               
An unexpected error has occurred.
Please consider posting the following information to the
conda GitHub issue tracker at:

    https://github.com/conda/conda/issues

Current conda install:

               platform : linux-64
          conda version : 4.3.14
       conda is private : False
      conda-env version : 4.3.14
    conda-build version : not installed
         python version : 2.7.13.final.0
       requests version : 2.12.4
       root environment : /conda  (writable)
    default environment : /conda
       envs directories : /conda/envs
                          /root/.conda/envs
          package cache : /conda/pkgs
                          /root/.conda/pkgs
           channel URLs : https://repo.continuum.io/pkgs/free/linux-64
                          https://repo.continuum.io/pkgs/free/noarch
                          https://repo.continuum.io/pkgs/r/linux-64
                          https://repo.continuum.io/pkgs/r/noarch
                          https://repo.continuum.io/pkgs/pro/linux-64
                          https://repo.continuum.io/pkgs/pro/noarch
            config file : /root/.condarc
           offline mode : False
             user-agent : conda/4.3.14 requests/2.12.4 CPython/2.7.13 Linux/4.8.6-300.fc25.x86_64 CentOS/6.8 glibc/2.12
                UID:GID : 0:0

`$ /conda/bin/conda -unknown unknown`

    Traceback (most recent call last):
      File "/conda/lib/python2.7/site-packages/conda/exceptions.py", line 573, in conda_exception_handler
        return_value = func(*args, **kwargs)
      File "/conda/lib/python2.7/site-packages/conda/cli/main.py", line 119, in _main
        args = p.parse_args(args)
      File "/conda/lib/python2.7/site-packages/conda/cli/conda_argparse.py", line 173, in parse_args
        return super(ArgumentParser, self).parse_args(*args, **kwargs)
      File "/conda/lib/python2.7/argparse.py", line 1701, in parse_args
        args, argv = self.parse_known_args(args, namespace)
      File "/conda/lib/python2.7/argparse.py", line 1740, in parse_known_args
        self.error(str(err))
      File "/conda/lib/python2.7/site-packages/conda/cli/conda_argparse.py", line 146, in error
        raise CommandNotFoundError(cmd, message)
    TypeError: __init__() takes exactly 2 arguments (3 given)
```


Discussion:
@nehaljwani thanks I will work on this one
I have the exact same problem.

----------------------------------------------------------------------------------------------------
In [24]: conda -unknown unknown
An unexpected error has occurred.
Please consider posting the following information to the
conda GitHub issue tracker at:

    https://github.com/conda/conda/issues



Current conda install:

               platform : win-64
          conda version : 4.3.14
       conda is private : False
      conda-env version : 4.3.14
    conda-build version : 2.0.2
         python version : 2.7.13.final.0
       requests version : 2.12.4
       root environment : C:\Program Files\Anaconda2  (writable)
    default environment : C:\Program Files\Anaconda2
       envs directories : C:\Program Files\Anaconda2\envs
                          C:\Users\dparaskevopoulos\AppData\Local\conda\conda\envs
                          C:\Users\dparaskevopoulos\.conda\envs
          package cache : C:\Program Files\Anaconda2\pkgs
                          C:\Users\dparaskevopoulos\AppData\Local\conda\conda\pkgs
           channel URLs : https://repo.continuum.io/pkgs/free/win-64
                          https://repo.continuum.io/pkgs/free/noarch
                          https://repo.continuum.io/pkgs/r/win-64
                          https://repo.continuum.io/pkgs/r/noarch
                          https://repo.continuum.io/pkgs/pro/win-64
                          https://repo.continuum.io/pkgs/pro/noarch
                          https://repo.continuum.io/pkgs/msys2/win-64
                          https://repo.continuum.io/pkgs/msys2/noarch
            config file : None
           offline mode : False
             user-agent : conda/4.3.14 requests/2.12.4 CPython/2.7.13 Windows/7 Windows/6.1.7601



`$ C:\Program Files\Anaconda2\Scripts\conda-script.py -unknown unknown`




    Traceback (most recent call last):
      File "C:\Program Files\Anaconda2\lib\site-packages\conda\exceptions.py", line 573, in conda_exception_handler
        return_value = func(*args, **kwargs)
      File "C:\Program Files\Anaconda2\lib\site-packages\conda\cli\main.py", line 119, in _main
        args = p.parse_args(args)
      File "C:\Program Files\Anaconda2\lib\site-packages\conda\cli\conda_argparse.py", line 173, in parse_args
        return super(ArgumentParser, self).parse_args(*args, **kwargs)
      File "C:\Program Files\Anaconda2\lib\argparse.py", line 1701, in parse_args
        args, argv = self.parse_known_args(args, namespace)
      File "C:\Program Files\Anaconda2\lib\argparse.py", line 1740, in parse_known_args
        self.error(str(err))
      File "C:\Program Files\Anaconda2\lib\site-packages\conda\cli\conda_argparse.py", line 146, in error
        raise CommandNotFoundError(cmd, message)
    TypeError: __init__() takes exactly 2 arguments (3 given)


@nehaljwani thanks I will work on this one
I have the exact same problem.

----------------------------------------------------------------------------------------------------
In [24]: conda -unknown unknown
An unexpected error has occurred.
Please consider posting the following information to the
conda GitHub issue tracker at:

    https://github.com/conda/conda/issues



Current conda install:

               platform : win-64
          conda version : 4.3.14
       conda is private : False
      conda-env version : 4.3.14
    conda-build version : 2.0.2
         python version : 2.7.13.final.0
       requests version : 2.12.4
       root environment : C:\Program Files\Anaconda2  (writable)
    default environment : C:\Program Files\Anaconda2
       envs directories : C:\Program Files\Anaconda2\envs
                          C:\Users\dparaskevopoulos\AppData\Local\conda\conda\envs
                          C:\Users\dparaskevopoulos\.conda\envs
          package cache : C:\Program Files\Anaconda2\pkgs
                          C:\Users\dparaskevopoulos\AppData\Local\conda\conda\pkgs
           channel URLs : https://repo.continuum.io/pkgs/free/win-64
                          https://repo.continuum.io/pkgs/free/noarch
                          https://repo.continuum.io/pkgs/r/win-64
                          https://repo.continuum.io/pkgs/r/noarch
                          https://repo.continuum.io/pkgs/pro/win-64
                          https://repo.continuum.io/pkgs/pro/noarch
                          https://repo.continuum.io/pkgs/msys2/win-64
                          https://repo.continuum.io/pkgs/msys2/noarch
            config file : None
           offline mode : False
             user-agent : conda/4.3.14 requests/2.12.4 CPython/2.7.13 Windows/7 Windows/6.1.7601



`$ C:\Program Files\Anaconda2\Scripts\conda-script.py -unknown unknown`




    Traceback (most recent call last):
      File "C:\Program Files\Anaconda2\lib\site-packages\conda\exceptions.py", line 573, in conda_exception_handler
        return_value = func(*args, **kwargs)
      File "C:\Program Files\Anaconda2\lib\site-packages\conda\cli\main.py", line 119, in _main
        args = p.parse_args(args)
      File "C:\Program Files\Anaconda2\lib\site-packages\conda\cli\conda_argparse.py", line 173, in parse_args
        return super(ArgumentParser, self).parse_args(*args, **kwargs)
      File "C:\Program Files\Anaconda2\lib\argparse.py", line 1701, in parse_args
        args, argv = self.parse_known_args(args, namespace)
      File "C:\Program Files\Anaconda2\lib\argparse.py", line 1740, in parse_known_args
        self.error(str(err))
      File "C:\Program Files\Anaconda2\lib\site-packages\conda\cli\conda_argparse.py", line 146, in error
        raise CommandNotFoundError(cmd, message)
    TypeError: __init__() takes exactly 2 arguments (3 given)



Resolving patch:
diff --git a/conda/cli/conda_argparse.py b/conda/cli/conda_argparse.py
--- a/conda/cli/conda_argparse.py
+++ b/conda/cli/conda_argparse.py
@@ -10,14 +10,11 @@
 import os
 import subprocess
 import sys
-from difflib import get_close_matches
 
 from .common import add_parser_help
 from .find_commands import find_commands, find_executable
 from ..exceptions import CommandNotFoundError
 
-build_commands = {'build', 'index', 'skeleton', 'package', 'metapackage',
-                  'pipbuild', 'develop', 'convert'}
 
 _ARGCOMPLETE_DEBUG = False
 def debug_argcomplete(msg):
@@ -129,21 +126,7 @@ def error(self, message):
                     cmd = m.group(1)
                     executable = find_executable('conda-' + cmd)
                     if not executable:
-                        if cmd in build_commands:
-                            raise CommandNotFoundError(cmd, '''
-Error: You need to install conda-build in order to
-use the "conda %s" command.''' % cmd)
-                        else:
-                            message = "Error: Could not locate 'conda-%s'" % cmd
-                            possibilities = (set(argument.choices.keys()) |
-                                             build_commands |
-                                             set(find_commands()))
-                            close = get_close_matches(cmd, possibilities)
-                            if close:
-                                message += '\n\nDid you mean one of these?\n'
-                                for s in close:
-                                    message += '    %s' % s
-                            raise CommandNotFoundError(cmd, message)
+                        raise CommandNotFoundError(cmd)
 
                     args = [find_executable('conda-' + cmd)]
                     args.extend(sys.argv[2:])
diff --git a/conda/cli/main.py b/conda/cli/main.py
--- a/conda/cli/main.py
+++ b/conda/cli/main.py
@@ -152,14 +152,8 @@ def main(*args):
                 activate.main()
                 return
             if argv1 in ('activate', 'deactivate'):
-
-                message = "'%s' is not a conda command.\n" % argv1
-                from ..common.compat import on_win
-                if not on_win:
-                    message += ' Did you mean "source %s" ?\n' % ' '.join(args[1:])
-
                 from ..exceptions import CommandNotFoundError
-                raise CommandNotFoundError(argv1, message)
+                raise CommandNotFoundError(argv1)
         except Exception as e:
             from ..exceptions import handle_exception
             return handle_exception(e)
diff --git a/conda/exceptions.py b/conda/exceptions.py
--- a/conda/exceptions.py
+++ b/conda/exceptions.py
@@ -11,7 +11,7 @@
 from ._vendor.auxlib.entity import EntityEncoder
 from ._vendor.auxlib.ish import dals
 from .base.constants import PathConflict
-from .common.compat import iteritems, iterkeys, string_types
+from .common.compat import iteritems, iterkeys, on_win, string_types
 from .common.signals import get_signal_name
 from .common.url import maybe_unquote
 
@@ -159,7 +159,32 @@ def __init__(self, target_path, incompatible_package_dists, context):
 
 class CommandNotFoundError(CondaError):
     def __init__(self, command):
-        message = "Conda could not find the command: '%(command)s'"
+        build_commands = {
+            'build',
+            'convert',
+            'develop',
+            'index',
+            'inspect',
+            'metapackage',
+            'render',
+            'skeleton',
+        }
+        needs_source = {
+            'activate',
+            'deactivate'
+        }
+        if command in build_commands:
+            message = dals("""
+            You need to install conda-build in order to
+            use the 'conda %(command)s' command.
+            """)
+        elif command in needs_source and not on_win:
+            message = dals("""
+            '%(command)s is not a conda command.
+            Did you mean 'source %(command)s'?
+            """)
+        else:
+            message = "Conda could not find the command: '%(command)s'"
         super(CommandNotFoundError, self).__init__(message, command=command)
 
 


Test patch:
diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py
--- a/tests/test_exceptions.py
+++ b/tests/test_exceptions.py
@@ -1,6 +1,8 @@
 import json
 from unittest import TestCase
 
+from conda.common.compat import on_win
+
 from conda import text_type
 from conda._vendor.auxlib.ish import dals
 from conda.base.context import reset_context, context
@@ -310,7 +312,7 @@ def test_CondaHTTPError(self):
                 Groot
                 """).strip()
 
-    def test_CommandNotFoundError(self):
+    def test_CommandNotFoundError_simple(self):
         cmd = "instate"
         exc = CommandNotFoundError(cmd)
 
@@ -330,3 +332,52 @@ def test_CommandNotFoundError(self):
 
         assert not c.stdout
         assert c.stderr.strip() == "CommandNotFoundError: Conda could not find the command: 'instate'"
+
+    def test_CommandNotFoundError_conda_build(self):
+        cmd = "build"
+        exc = CommandNotFoundError(cmd)
+
+        with env_var("CONDA_JSON", "yes", reset_context):
+            with captured() as c, replace_log_streams():
+                conda_exception_handler(_raise_helper, exc)
+
+        json_obj = json.loads(c.stdout)
+        assert not c.stderr
+        assert json_obj['exception_type'] == "<class 'conda.exceptions.CommandNotFoundError'>"
+        assert json_obj['message'] == text_type(exc)
+        assert json_obj['error'] == repr(exc)
+
+        with env_var("CONDA_JSON", "no", reset_context):
+            with captured() as c, replace_log_streams():
+                conda_exception_handler(_raise_helper, exc)
+
+        assert not c.stdout
+        assert c.stderr.strip() == ("CommandNotFoundError: You need to install conda-build in order to\n" \
+                                    "use the 'conda build' command.")
+
+    def test_CommandNotFoundError_activate(self):
+        cmd = "activate"
+        exc = CommandNotFoundError(cmd)
+
+        with env_var("CONDA_JSON", "yes", reset_context):
+            with captured() as c, replace_log_streams():
+                conda_exception_handler(_raise_helper, exc)
+
+        json_obj = json.loads(c.stdout)
+        assert not c.stderr
+        assert json_obj['exception_type'] == "<class 'conda.exceptions.CommandNotFoundError'>"
+        assert json_obj['message'] == text_type(exc)
+        assert json_obj['error'] == repr(exc)
+
+        with env_var("CONDA_JSON", "no", reset_context):
+            with captured() as c, replace_log_streams():
+                conda_exception_handler(_raise_helper, exc)
+
+        assert not c.stdout
+
+        if on_win:
+            message = "CommandNotFoundError: Conda could not find the command: 'activate'"
+        else:
+            message = ("CommandNotFoundError: 'activate is not a conda command.\n"
+                       "Did you mean 'source activate'?")
+        assert c.stderr.strip() == message