8000 First use python_requires to determine support, otherwise classifiers · hugovk/drop-python@813fdbc · GitHub
[go: up one dir, main page]

Skip to content

Commit 813fdbc

Browse files
committed
First use python_requires to determine support, otherwise classifiers
1 parent 3e972e2 commit 813fdbc

File tree

2 files changed

+102
-12
lines changed

2 files changed

+102
-12
lines changed

test_utils.py

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
import utils
1010

1111

12-
class TestIt(unittest.TestCase):
12+
class TestClassifiersSupport(unittest.TestCase):
1313

14-
def test_supports_has_support(self):
14+
def test_has_support(self):
1515
# Arrange
1616
classifiers = [
1717
"Programming Language :: Python",
@@ -31,7 +31,7 @@ def test_supports_has_support(self):
3131
# Assert
3232
self.assertEqual(has_support, "yes")
3333

34-
def test_supports_no_support_but_others_are(self):
34+
def test_no_support_but_others_are(self):
3535
# Arrange
3636
classifiers = [
3737
"Programming Language :: Python",
@@ -49,7 +49,7 @@ def test_supports_no_support_but_others_are(self):
4949
# Assert
5050
self.assertEqual(has_support, "no")
5151

52-
def test_supports_no_support_but_other_2x_are(self):
52+
def test_no_support_but_other_2x_are(self):
5353
# Arrange
5454
classifiers = [
5555
"Programming Language :: Python",
@@ -63,7 +63,7 @@ def test_supports_no_support_but_other_2x_are(self):
6363
# Assert
6464
self.assertEqual(has_support, "no")
6565

66-
def test_supports_no_support_but_other_3x_are(self):
66+
def test_no_support_but_other_3x_are(self):
6767
# Arrange
6868
classifiers = [
6969
"Programming Language :: Python",
@@ -79,7 +79,7 @@ def test_supports_no_support_but_other_3x_are(self):
7979
# Assert
8080
self.assertEqual(has_support, "no")
8181

82-
def test_supports_no_support_or_any_major_minor(self):
82+
def test_maybe_support_or_any_major_minor(self):
8383
# Arrange
8484
# No major.minor classifiers
8585
classifiers = [
@@ -88,25 +88,88 @@ def test_supports_no_support_or_any_major_minor(self):
8888
]
8989

9090
# Act
91-
# Classifiers are not explicit: we want to assume support
9291
has_support = utils.classifiers_support(classifiers, "2.6")
9392

9493
# Assert
9594
self.assertEqual(has_support, "maybe")
9695

97-
def test_supports_no_support_for_empty(self):
96+
def test_maybe_support_for_empty(self):
9897
# Arrange
9998
# No classifiers
10099
classifiers = []
101100

102101
# Act
103-
# Classifiers are not explicit: we want to assume support
104102
has_support = utils.classifiers_support(classifiers, "2.6")
105103

106104
# Assert
107105
self.assertEqual(has_support, "maybe")
108106

109107

108+
class TestRequiresPythonSupports(unittest.TestCase):
109+
110+
def test_has_support(self):
111+
# Arrange
112+
python_requires = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
113+
114+
# Act
115+
has_support = utils.requires_python_supports(python_requires, "2.6")
116+
117+
# Assert
118+
self.assertEqual(has_support, "yes")
119+
120+
def test_no_support_but_others_are(self):
121+
# Arrange
122+
python_requires = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
123+
124+
# Act
125+
has_support = utils.requires_python_supports(python_requires, "2.6")
126+
127+
# Assert
128+
self.assertEqual(has_support, "no")
129+
130+
def test_no_support_but_other_2x_are(self):
131+
# Arrange
132+
python_requires = "==2.7"
133+
134+
# Act
135+
has_support = utils.requires_python_supports(python_requires, "2.6")
136+
137+
# Assert
138+
self.assertEqual(has_support, "no")
139+
140+
def test_no_support_but_other_3x_are(self):
141+
# Arrange
142+
python_requires = ">=3.4"
143+
144+
# Act
145+
has_support = utils.requires_python_supports(python_requires, "2.6")
146+
147+
# Assert
148+
self.assertEqual(has_support, "no")
149+
150+
def test_maybe_support_for_none(self):
151+
# Arrange
152+
# No python_requires
153+
python_requires = None
154+
155+
# Act
156+
has_support = utils.requires_python_supports(python_requires, "2.6")
157+
158+
# Assert
159+
self.assertEqual(has_support, "maybe")
160+
161+
def test_maybe_support_for_empty(self):
162+
# Arrange
163+
# No python_requires
164+
python_requires = ""
165+
166+
# Act
167+
has_support = utils.requires_python_supports(python_requires, "2.6")
168+
169+
# Assert
170+
self.assertEqual(has_support, "maybe")
171+
172+
110173
if __name__ == '__main__':
111174
unittest.main()
112175

utils.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
from __future__ import print_function, unicode_literals
2+
23
import datetime
34
import json
5+
46
import pytz
57
import requests
6-
8+
from pip._vendor.packaging import specifiers
79

810
BASE_URL = 'https://pypi.python.org/pypi'
911

@@ -42,6 +44,24 @@ def get_json_url(package_name):
4244
return BASE_URL + '/' + package_name + '/json'
4345

4446

47+
def requires_python_supports(requires_python, version):
48+
"""
49+
Check if a given Python version matches the `requires_python` specifier.
50+
51+
Returns "yes" if the version of Python matches the requirement.
52+
Returns "no" if the version of Python does not matches the requirement.
53+
Returns "maybe" if there's no requirement.
54+
55+
Raises an InvalidSpecifier if `requires_python` have an invalid format.
56+
"""
57+
if requires_python is None or requires_python == "":
58+
# The package provides no information
59+
return "maybe"
60+
requires_python_specifier = specifiers.SpecifierSet(requires_python)
61+
62+
return "yes" if version in requires_python_specifier else "no"
63+
64+
4565
def classifiers_support(classifiers, version):
4666
"""Do these classifiers support this Python version?"""
4767
desired_classifier = CLASSIFIER.format(version)
@@ -80,8 +100,15 @@ def annotate_support(packages, versions=['2.6']):
80100
# Init
81101
package[version] = {}
82102

83-
has_support = classifiers_support(data['info']['classifiers'],
84-
version)
103+
# First try with requires_python
104+
has_support = requires_python_supports(
105+
data['info']['requires_python'], version)
106+
107+
# Second try with classifers
108+
if has_support == 'maybe':
109+
has_support = classifiers_support(
110+
data['info']['classifiers'], version)
111+
85112
if has_support == "yes":
86113
package[version]['dropped_support'] = "no"
87114
if has_support == "no":

0 commit comments

Comments
 (0)
0