2015-04-07 15 views
6

Obecnie projekt Django obsługuje wersje 1.4, 1.7 i 1.8. W moim setup.py chcę odzwierciedlić te wersje jako obsługiwane.Wyklucz pewne zakresy wersji zależności w setuptools/pip

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

Jednak nadal pozwala na wydania 1.5.x i 1.6.x. Jak mogę wykluczyć pełen zakres?

Setuptools lists następujące ważne wymagania jako przykład:

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

Jednak to nie zadziała z PIP (to powinien przynajmniej mecz 1.4.x/1.5.x):

Nie dopasowanie rozkładu znalezionych dla PickyThing! = 1.9.6, 1.6, < < 2.0a0, == 2.4c1,> 1,9

Aktualizacja z przykładem
Na przykład; Chcę tylko dołączyć currently supported versions of Django. Byłby to 1,4.x, 1,7.x i 1,8.x. Napisałem więc;

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

Jednak jeśli uruchomię pip install -e . tego projektu, nie powiedzie się;

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

Jest oczywiste, że numer wersji 1.4.20 nie może zaspokoić >=1.7 i 1.8.1 nie mogą zaspokoić <1.4.99. Jednak dokumentacja z Setuptools (patrz wyżej) sugeruje, że coś podobnego powinno być możliwe. Jednak dla mnie to nie jest oczywiste.

+0

Ten błąd występuje, gdy robisz co dokładnie? – skyline75489

+0

@ skyline75489 zobacz moją aktualizację. – bouke

+0

Którą używasz wersji pip? – skyline75489

Odpowiedz

1

Czytałem jakiś powiązany kod z pkg_resources. Myślę, że dokument here nie jest dokładny. Nie tylko pip nie uda się znaleźć odpowiedniej wersji pakietu, python setup.py install, która faktycznie używa setuptools, również zawiedzie.

Niektóre powiązanego kodu:

pip/_vendor/opakowań/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 

Widać, że w komentarzu, autor podkreślił, że będzie to powodować AND wśród każdy specyfikator, a nie OR. Jeśli więc to zrobisz:

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

Nic nie dostaniesz!

Próbowałem z tego kodu poniżej:

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 [] 

Możesz zgłosić błąd do pip więc mogą go naprawić.

+0

Dzięki za śledztwo, nagrodzę nagrodę, gdy tylko będzie dostępna. Przesłałem [raport błędu] (https://github.com/pypa/pip/issues/2744) do pip. – bouke

2

Można użyć Django>=1.4.2,<1.9,!=1.5.*,!=1.6.*

ta jest zdefiniowana wewnątrz PEP440.

Możesz przetestować to zachowanie za pomocą modułu packaging, który jest sprzedawany w ostatnich wersjach setuptools and 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

To wygląda na dobrą alternatywę, dzięki! – bouke