полностью автономная виртуальная среда

Я создаю виртуальную среду python3 (явно избегая символических ссылок с --copies):

» python3 -m venv --without-pip --copies venv

Теперь это моя полная виртуальная среда:

» tree venv/
venv/
├── bin
│   ├── activate
│   ├── activate.csh
│   ├── activate.fish
│   ├── python
│   └── python3
├── include
├── lib
│   └── python3.4
│       └── site-packages
├── lib64 -> lib
└── pyvenv.cfg

Я отключаю PYTHONPATH, чтобы убедиться, что снаружи ничего не протекает:

» PYTHONPATH=""

Активируйте венв:

» source venv/bin/activate

Убедитесь, что activate не загрязнил мой PYTHONPATH:

» echo $PYTHONPATH

(пусто, как и ожидалось)

Я использую правильный питон:

» which python
/foo/bar/venv/bin/python

Но к системным модулям все еще обращаются:

» python 
Python 3.4.3 (default, Oct 14 2015, 20:28:29) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import unittest
>>> print(unittest)
<module 'unittest' from '/usr/lib/python3.4/unittest/__init__.py'>
>>> 

Я ожидал, что оператор import unittest завершится ошибкой, поскольку в виртуальной среде такого модуля нет.

Я бы хотел знать:

  • Почему доступ к системным пакетам осуществляется в виртуальном окружении?
  • Как я могу создать полностью автономную виртуальную среду?

person blueFast    schedule 27.01.2016    source источник


Ответы (1)


Если я правильно помню, основные системные пакеты связаны символическими ссылками, поэтому они являются одними и теми же файлами (частично для уменьшения размера virtualenv).

По умолчанию каталог site-packages не включается, поэтому он не будет обращаться к сторонним библиотекам, которые были установлены.

Если вы хотите по-настоящему изолированную и автономную виртуальную среду, возможно, вам лучше взглянуть на docker.

Virtualenv - это действительно более легкий способ управления различными сторонними установленными пакетами для разных приложений.

РЕДАКТИРОВАТЬ:

Похоже, что --always-copy на самом деле не всегда копирует все файлы:

virtualenv не копирует все файлы .py из каталог lib / python

Копаемся в исходный код, и похоже, что есть небольшой набор модулей, которые считаются «необходимыми», и это те, которые были скопированы:

https://github.com/pypa/virtualenv/blob/ac4ea65b14270caeac56b1e1e64c56928037ebe2/virtualenv.py#L116

Изменить 2:

Вы можете видеть, что старые каталоги python все еще появляются в sys.path, но после каталогов для самого virtualenv:

>>> import sys
>>> sys.path
['', '/home/john/venv/lib/python2.7', 
'/home/john/venv/lib/python2.7/plat-linux2', 
'/home/john/venv/lib/python2.7/lib-tk',
'/home/john/venv/lib/python2.7/lib-old', 
'/home/john/venv/lib/python2.7/lib-dynload', '/usr/lib/python2.7',
'/usr/lib/python2.7/plat-linux2',
'/usr/lib/python2.7/lib-tk',
'/home/john/venv/local/lib/python2.7/site-packages',
'/home/john/venv/lib/python2.7/site-packages']
person John Montgomery    schedule 27.01.2016
comment
Обратите внимание, что я использую --copies: никакие символические ссылки не используются (как видно в дереве каталогов). Docker не подходит для моих нужд: я могу жить в этой ситуации, но я хочу разобраться в фоновых проблемах. Может быть, встроенный PYTHONPATH в системный двоичный файл python (который копируется в virtualenv)? Как это сделать? Системный двоичный файл python устанавливается (в данном случае) с помощью apt get, поэтому как двоичный файл python узнает, где он установлен (особенно после копирования!)? - person blueFast; 27.01.2016
comment
Не заметил там --copies. Я тестировал использование --always-copy локально (--copies старое имя?), И это копирует файлы, но, как ни странно, не для unittest. Если вы попробуете тот же тест для модуля os, вы увидите, что это правильный путь. - person John Montgomery; 27.01.2016
comment
У меня нет варианта --always-copy, но --copies. Не знаю, кто старше. Я использую Python 3.4.3, а вы? - person blueFast; 28.01.2016
comment
И спасибо за ваше объяснение. Он поясняет почему определенные пакеты не копируются с помощью virtualenv (для меня ничего не копируется, кто знает почему), но я все же хотел бы знать, как python в virtualenv может использовать системные пакеты (например, модульный тест) - person blueFast; 28.01.2016
comment
На самом деле я пробовал это с помощью virtualenv 13.1.2 (в Linux), но документы, похоже, относятся только к --always-copy. Странный. - person John Montgomery; 28.01.2016
comment
Старый питон все еще упоминается в PYTHONPATH - возможно, жестко запрограммирован в двоичном формате. - person John Montgomery; 28.01.2016
comment
Хорошо понял. Как вы говорите, вероятно, встроен в двоичный файл python во время компиляции. Как уже упоминалось, мой python установлен с помощью apt, поэтому я использую предварительно скомпилированные пакеты. Однако кажется странным, что такая информация об этапе установки жестко запрограммирована в двоичном коде: это делает каталог установки для двоичного файла не совсем перемещаемым (так что в основном его можно правильно установить только по пути, жестко запрограммированному во время компиляции) - person blueFast; 28.01.2016
comment
Вы можете использовать --relocatable, чтобы сделать virtualenv подвижным. Однако довольно часто двоичные файлы имеют жестко заданный путь к библиотеке, поскольку это означает, что вы можете установить несколько версий с разными закодированными в них путями. Тогда все работает так, как ожидалось. - person John Montgomery; 28.01.2016
comment
Спасибо, я знаю про --relocatable, но это совсем другое дело. Что меня раздражает, так это то, что сам двоичный файл python (а не virtualenv) имеет жестко заданную зависимость от пути установки, что его не касается. Я тот, кто устанавливает его везде, где считаю нужным (или apt в случае системного питона, или virtualenv в случае питона virtualenv). - person blueFast; 28.01.2016
comment
Меня бы меньше раздражало, что python имеет жестко запрограммированную относительную ссылку на путь lib, но не на абсолютный путь. Я предполагаю, что это соглашения linux / unix, и, безусловно, есть объяснение, почему это так (моя последняя установка linux с нуля была сделана некоторое время назад), но это все еще удивительно. - person blueFast; 28.01.2016