Wywołanie IPythona z virtualenv

84

Rozumiem, że IPython nie jest świadomy Virtualenv i że najbardziej logicznym rozwiązaniem jest zainstalowanie ipythona w każdym virtualenv osobno przy użyciu

pip install ipython

Jak na razie dobrze. Jedną z rzeczy, które zauważyłem, jest to, że jeśli ogólnosystemowa kopia IPythona jest wywoływana z poziomu virtualenv, $> ipythonzanim IPython zostanie zainstalowany pod tym virtualenv, kolejne $> ipythonpolecenia będą nadal wywoływać ogólnosystemową kopię ipythona.

Z drugiej strony, jeśli ipython nie zostanie wywołany przed zainstalowaniem go pod virtualenv $> ipython, wyświetli nowo zainstalowaną kopię.

Jakie jest tego wytłumaczenie?

Zastanawiam się również, czy to zachowanie oznacza, że ​​powinienem spodziewać się po drodze kłopotów?

Mo Sander
źródło
10
Najnowsze wersje IPythona powinny rozpoznawać virtualenv bez konieczności instalowania ich oddzielnie - po uruchomieniu zobaczysz komunikat „próbuję pracować z virtualenv”. Polecenie „sticky”, które widzisz, to bash buforujący ipythongdzieś lokalizację pliku wykonywalnego ( zobacz to pytanie ).
Thomas K
Thomas, dzięki za link o buforowaniu basha, wygląda na to, że tak właśnie się dzieje. IPython 1.1.0 pokazuje mi ostrzeżenie „Próbuję pracować w virtualenv”, ale nie rozpoznaje virtualenv, chyba że jest zainstalowany w virtualenv - ale to w porządku. Chciałem tylko upewnić się, że procedura jest bezproblemowa.
Mo Sander
7
jakiej wersji virtualenv używasz i jak aktywujesz env? Polecenie, którego brakuje, powoduje hash -rusunięcie pamięci podręcznej wcześniej uruchomionych poleceń, co zwykle jest wykonywane w ramach aktywacji pliku env. Sprawdź hash -rw ENV / bin / Activ.
minrk
1
tak, prawda! Jak zauważył Thomas, był to problem z buforowaniem basha i uruchomienie hash -rprzed aktywacją środowiska env rozwiązuje problem. FYI Pracowałem z virtualenv 1.10.1
Mo Sander,

Odpowiedzi:

110

alias ipy="python -c 'import IPython; IPython.terminal.ipapp.launch_new_instance()'"

To świetny sposób, aby zawsze mieć pewność, że instancja ipython zawsze należy do wersji Pythona virtualenv.

Działa to tylko na ipythonie> 2.0.

Źródło

SiddharthaRT
źródło
1
BTW, nazwa profilu może być przekazana przez kwargs. Dzięki za odpowiedź!
roboslone
25

Odpowiedź udzielona przez @SiddharthaRT jest dobra! Zgodnie z tym podejściem jest dla mnie prostsze po prostu:

python -m IPython

Spowoduje to użycie modułu IPython przez bin Pythona, upewniając się, że odwołuje się on do bin z wirtualnego środowiska env.

jcozar87
źródło
10

Możesz wymusić na IPythonie korzystanie ze środowiska wirtualnego, jeśli jest dostępne, dodając poniższy plik do ~/.ipython/profile_default/startups:

import os
import sys

if 'VIRTUAL_ENV' in os.environ:
    py_version = sys.version_info[:2] # formatted as X.Y 
    py_infix = os.path.join('lib', ('python%d.%d' % py_version))
    virtual_site = os.path.join(os.environ.get('VIRTUAL_ENV'), py_infix, 'site-packages')
    dist_site = os.path.join('/usr', py_infix, 'dist-packages')

    # OPTIONAL: exclude debian-based system distributions sites
    sys.path = filter(lambda p: not p.startswith(dist_site), sys.path)

    # add virtualenv site
    sys.path.insert(0, virtual_site)

Zalecam nazwanie go, 00-virtualenv.pyaby zmiany zostały wprowadzone jak najwcześniej.

Uwaga: upewnij się, że ipython jest zainstalowany w nowym środowisku wirtualnym, aby to zadziałało.

rgtk
źródło
1
Działa to świetnie w środowiskach Python 2, ale w wersji 3 envs otrzymuję błąd ImportError stwierdzający, że nie ma modułu o nazwie „IPython”. Uruchamianie ipython3 poza środowiskiem działa, czy wiesz, czego tu brakuje?
efr4k
Dzięki za to. Ale myślę, że "Opcjonalna" linia zrywa z python3, gdy sys.path staje się obiektem filtru, który nie reaguje na metody listy, prawda?
mota
6

Jak wspominali inni, ostatnie wersje ipython są świadome virtualenv, więc możesz użyć skryptu aktywacji binarki virtualenv, aby uruchomić ipython za pomocą virtualenv, np.

$ source venv/bin/activate
(venv) $ ipython
WARNING: Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
JDiMatteo
źródło
2
Tyle głosów przeciw. Jeśli to nie zadziała, prosimy o komentarz z komunikatem o błędzie i wyjściemipython --version; cat /etc/issue
JDiMatteo
2
Będzie to działać z konsolą IPythona, ale nie będzie działać z innymi rzeczami, na przykład z jądrem IPython.
Błażej Michalik
5
  1. Aktywuj swoje wirtualne środowisko za pomocą source ~ / .virtualenvs / my_venv / bin / activ lub uruchamiając workon my_venv (w zależności od tego, jak zainstalowałeś wirtualne środowisko my_venv)

  2. Zainstaluj ipython

pip zainstaluj ipython

  1. Teraz uruchom ipython z my_venv.

Jeśli nadal ładuje ipython systemu, uruchom

hash -r

TheDataGuy
źródło
1

Jeśli próbujesz otworzyć notebooka, nawet ipython 5 nie pomoże - ipython zignoruje virtualenv (przynajmniej na moim komputerze / konfiguracji). Będziesz musiał użyć skryptu rgtk, ale pamiętaj, aby zmodyfikować opcjonalną część filtru i sys.path.insert, jak poniżej:

import os
import sys

if 'VIRTUAL_ENV' in os.environ:
    py_version = sys.version_info[:2] # formatted as X.Y 
    py_infix = os.path.join('lib', ('python%d.%d' % py_version))
    virtual_site = os.path.join(os.environ.get('VIRTUAL_ENV'), py_infix, 'site-packages')
    dist_site = os.path.join('/usr', py_infix, 'dist-packages')

    # OPTIONAL: exclude debian-based system distributions sites
    # ADD1: sys.path must be a list
    sys.path = list(filter(lambda p: not p.startswith(dist_site), sys.path))

    # add virtualenv site
    # ADD2: insert(0 is wrong and breaks conformance of sys.path
    sys.path.insert(1, virtual_site)
  • ADD1: w oryginalnym skrypcie otrzymujemy obiekt filtru, przerywamy sys.path i wstawianie poniżej nie powiedzie się
  • ADD2: zobacz to pytanie i dokumentację Pythona
Fabio Scaccabarozzi
źródło
1

(Debian / Ubuntu) zakładając, że jest zainstalowana jakaś wersja (x) Python3, to:

$ sudo apt-get install -y ipython
$ virtualenv --python=python3.x .venv
$ source .venv/bin/activate
$ pip3 install ipython
$ ipython3

uruchomi ipython z Twoją wersją Python3.

mjkrause
źródło
1

Będę dzwonił po latach w nadziei, że ktoś uzna to za przydatne.

To rozwiązanie rozwiązuje kilka problemów:

  • Nie musisz instalować iPythona w aktualnym virtualenv, tylko dla globalnego Pythona, który pasuje do wersji Pythona twojego virtualenv (3.6 != 3.7 ).
  • Działa dla użytkowników, w pyenvktórych może znajdować się Twoja globalna wersja Pythona, 3.7a Twój lokalny virtualenv Python 3.6używa w związku z tym globalnegoipython zawiedzie.
  • Działa poza środowiskami wirtualnymi (choć niezbyt przydatne, ponieważ zawsze jest przeznaczone python).

Wrzuć to do swojego ~/.bashrclub ~/.zshrclub co masz:

# This is a roundabout way to start ipython from inside a virtualenv without it being installed
# in that virtualenv. The only caveot is that the "global" python must have ipython installed.
# What this function does that's different than simply calling the global ipython is it ensures to
# call the ipython that is installed for the same major.minor python version as in the virtualenv.
# This is most useful if you use pyenv for example as global python3 could be 3.7 and local
# virtualenv python3 is 3.6.
function ipy {
  local PY_BIN
  local IPYTHON
  local PYV
  # This quick way will work if ipython is in the virtualenv
  PY_BIN="$(python -c 'import sys; print(sys.executable)')"
  IPYTHON="$(dirname "$PY_BIN")/ipython"
  if [[ -x "$IPYTHON" ]]; then
    "$IPYTHON"
  else
    # Ask the current python what version it is
    PYV="$(python -c 'import sys; print(".".join(str(i) for i in sys.version_info[:2]))')"
    echo "Looking for iPython for Python $PYV"
    # In a new shell (where pyenv should load if equipped) try to find that version
    PY_BIN="$($SHELL -i -c "python$PYV -c 'import sys; print(sys.executable)'")"
    "$(dirname "$PY_BIN")/ipython"
  fi
}

Następnie sourcelub otwórz nowy terminal i uruchom ipy.

Skinner927
źródło