2015-04-07 2 views
6

Attualmente il progetto Django supporta 1.4, 1.7 e 1.8. Nel mio setup.py voglio riflettere queste versioni come supportate.Escludere determinati intervalli di versioni di dipendenza in setuptools/pip

install_requires=['Django>=1.4.2,<1.8.99,!=1.5,!=1.6'] 

Tuttavia, questo consente ancora le versioni 1.5.xe 1.6.x. Come posso escludere un intervallo completo?

Setuptools lists i seguenti requisiti validi come esempio:

PickyThing<1.6,>1.9,!=1.9.6,<2.0a0,==2.4c1 

Tuttavia, questo non funziona con pip (dovrebbe almeno partita 1.4.x/1.5.x):

No corrispondenza di distribuzione trovata per PickyThing! = 1.9.6, < 1.6, < 2.0a0, == 2.4c1,> 1,9

Aggiornamento con esempio
Ad esempio; Voglio solo includere currently supported versions of Django. Questo sarebbe 1.4.x, 1.7.xe 1.8.x. Quindi scriverei;

#setup.py 
install_requires=['Django>=1.4.2,<1.4.99,>=1.7,<1.8.99'] 

Tuttavia se corro pip install -e . su questo progetto, non riesce con;

Collecting Django<1.4.99,<1.8.99,>=1.4.2,>=1.7 (from ...) 
Could not find a version that satisfies the requirement Django<1.4.99,<1.8.99,>=1.4.2,>=1.7 (from django-two-factor-auth==1.2.0) (from versions: 1.1.3, 1.1.4, 1.2, 1.2.1, 1.2.2, 1.2.3, 1.2.4, 1.2.5, 1.2.6, 1.2.7, 1.3, 1.3.1, 1.3.2, 1.3.3, 1.3.4, 1.3.5, 1.3.6, 1.3.7, 1.4, 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.4.8, 1.4.9, 1.4.10, 1.4.11, 1.4.12, 1.4.13, 1.4.14, 1.4.15, 1.4.16, 1.4.17, 1.4.18, 1.4.19, 1.4.20, 1.5, 1.5.1, 1.5.2, 1.5.3, 1.5.4, 1.5.5, 1.5.6, 1.5.7, 1.5.8, 1.5.9, 1.5.10, 1.5.11, 1.5.12, 1.6, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.6.5, 1.6.6, 1.6.7, 1.6.8, 1.6.9, 1.6.10, 1.6.11, 1.7, 1.7.1, 1.7.2, 1.7.3, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.8a1, 1.8b1, 1.8b2, 1.8rc1, 1.8, 1.8.1) 
No matching distribution found for Django<1.4.99,<1.8.99,>=1.4.2,>=1.7 (from ...) 

E 'ovvio che un numero di versione 1.4.20 non può soddisfare >=1.7 e 1.8.1 non può soddisfare <1.4.99. Tuttavia, la documentazione di Setuptools (vedi sopra) suggerisce che qualcosa del genere dovrebbe essere possibile. Tuttavia, questo non è ovvio per me.

+0

Questo errore si verifica quando si fa cosa esattamente? – skyline75489

+0

@ skyline75489 vedi il mio aggiornamento. – bouke

+0

Quale versione di pip stai usando? – skyline75489

risposta

1

Ho letto qualche codice correlato di pkg_resources. Penso che il documento here non sia preciso. Non solo pip non riesce a trovare la giusta versione del pacchetto, python setup.py install, che effettivamente utilizza setuptools, anche fallisce.

Parte del codice relativo:

pip/_vendor/imballaggio/specifiers.py

# If we have any specifiers, then we want to wrap our iterable in the 
# filter method for each one, this will act as a logical AND amongst 
# each specifier. 
if self._specs: 
    for spec in self._specs: 
     iterable = spec.filter(iterable, prereleases=prereleases) 
    return iterable 

Si può vedere che nel commento, l'autore ha sottolineato che questo causerà un AND tra ogni specificatore, non OR. Quindi, se lo fai:

PickyThing<1.6,>1.9,!=1.9.6,<2.0a0,==2.4c1 

Non otterrai nulla!

ho provato con questo codice qui sotto:

import pkg_resources 

a = ['1.4', '1.8', '1.9.2'] 
d = pkg_resources.Requirement.parse('PickyThing<1.6,>1.9,!=1.9.6') 
r = d.specifier.filter(a) 

print(list(r)) # Nothing, just an empty list [] 

si consiglia di aprire un bug per pip in modo che possano risolvere il problema.

+0

Grazie per le indagini, assegnerò la taglia, una volta disponibile. Ho inviato [un bug report] (https://github.com/pypa/pip/issues/2744) a pip. – bouke

2

È possibile utilizzare Django>=1.4.2,<1.9,!=1.5.*,!=1.6.*

Questo è definito all'interno PEP440.

È possibile verificare questo comportamento con il modulo packaging che è stato distribuito all'interno delle ultime versioni di setuptools e pip.

In [1]: from packaging import specifiers 

In [2]: sp=specifiers.SpecifierSet(">=1.4.2,<1.9,!=1.5.*,!=1.6.*") 

In [3]: sp.contains("1.4.2") 
Out[3]: True 

In [4]: sp.contains("1.6.4") 
Out[4]: False 

In [5]: sp.contains("1.8.2") 
Out[5]: True 
+0

Questa sembra una buona alternativa, grazie! – bouke