-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Add %pip and %conda magic functions #11524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Needs some work on tests, but that can wait until there's some consensus on whether this feature should be added or not! |
|
I think this is a great thing to add, personally. |
|
Yes! #11481 I'll take a look, and, going forward, will always try to help maintain keep refined. This is important. |
|
Very clever on scanning the history, looking for the path! Never would have thought of that. What will the advice be to users who don't know if a package can be install by conda or pip? I was originally thinking a general |
|
We're also having problems with people using Could it be possible to intercept the use of |
|
Thank you so much @jakevdp |
| def _is_conda_environment(): | ||
| """Return True if the current Python executable is in a conda env""" | ||
| # TODO: does this need to change on windows? | ||
| conda_history = os.path.join(sys.prefix, 'conda-meta', 'history') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dhirschfeld would this correctly detect being in a conda environment on Windows?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A better way might be to check if Anaconda is in sys.version. That should work cross-platform.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that only works if you happen to be using the Python built by Anaconda. For example:
$ conda create -n forge-python
$ conda activate forge-python
$ conda install python --yes -c conda-forge
$ python -c "import sys; print(sys.version)"
3.7.1 | packaged by conda-forge | (default, Nov 13 2018, 09:50:42)
[Clang 9.0.0 (clang-900.0.37)]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh yes you're right
| 'install', 'list', 'remove', 'uninstall', 'update', 'upgrade', | ||
| } | ||
| CONDA_COMMANDS_REQUIRING_YES = { | ||
| 'install', 'remove', 'uninstall', 'update', 'upgrade', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love this organization around args needing --y or the --prefix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It really is gloriously nice.
| Usage: | ||
| %pip install [pkgs] | ||
| """ | ||
| self.shell.system(' '.join([sys.executable, '-m', 'pip', line])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works pretty well, the only hidden API surface to this is that this allows the full pip API. We likely wouldn't be able to extend this with new args, possibly for something ipython / jupyter specific (capturing metadata, accepting a flag to do so).
Needless to say, I'm cool with this implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 We likely want to remind user they might need to restart the kernel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 594d000
|
There might be an issue on Windows where you can silently corrupt your installation by trying to update a compiled extension when Windows is holding a reference to the DLL. Certainly, with pandas that used to often happen. I still kill all Python processes before doing any upgrades, but maybe that's no longer required and conda has worked around the original issue. I'll try to check the current behaviour and report back... |
|
I need to dig into that but yes one of the function magic options isn't erroring as one would expect. |
|
I guess we could also use |
|
I fixed the tests. |
|
Thanks y'all! |
|
Can't wait for this! Was just experiencing confusion today around this specific action |
|
@Carreau Time for a 7.3 release? |
|
Yes, on my todo list, but tiem is short and $DAYJOB is taking more time than planned after holidays. One of the biggest task is writing the what's new :-) |
|
@Carreau Just saw your note. What "steps remaining" do you mean? |
|
Basically a todo-list, with list of stem necessary before/during/after the release and list of issues /changes that need to be added in the what's new. |
This PR adds
%pipand%condamagic functions which automatically install packages into the currently-running kernel in an IPython or Jupyter notebook session.Why? Correctly installing Python packages within a running kernel has long been a point of confusion within the Jupyter ecosystem. While this might seem like an anti-pattern for the traditional local kernel use-case, the recent popularity of cloud-backed Jupyter notebook services has made this more relevant.
For some background on why
!pip installor!conda installare incorrect in ways that can be very subtle and confusing, see my blog post from last year: Installing Python Packages From a Jupyter Notebook.There are some existing issues requesting this sort of feature (see #9517 & #11481) as well as some prior art on pip and conda magic function implementations by @minrk (https://github.com/minrk/condamagic/) and @Carreau (https://github.com/Carreau/pip_magic), but the fact that these third-party functions must be manually installed limits their usefulness to people who are having trouble installing things 😄.
I'm hoping that including functionality like this within IPython itself will address the bulk of the confusion many of us have seen from users of the Jupyter stack.