2015-05-31 24 views

risposta

4

Mentre tox non può fare uso di conda, è possibile utilizzare conda per "installare" diverse versioni di Python dove tox può trovarle (come se trovasse "normali" installazioni Python in quelle cartelle). Quanto segue è testato su Windows:

  1. È necessario virtualenv installato tramite pip nell'ambiente radice Conda. Sospetto che questo sia il virtualenv che verrà usato da tossicodipendenza. (Ho dovuto installare virtualenv usando pip install virtualenv per far funzionare il comando virtualenv, anche se conda list lo ha mostrato come installato.)
  2. Installa le versioni di Python che vuoi testare. Questo è fatto facilmente usando conda create. tox sarà rilevare automaticamente i binari Python su Windows in C:\python27, C:\python33, ecc, in modo creare ambienti utilizzando conda create -p C:\python27 python=2.7 ecc
+1

non sembra di lavorare su OSX.I avere virtualenv installato nella root conda, ma quando si avvia 'tox', alcune installazioni stanno accadendo ma poi le cose diventano RED e ottengo questi errori: ERRORE: virtualenv non è compatibile con questo sistema o eseguibile. –

+5

** No. ** Questa risposta non dovrebbe essere stata accettata. Al momento, non c'è una buona risposta. ['ctox'] (https://github.com/hayd/ctox) è un trucco orribile, mentre' tox' è ben noto [_non_ per supportare 'conda'] (https: // bitbucket.org/hpk42/Tox/problemi/273/supporto-Conda-ENV-quando-con-miniconda). 'conda' e' virtualenv' sono soluzioni concorrenti allo stesso problema: provisioning dell'ambiente Python. Il tuo hack è garantito per fallire in casi limite comuni. Dovremo solo aspettare che 'tox' supporti ufficialmente' conda', temo. –

+4

Grazie per il commento, @CecilCurry. Ho aggiornato la risposta per chiarire cosa intendevo. Tox non può usare conda, ma conda può essere usato per installare Python su dove tox può farne uso. – cmeeren

4

Sì, è necessario installare la versione conda di virtualenv affinché funzioni.

Prova:

>conda install virtualenv

virtualenv    15.1.0     py36_ 

Passare alla directory del progetto contenente tox.ini

>tox

+0

ottenendo questo errore: 'TypeError: do_file() richiede almeno 4 argomenti (3 dati)' – avloss

1

ho fatto tox e Conda lavorare insieme in Windows:

  • Installazione virtualenv con Conda nell'ambiente che uso tox:

    conda install virtualenv

  • Creazione "Directory Junction" symlinks da C: \ PythonXY al mio percorso di ambiente reale. Questo aggira il InterpreterNotFound -Errore:

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

Ho installato Anaconda in E: \ Anaconda3 \, e tutti i miei ambienti in E: \ Anaconda3 \ ENV \, per esempio E: \ Anaconda3 \ envs \ py27 \

(Vedere sotto per un script per rendere questo rapido e facile.)

Fase 1 - Creare ambienti con 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 

Fase 2 - Creare tutti i link simbolici:

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 

Nota: io chiamo conda create da una directory su l'E-Drive, quindi l'opzione --prefix/-p non è necessaria per installare un nuovo ambiente ts in E: \ Anaconda3 \ envs \.

un modo più semplice:

Invece di passare attraverso il processo ingombrante di impostarlo per ciascuna versione ambiente/pitone, si può usare il -class ToxEnvMatcher aggiunto più in basso in questo modo:

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

Modifica: per rendere lo script più facile da usare, ho aggiunto una nuova sezione al file, (qui si presume sia tox_with_conda.py,) in modo che possa essere chiamato da cmd.exe:

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

sto usando Python 3.6.3 e 2.9.1 tox, ma non so quando/se le versioni precedenti funzionano anche.

Difesa: suppongo che per alcuni, questo mi sembra un processo troppo ingombrante (in realtà non è, però), o per gran parte di un hack. Ma tieni presente che la possibilità di utilizzare Anaconda/conda riduce anche lo spreco di tempo speso cercando di installare librerie, pacchetti, ++++.

Si prega di notare:

  • I Uso Telefono con pytest, e non hanno notato alcun impatto sui miei test.
  • I miei test sono semplici e c'è la possibilità che non sia stato ancora esposto a problemi.
  • Assumabile, ci sono cose che non ho pensato che potrebbero essere rilevanti per gli altri.

La classe (disponibile anche here):

from subprocess import run 
from os.path import join 

from sphinx.addnodes import desc 

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(' ') 

Il codice aggiunto per farlo funzionare da 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)