Skip to content

Commit 80d136a

Browse files
didstufft
andauthored
Add support for PEP 700 (#12727)
* Change API version to 1.1 * Fix flaky test * Add versions field * Add file size field * Add file upload-time field --------- Co-authored-by: Donald Stufft <[email protected]>
1 parent f096db0 commit 80d136a

File tree

3 files changed

+32
-12
lines changed

3 files changed

+32
-12
lines changed

Diff for: tests/common/db/packaging.py

+1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class Meta:
111111
]
112112
)
113113
)
114+
size = factory.Faker("pyint")
114115

115116

116117
class RoleFactory(WarehouseFactory):

Diff for: tests/unit/api/test_simple.py

+26-11
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
import pretend
1414
import pytest
1515

16+
from packaging.version import parse
1617
from pyramid.httpexceptions import HTTPMovedPermanently
1718
from pyramid.testing import DummyRequest
1819

1920
from warehouse.api import simple
21+
from warehouse.packaging.utils import API_VERSION
2022

2123
from ...common.db.accounts import UserFactory
2224
from ...common.db.packaging import (
@@ -81,7 +83,7 @@ class TestSimpleIndex:
8183
def test_no_results_no_serial(self, db_request, content_type, renderer_override):
8284
db_request.accept = content_type
8385
assert simple.simple_index(db_request) == {
84-
"meta": {"_last-serial": 0, "api-version": "1.0"},
86+
"meta": {"_last-serial": 0, "api-version": API_VERSION},
8587
"projects": [],
8688
}
8789
assert db_request.response.headers["X-PyPI-Last-Serial"] == "0"
@@ -99,7 +101,7 @@ def test_no_results_with_serial(self, db_request, content_type, renderer_overrid
99101
user = UserFactory.create()
100102
je = JournalEntryFactory.create(submitted_by=user)
101103
assert simple.simple_index(db_request) == {
102-
"meta": {"_last-serial": je.id, "api-version": "1.0"},
104+
"meta": {"_last-serial": je.id, "api-version": API_VERSION},
103105
"projects": [],
104106
}
105107
assert db_request.response.headers["X-PyPI-Last-Serial"] == str(je.id)
@@ -119,7 +121,7 @@ def test_with_results_no_serial(self, db_request, content_type, renderer_overrid
119121
for x in [ProjectFactory.create() for _ in range(3)]
120122
]
121123
assert simple.simple_index(db_request) == {
122-
"meta": {"_last-serial": 0, "api-version": "1.0"},
124+
"meta": {"_last-serial": 0, "api-version": API_VERSION},
123125
"projects": [
124126
{"name": x[0], "_last-serial": 0}
125127
for x in sorted(projects, key=lambda x: x[1])
@@ -147,7 +149,7 @@ def test_with_results_with_serial(
147149
je = JournalEntryFactory.create(submitted_by=user)
148150

149151
assert simple.simple_index(db_request) == {
150-
"meta": {"_last-serial": je.id, "api-version": "1.0"},
152+
"meta": {"_last-serial": je.id, "api-version": API_VERSION},
151153
"projects": [
152154
{"name": x[0], "_last-serial": 0}
153155
for x in sorted(projects, key=lambda x: x[1])
@@ -187,9 +189,10 @@ def test_no_files_no_serial(self, db_request, content_type, renderer_override):
187189
JournalEntryFactory.create(submitted_by=user)
188190

189191
assert simple.simple_detail(project, db_request) == {
190-
"meta": {"_last-serial": 0, "api-version": "1.0"},
192+
"meta": {"_last-serial": 0, "api-version": API_VERSION},
191193
"name": project.normalized_name,
192194
"files": [],
195+
"versions": [],
193196
}
194197

195198
assert db_request.response.headers["X-PyPI-Last-Serial"] == "0"
@@ -210,9 +213,10 @@ def test_no_files_with_serial(self, db_request, content_type, renderer_override)
210213
je = JournalEntryFactory.create(name=project.name, submitted_by=user)
211214

212215
assert simple.simple_detail(project, db_request) == {
213-
"meta": {"_last-serial": je.id, "api-version": "1.0"},
216+
"meta": {"_last-serial": je.id, "api-version": API_VERSION},
214217
"name": project.normalized_name,
215218
"files": [],
219+
"versions": [],
216220
}
217221

218222
assert db_request.response.headers["X-PyPI-Last-Serial"] == str(je.id)
@@ -229,6 +233,7 @@ def test_with_files_no_serial(self, db_request, content_type, renderer_override)
229233
db_request.accept = content_type
230234
project = ProjectFactory.create()
231235
releases = [ReleaseFactory.create(project=project) for _ in range(3)]
236+
release_versions = sorted([r.version for r in releases], key=parse)
232237
files = [
233238
FileFactory.create(release=r, filename=f"{project.name}-{r.version}.tar.gz")
234239
for r in releases
@@ -242,15 +247,18 @@ def test_with_files_no_serial(self, db_request, content_type, renderer_override)
242247
JournalEntryFactory.create(submitted_by=user)
243248

244249
assert simple.simple_detail(project, db_request) == {
245-
"meta": {"_last-serial": 0, "api-version": "1.0"},
250+
"meta": {"_last-serial": 0, "api-version": API_VERSION},
246251
"name": project.normalized_name,
252+
"versions": release_versions,
247253
"files": [
248254
{
249255
"filename": f.filename,
250256
"url": f"/file/{f.filename}",
251257
"hashes": {"sha256": f.sha256_digest},
252258
"requires-python": f.requires_python,
253259
"yanked": False,
260+
"size": f.size,
261+
"upload-time": f.upload_time.isoformat() + "Z",
254262
}
255263
for f in files
256264
],
@@ -270,28 +278,32 @@ def test_with_files_with_serial(self, db_request, content_type, renderer_overrid
270278
db_request.accept = content_type
271279
project = ProjectFactory.create()
272280
releases = [ReleaseFactory.create(project=project) for _ in range(3)]
281+
release_versions = sorted([r.version for r in releases], key=parse)
273282
files = [
274283
FileFactory.create(release=r, filename=f"{project.name}-{r.version}.tar.gz")
275284
for r in releases
276285
]
277-
# let's assert the result is ordered by string comparison of filename
278-
files = sorted(files, key=lambda key: key.filename)
286+
# let's assert the result is ordered by version and filename
287+
files = sorted(files, key=lambda f: (parse(f.release.version), f.filename))
279288
urls_iter = (f"/file/{f.filename}" for f in files)
280289
db_request.matchdict["name"] = project.normalized_name
281290
db_request.route_url = lambda *a, **kw: next(urls_iter)
282291
user = UserFactory.create()
283292
je = JournalEntryFactory.create(name=project.name, submitted_by=user)
284293

285294
assert simple.simple_detail(project, db_request) == {
286-
"meta": {"_last-serial": je.id, "api-version": "1.0"},
295+
"meta": {"_last-serial": je.id, "api-version": API_VERSION},
287296
"name": project.normalized_name,
297+
"versions": release_versions,
288298
"files": [
289299
{
290300
"filename": f.filename,
291301
"url": f"/file/{f.filename}",
292302
"hashes": {"sha256": f.sha256_digest},
293303
"requires-python": f.requires_python,
294304
"yanked": False,
305+
"size": f.size,
306+
"upload-time": f.upload_time.isoformat() + "Z",
295307
}
296308
for f in files
297309
],
@@ -361,15 +373,18 @@ def test_with_files_with_version_multi_digit(
361373
je = JournalEntryFactory.create(name=project.name, submitted_by=user)
362374

363375
assert simple.simple_detail(project, db_request) == {
364-
"meta": {"_last-serial": je.id, "api-version": "1.0"},
376+
"meta": {"_last-serial": je.id, "api-version": API_VERSION},
365377
"name": project.normalized_name,
378+
"versions": release_versions,
366379
"files": [
367380
{
368381
"filename": f.filename,
369382
"url": f"/file/{f.filename}",
370383
"hashes": {"sha256": f.sha256_digest},
371384
"requires-python": f.requires_python,
372385
"yanked": False,
386+
"size": f.size,
387+
"upload-time": f.upload_time.isoformat() + "Z",
373388
}
374389
for f in files
375390
],

Diff for: warehouse/packaging/utils.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from warehouse.packaging.interfaces import ISimpleStorage
2222
from warehouse.packaging.models import File, Project, Release
2323

24-
API_VERSION = "1.0"
24+
API_VERSION = "1.1"
2525

2626

2727
def _simple_index(request, serial):
@@ -48,10 +48,12 @@ def _simple_detail(project, request):
4848
.all(),
4949
key=lambda f: (parse(f.release.version), f.filename),
5050
)
51+
versions = sorted({f.release.version for f in files}, key=parse)
5152

5253
return {
5354
"meta": {"api-version": API_VERSION, "_last-serial": project.last_serial},
5455
"name": project.normalized_name,
56+
"versions": versions,
5557
"files": [
5658
{
5759
"filename": file.filename,
@@ -60,6 +62,8 @@ def _simple_detail(project, request):
6062
"sha256": file.sha256_digest,
6163
},
6264
"requires-python": file.release.requires_python,
65+
"size": file.size,
66+
"upload-time": file.upload_time.isoformat() + "Z",
6367
"yanked": file.release.yanked_reason
6468
if file.release.yanked and file.release.yanked_reason
6569
else file.release.yanked,

0 commit comments

Comments
 (0)