2014-06-25 7 views
5

Esiste un modo standard per consentire il fallimento di un pacchetto python in uno script di installazione dei pacchetti?Permettere il fallimento di un pacchetto Python nell'installazione

Sto creando un pacchetto simile a Python Social Auth in quanto ha un numero di provider.

Esiste un modo standard per consentire il fallimento dei requisiti di installazione di alcuni provider, ma l'installazione del pacchetto è ancora soddisfacente?

+0

possibile duplicato del [Posso definire pacchetti opzionali in setuptools?] (http://stackoverflow.com/questions/11240285/can-i-define-optional-packages-in-setuptools) ... anche se la risposta di @ Jonathan-Villemaire-Krajden fornisce alcuni dettagli aggiuntivi – Stefano

risposta

4

dipendenze opzionale specificato dall'utente al momento dell'installazione:

È possibile utilizzare il parametro extras_require-setup(): http://pythonhosted.org/setuptools/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies

setup(
    name="MyProject", 
    ... 
    extras_require = { 
     'ProviderX': ["DependencyX1", "DependencyX2"], 
     'ProviderY': ["DependencyY"], 
    } 
) 

Con questo metodo, l'utente può chiedere di installare estensioni specifiche pip install Myproject[ProviderX].

dipendenze opzionali basati su pacchetti esistenti:

Al fine di rilevare automaticamente i pacchetti installati, si può costruire l'elenco dei requisiti in modo dinamico. Ad esempio, puoi vedere come fa matplotlib (hanno molti backend opzionali per il tracciamento tra gli altri): https://github.com/matplotlib/matplotlib.

Fondamentalmente, setup.py è solo un normale codice Python, quindi è possibile eseguire una funzione che verifica le dipendenze opzionali e regolare i requisiti e l'elenco dei pacchetti da installare di conseguenza.

Il modo in cui questo fa matplotlib definisce una classe per le dipendenze che estende per ciascuna dipendenza (in setupExt.py).

class SetupPackage(object): 
    optional = False 

    def check(self): 
     """ 
     Checks whether the dependencies are met. [...] 
     """ 
     pass 

    def get_packages(self): 
     """ 
     Get a list of package names to add to the configuration. 
     These are added to the `packages` list passed to 
     `distutils.setup`. 
     """ 
     return [] 

    def get_namespace_packages(self): 
     """ 
     Get a list of namespace package names to add to the configuration. 
     These are added to the `namespace_packages` list passed to 
     `distutils.setup`. 
     """ 
     return [] 


    def get_py_modules(self): 
     """ 
     Get a list of top-level modules to add to the configuration. 
     These are added to the `py_modules` list passed to 
     `distutils.setup`. 
     """ 
     return [] 

    ... 

class Numpy(SetupPackage): 
    ... 

E poi itera su ogni dipendenza in setup.py, controlla se dovrebbe essere installato, e si estende di conseguenza ogni lista da passare al setup()

mpl_packages = [ 
    'Building Matplotlib', 
    setupext.Six(), 
    setupext.Dateutil(), 
    ... 

good_packages = [] 
for package in mpl_packages: 
    [...] 
    # check and append 
    if ... 
     good_packages.append(package) 

[...] 
for package in good_packages: 
    if isinstance(package, str): 
     continue 
    packages.extend(package.get_packages()) 
    namespace_packages.extend(package.get_namespace_packages()) 
    py_modules.extend(package.get_py_modules()) 
    ext = package.get_extension()