0

While installing QDK for use with python as described in this guide, on executing dotnet iqsharp install I get the following exception

Traceback (most recent call last):
  File "c:\users\hp\appdata\local\programs\python\python36\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\users\hp\appdata\local\programs\python\python36\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\hp\AppData\Local\Programs\Python\Python36\Scripts\jupyter.exe\__main__.py", line 7, in <module>
  File "c:\users\hp\appdata\local\programs\python\python36\lib\site-packages\jupyter_core\command.py", line 247, in main
    command = _jupyter_abspath(subcommand)
  File "c:\users\hp\appdata\local\programs\python\python36\lib\site-packages\jupyter_core\command.py", line 134, in _jupyter_abspath
    'Jupyter command `{}` not found.'.format(jupyter_subcommand)
Exception: Jupyter command `jupyter-kernelspec` not found.

However, when I run jupyter-kernelspec command on cmd it is found on PATH. Why is it happening that python is unable to locate a command if cmd can find it?

Raghav Kumar
  • 11
  • 1
  • 2

1 Answers1

2

To address your specific question, you can see whether Python can locate jupyter-kernelspec (and if so, where) by running something like:

python -c "from shutil import which; print(which('jupyter-kernelspec'))"

But as to the underlying cause of the error, it seems likely that your Jupyter installation is incomplete and/or your environment is somehow misconfigured. You may want to try creating a new Python environment (perhaps using Anaconda, if you're new to Python development) and then following the QDK installation instructions again from inside that new environment (e.g., from an Anaconda command prompt with the new environment active).

Edit: From comments below, it sounds like the problem is that you have a trailing semicolon in your PATHEXT environment variable. This confuses shutil.which(), and this in turn prevents Jupyter from finding the necessary executable. (I can reproduce this problem locally by adding a trailing semicolon to PATHEXT.)

The fix should be simply to remove the trailing semicolon from PATHEXT.

Ryan Shaffer
  • 405
  • 3
  • 12
  • 1
    Thank you for your answer. I did try running the script in python but the result was same. I got _None_ as the return value of `which` function. I also created a virtual environment using _virtualenv_ and installed Jupyter but to no avail. I'm trying to read the script for `which` line by line to figure a way out, but anything that could save me some time will be of immense help :) – Raghav Kumar Apr 15 '20 at 18:05
  • I just sifted through the entire `which` script and found that the function was looking for **jupyter-kernelspec** but the file that existed on PATH was **jupyter-kernelspec.exe**. Windows allow empty path extensions, thus when _jupyter-kernelspec_ was passed to `which`, it did not append _.exe_ to the command name. Is there any way that I can let the maintainers of shutils know about this? – Raghav Kumar Apr 15 '20 at 19:18
  • It looks like this issue has been discussed here: https://stackoverflow.com/questions/50484397/jupyter-commands-work-only-with-a-dash-e-g-jupyter-kernelspec-instead-of-jupyt That post includes a possible workaround that you could try (by modifying Jupyter code locally), although it doesn't seem to identify the root cause. And another potential workaround at https://stackoverflow.com/questions/56399696/shutil-which-not-finding-programs-without-appending-file-extension, if you by chance enabled case-sensitivity on your file system? – Ryan Shaffer Apr 16 '20 at 00:36
  • Instalaltion done. What happens is that `which` looks for the path extension in the name of function passed to it. If the function name contains any of the allowed path extensions `which` leaves the name unchanged, if not all the path extensions are appended to the passed function and every possibility is checked for. The issue is that empty string is also an allowed path extension, you can see that by running `os.environ.get("PATHEXT","").split(os.pathsep)` and technically it is a part of every name. So if _git_ is passed to `which` it is supposed to look for git.exe but it looks for _git_ – Raghav Kumar Apr 16 '20 at 16:03
  • I think that's your problem! The empty string should not be part of PATHEXT. And if I add empty string to my PATHEXT, I start hitting exactly the same problem as you. Make sure that your PATHEXT does not start or end with a semicolon and try again. – Ryan Shaffer Apr 16 '20 at 19:50