web-dev-qa-db-ja.com

condaベースのPythonインストールでtoxを使用することは可能ですか?

Pythonテストツールtoxはvirtualenvで動作するように設計されているようです。conda/ anacondaベースのPythonインストールでも動作しますか?

24
cmeeren

Toxはcondaを利用できませんが、condaを使用してさまざまなPythonバージョンをtoxが見つけることができるバージョンを「インストール」することができます(「通常」を見つけるようにPythonこれらのフォルダへのインストール)。以下はWindowsでテストされています。

  1. ルートコンダ環境にvirtualenvを介してpipをインストールする必要があります。これがtoxで使用されるvirtualenvだと思います。 (pip install virtualenvがインストール済みとして表示されていても、virtualenvコマンドを機能させるには、conda listを使用してvirtualenvをインストールする必要がありました。)
  2. テストするPythonバージョンをインストールします。これは、conda createを使用して簡単に実行できます。toxはWindowsでPythonバイナリを自動検出しますC:\python27C:\python33などで、conda create -p C:\python27 python=2.7などを使用して環境を作成します。
5
cmeeren

はい、これを機能させるには、virtualenvのc​​ondaバージョンをインストールする必要があります。

実行してみてください:

conda install virtualenv

virtualenv                15.1.0                   py36_

tox.iniを含むプロジェクトディレクトリに移動し、以下を実行します。

tox
6
sdayal

tox-conda プラグインは、最近そのギャップを埋めるはずですが、condaを積極的に使用してテストおよび改善する貢献者が必要です。

rEADMEから:

tox-condaは、 conda パッケージおよび tox 自動化ツールの環境マネージャーとの統合を提供するプラグインです。それはあなたのケーキを持ってそれを食べるようなものです!

デフォルトでは、toxは[virtualenv]( https://virtualenv.pypa.io] を使用して分離された環境を作成し、pipから依存関係をインストールします。

対照的に、tox-condaプラグインを使用する場合、toxcondaを使用して環境を作成し、condaから指定された依存関係をインストールします。これは、環境管理とパッケージ配布にcondaを使用しているが、テスト自動化にtoxが提供する機能を利用したい開発者にとって便利です。

そのプラグインをインストールするには、同じ仮想環境にtoxと一緒にインストールする必要があります。 toxtox-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はコマンドラインツールとして使用でき、toxbasevirtualenvでアップグレードすることで最新の状態に保つことができます。もう1つの、より自動化された方法は、 pipx を使用することです。

6

私はtoxとcondaをWindowsで一緒に動作させました:

  • virtualenvを使用する環境にcondaを使用してtoxをインストールする:

    conda install virtualenv

  • 「ディレクトリジャンクション」の作成 symlinks 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

注:Eドライブのディレクトリからconda createを呼び出すので、--prefix/-pオプションE:\ Anaconda3\envs \に新しい環境をインストールするために必要ありません。

より簡単な方法:

環境/ Pythonバージョンごとにこれを設定する面倒なプロセスを実行する代わりに、次の方法でさらに下に追加されたToxEnvMatcher- classを使用できます。

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

編集:スクリプトを使いやすくするために、 ファイル に新しいセクションを追加しました(ここではbetox_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およびtox2.9.1を使用していますが、以前のバージョンでも機能するかどうかはわかりません。

防御:一部の人にとっては、これは面倒なプロセスのように思えるか(実際にはそうではありません)、またはハックの多くに思えます。ただし、Anaconda/condaを使用できると、ライブラリ、パッケージ、++++のインストールに費やす時間の無駄も減ることに注意してください。

注意してください

  • 私はpytestでtoxを使用していますが、テストへの影響に気づいていません。
  • 私のテストは単純で、まだ問題にさらされていない可能性があります。
  • おそらく、他の人に関係があるかもしれないと私が考えていなかったことがあります。

クラス(利用可能 ここ ):

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)
4

それがどのように開発されているかはわかりませんが、 https://github.com/hayd/ctox を見ることができます。

3
asmeurer