Можно ли использовать tox с установками Python на основе conda?

Инструмент тестирования Python tox, похоже, разработан для работы с virtualenv. Может ли он также работать с установками Python на основе conda / anaconda?


person cmeeren    schedule 31.05.2015    source источник


Ответы (5)


Плагин tox-conda должен закрыть этот пробел в настоящее время, но ему нужны участники, которые активно используют conda для протестируйте и улучшите его.

из README:

tox-conda - это плагин, который обеспечивает интеграцию с пакетом conda и менеджером среды для tox инструмент автоматизации. Это все равно, что съесть свой торт и съесть его!

По умолчанию tox создает изолированные среды с помощью [virtualenv] (https://virtualenv.pypa.io] и устанавливает зависимости от pip.

Напротив, при использовании tox-conda подключаемый модуль tox будет использовать conda для создания сред и будет устанавливать указанные зависимости из conda. Это полезно для разработчиков, которые полагаются на conda для управления средой и распространения пакетов, но хотят воспользоваться функциями, предоставляемыми tox для автоматизации тестирования.

Чтобы установить этот плагин, он должен быть установлен вместе с tox в той же виртуальной среде. Для создания виртуальной среды, содержащей tox и tox-conda, этого должно быть достаточно:

$ python3 -m venv toxbase
$ toxbase/bin/pip install tox tox-conda
[...]
Successfully installed tox-3.13.2 tox-conda-0.2.0
$ toxbase/bin/tox --version
3.13.1 imported from /home/ob/tmp/toxbase/lib/python3.6/site-packages/tox/__init__.py
registered plugins:
    tox-conda-0.2.0 at /home/ob/tmp/toxbase/lib/python3.6/site-packages/tox_conda/plugin.py

с этого момента tox можно использовать как инструмент командной строки и поддерживать его актуальность, обновляя его в toxbase virtualenv. Другой, более автоматизированный способ - использовать pipx.

person Oliver Bestwalter    schedule 26.08.2019

Да, для этого вам потребуется установить virtualenv версию conda.

Попробуйте выполнить:

conda install virtualenv

virtualenv                15.1.0                   py36_

Перейдите в каталог проекта, содержащий tox.ini, и выполните:

tox
person sdayal    schedule 20.05.2017
comment
получение этой ошибки: TypeError: do_file() takes at least 4 arguments (3 given) - person avloss; 27.07.2017

Хотя tox не может использовать conda, вы можете использовать conda для «установки» различных версий Python, где tox может их найти (как если бы он находил «обычные» установки Python в этих папках). Следующее проверено в Windows:

  1. Вам необходимо virtualenv установить через pip в корневой среде conda. Я подозреваю, что это virtualenv, который будет использоваться tox. (Мне пришлось установить virtualenv, используя pip install virtualenv, чтобы команда virtualenv заработала, хотя conda list показал ее как установленную.)
  2. Установите версии Python, которые хотите протестировать. Это легко сделать с помощью conda create. tox будет автоматически определять двоичные файлы Python в Windows в C:\python27, C:\python33 и т. Д., Поэтому создавайте среды, используя conda create -p C:\python27 python=2.7 и т. Д.
person cmeeren    schedule 31.05.2015
comment
Похоже, не работает на OSX. У меня в корне conda установлен virtualenv, но при запуске tox происходят некоторые установки, но затем все становится КРАСНЫМ, и я получаю следующие ошибки: ОШИБКА: virtualenv несовместим с этой системой или исполняемым файлом. - person K.-Michael Aye; 28.07.2015
comment
Нет. Этот ответ не должен был не быть принят. На момент написания этой статьи нет хорошего ответа. ctox - ужасный взлом, а tox хорошо известен не для поддержки conda. conda и virtualenv - это конкурирующие решения одной и той же проблемы: подготовка среды Python. Ваш взлом гарантированно потерпит неудачу в распространенных крайних случаях. Боюсь, нам просто нужно подождать, пока tox официально не поддержит conda. - person Cecil Curry; 15.12.2015
comment
Спасибо за комментарий, @CecilCurry. Я обновил ответ, чтобы прояснить, что я имел в виду. Tox не может использовать conda, но conda можно использовать для установки Python туда, где tox может его использовать. - person cmeeren; 15.12.2015
comment
По этой проблеме могут быть некоторые подвижки: github.com/tox-dev/tox/issues / 273 - person winni2k; 22.09.2018

Я заставил tox и conda работать вместе в Windows:

  • Установка virtualenv с помощью conda в среде, которую я использую tox:

    conda install virtualenv

  • Создание «соединения каталогов» символические ссылки из C: \ PythonXY на мой фактический путь к среде. Это позволяет обойти InterpreterNotFound-ошибку:

    mklink /J C:\PythonXY C:\real\path\to\myPythonXYenv

Я установил Anaconda в E: \ Anaconda3 \ и все мои среды в E: \ Anaconda3 \ envs \, например E: \ Anaconda3 \ envs \ py27 \

(См. Ниже сценарий, который сделает это быстро и легко.)

Шаг 1. Создайте среду с помощью conda:

E:\dev> conda create -n py27 python=2.7 --yes
E:\dev> conda create -n py33 python=3.3 --yes
...
E:\dev> conda create -n py36 python=3.6 --yes

Шаг 2. Создайте все символические ссылки:

E:\dev> mklink /J C:\Python27 E:\Anaconda3\envs\py27
E:\dev> mklink /J C:\Python33 E:\Anaconda3\envs\py33
...
E:\dev> mklink /J C:\Python36 E:\Anaconda3\envs\py36

Примечание. Я вызываю conda create из каталога на электронном диске, поэтому параметр _9 _ / _ 10_ не требуется для установки новых сред в E: \ Anaconda3 \ envs \ .

Более простой способ:

Вместо того, чтобы выполнять громоздкий процесс настройки для каждой версии среды / Python, можно использовать класс ToxEnvMatcher, добавленный ниже следующим образом:

my_envs = os.path.join('E:\\', 'Anaconda3', 'envs')
tem = ToxEnvMatcher(my_envs)
for version in '27,34,35,36'.split(','):
    tem.make(version)

Изменить: чтобы упростить использование скрипта, я добавил новый раздел в файл (здесь предполагается, что это tox_with_conda.py), поэтому его можно вызвать из cmd.exe:

C:\dev> python tox_with_conda.py E:\Anaconda3\envs 27 34 35 36 37

Редактировать 2: также можно установить с помощью pip: pip install tox_with_conda и использовать как:

C:\dev> python -m tox_with_conda E:\Anaconda3\envs 27 34 35 36 37

Я использую Python 3.6.3 и tox 2.9.1, но не знаю, работают ли и более ранние версии.

Защита: я полагаю, что некоторым это кажется слишком громоздким процессом (хотя на самом деле это не так) или большим количеством взлома. Но имейте в виду, что возможность использовать Anaconda / conda также снижает трату времени на установку библиотек, пакетов, ++++.

Обратите внимание:

  • Я использую tox с pytest и не заметил никакого влияния на мои тесты.
  • Мои тесты просты, и есть вероятность, что я просто еще не сталкивался с проблемами.
  • Возможно, есть вещи, о которых я не думал, которые могут иметь отношение к другим.

Класс (также доступен здесь):

from subprocess import run
from os.path import join

DEFAULT_BASE = join('C:\\', 'Python')


class ToxEnvMatcher:
    """
    Utility to make conda environments work with tox.

    Conda envs might be in other locations than where `tox <https://tox.readthedocs.io>`_ expects them to be.

    A symbolic link 'Directory Junction' is created from expected location to the actual location.
    Intended for Windows to get around the ``InterpreterNotFound``-error.

    E.g.: tox expects to find Python 2.7 in ``C:\Python27``,
    but may actually be installed in another drive and location.

    Examples of use:

    .. code-block:: python

        my_envs = join('E:\\', 'Anaconda3', 'envs')
        tem = ToxEnvMatcher(my_envs)
        for version in '27,34,35,36'.split(','):
            tem.make(version)

    The class is utilized through ``argsparse`` so it can also be used from cmd.exe.

    Examples of use of th of using ``ToxEnvMatcher`` from cmd.exe:

    .. code-block:: none

        E:\dev> tox_with_conda.py E:\Anaconda3\envs 27 34 35 36 37

    It's possible to use the ``-b``/``--base`` option to override the default base location (``C:\Python``):

    .. code-block:: none

        E:\dev> tox_with_conda.py E:\Anaconda3\envs 27 34 35 36 37 --base D:\Python

    :param str envs_dir: The path to where new conda environments will be created
    :param str default_base: The base of the 'default' location. Usually it's ``C:\Python``
    """
    def __init__(self, envs_dir, default_base=DEFAULT_BASE):
        self.envs_dir = envs_dir
        self.default_base = default_base

    def __repr__(self):
        return '{}({})'.format(self.__class__.__name__, self.envs_dir)

    def make(self, version):
        """
        Take version and create conda environment with symlink from 'default tox location'.

        E.g.: given version='27' and environment folder ``{self.envs_dir}``:

         - ``conda create -p {self.envs_dir}\py27 python=2.7``
         - ``mklink /J C:\Python27 {self.envs_dir}\py27``

        :param str version: A string on the form 'XY', e.g. '27' or '36'
        :return: None
        :rtype: NoneType
        """
        if len(version) != 2 or not int(version):
            raise ValueError("Parameter 'version' must be on the form 'XY', and not '{}'".format(version))
        conda_cmd = self._create_cmd_args(version)
        symlink_cmd = self._create_symlink_args(version)
        run(conda_cmd, shell=True)
        run(symlink_cmd, shell=True)

    def _get_env_folder(self, version):
        return join(self.envs_dir, 'py{}'.format(version))

    def _create_cmd_args(self, version):
        env_dir = self._get_env_folder(version)
        python_version = '.'.join(version)
        conda_create = 'conda create -p {} python={} --yes'.format(env_dir, python_version)
        return conda_create.split(' ')

    def _create_symlink_args(self, version):
        env_dir = self._get_env_folder(version)
        return 'mklink /J {}{} {}'.format(self.default_base, version, env_dir).split(' ')

Добавленный код для его работы из cmd:

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument("env_dir",
                        help="The folder where conda environments should be installed.")
    parser.add_argument("versions", nargs='*',
                        help="The list of versions, formatted 'XY' where X is major and Y minor. E.g. '27 35 36'")
    parser.add_argument("-b", "--base", default=DEFAULT_BASE,
                        help="Base of the path which tox expects to find Python installed. "
                             "Default: {}.".format(DEFAULT_BASE))
    args = parser.parse_args()

    print('env_dir: ', args.env_dir)
    print('versions: ', args.versions)
    print('--base: ', args.base)

    tem = ToxEnvMatcher(args.env_dir, default_base=args.base)
    for version in args.versions:
        tem.make(version)
person Thomas Fauskanger    schedule 06.12.2017

Не знаю, насколько он развит, но вы можете посмотреть https://github.com/hayd/ctox < / а>.

person asmeurer    schedule 01.06.2015