pulp-python 3.19.2__py3-none-any.whl → 3.19.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,7 +12,7 @@ class PulpPythonPluginAppConfig(PulpPluginAppConfig):
12
12
 
13
13
  name = "pulp_python.app"
14
14
  label = "python"
15
- version = "3.19.2"
15
+ version = "3.19.3"
16
16
  python_package_name = "pulp-python"
17
17
  domain_compatible = True
18
18
 
@@ -15,6 +15,7 @@ from django.http.response import (
15
15
  HttpResponse,
16
16
  HttpResponseBadRequest,
17
17
  HttpResponseForbidden,
18
+ HttpResponseNotFound,
18
19
  StreamingHttpResponse,
19
20
  )
20
21
  from django.shortcuts import redirect
@@ -255,7 +256,7 @@ class SimpleView(PackageUploadMixin, ViewSet):
255
256
 
256
257
  rfilter = get_remote_package_filter(remote)
257
258
  if not rfilter.filter_project(package):
258
- raise Http404(f"{package} does not exist.")
259
+ return {}
259
260
 
260
261
  url = remote.get_remote_artifact_url(f"simple/{package}/")
261
262
  remote.headers = remote.headers or []
@@ -263,19 +264,19 @@ class SimpleView(PackageUploadMixin, ViewSet):
263
264
  downloader = remote.get_downloader(url=url, max_retries=1)
264
265
  try:
265
266
  d = downloader.fetch()
266
- except ClientError:
267
- return HttpResponse(f"Failed to fetch {package} from {remote.url}.", status=502)
268
- except TimeoutException:
269
- return HttpResponse(f"{remote.url} timed out while fetching {package}.", status=504)
267
+ except (ClientError, TimeoutException):
268
+ log.info(f"Failed to fetch {package} simple page from {remote.url}")
269
+ return {}
270
270
 
271
271
  if d.headers["content-type"] == "application/vnd.pypi.simple.v1+json":
272
272
  page = ProjectPage.from_json_data(json.load(open(d.path, "rb")), base_url=url)
273
273
  else:
274
274
  page = ProjectPage.from_html(package, open(d.path, "rb").read(), base_url=url)
275
- packages = [
276
- parse_package(p) for p in page.packages if rfilter.filter_release(package, p.version)
277
- ]
278
- return HttpResponse(write_simple_detail(package, packages))
275
+ return {
276
+ p.filename: parse_package(p)
277
+ for p in page.packages
278
+ if rfilter.filter_release(package, p.version)
279
+ }
279
280
 
280
281
  @extend_schema(operation_id="pypi_simple_package_read", summary="Get package simple page")
281
282
  def retrieve(self, request, path, package):
@@ -283,24 +284,25 @@ class SimpleView(PackageUploadMixin, ViewSet):
283
284
  repo_ver, content = self.get_rvc()
284
285
  # Should I redirect if the normalized name is different?
285
286
  normalized = canonicalize_name(package)
287
+ releases = {}
286
288
  if self.distribution.remote:
287
- return self.pull_through_package_simple(normalized, path, self.distribution.remote)
288
- if self.should_redirect(repo_version=repo_ver):
289
+ releases = self.pull_through_package_simple(normalized, path, self.distribution.remote)
290
+ elif self.should_redirect(repo_version=repo_ver):
289
291
  return redirect(urljoin(self.base_content_url, f"{path}/simple/{normalized}/"))
290
- packages = (
291
- content.filter(name__normalize=normalized)
292
- .values_list("filename", "sha256", "name")
293
- .iterator()
294
- )
295
- try:
296
- present = next(packages)
297
- except StopIteration:
298
- raise Http404(f"{normalized} does not exist.")
299
- else:
300
- packages = chain([present], packages)
301
- name = present[2]
302
- releases = ((f, urljoin(self.base_content_url, f"{path}/{f}"), d) for f, d, _ in packages)
303
- return StreamingHttpResponse(write_simple_detail(name, releases, streamed=True))
292
+ if content:
293
+ packages = content.filter(name__normalize=normalized).values("filename", "sha256")
294
+ local_releases = {
295
+ p["filename"]: (
296
+ p["filename"],
297
+ urljoin(self.base_content_url, f"{path}/{p['filename']}"),
298
+ p["sha256"],
299
+ )
300
+ for p in packages
301
+ }
302
+ releases.update(local_releases)
303
+ if not releases:
304
+ return HttpResponseNotFound(f"{normalized} does not exist.")
305
+ return HttpResponse(write_simple_detail(normalized, releases.values()))
304
306
 
305
307
  @extend_schema(
306
308
  request=PackageUploadSerializer,
pulp_python/app/utils.py CHANGED
@@ -458,7 +458,7 @@ class PackageIncludeFilter:
458
458
 
459
459
  try:
460
460
  version = parse(version)
461
- except InvalidVersion:
461
+ except (InvalidVersion, TypeError):
462
462
  return False
463
463
 
464
464
  include_range = self._filter_includes.get("range", {})
@@ -66,7 +66,7 @@ def test_pull_through_filter(python_remote_factory, python_distribution_factory)
66
66
 
67
67
  r = requests.get(f"{distro.base_url}simple/pulpcore/")
68
68
  assert r.status_code == 404
69
- assert r.json() == {"detail": "pulpcore does not exist."}
69
+ assert r.text == "pulpcore does not exist."
70
70
 
71
71
  r = requests.get(f"{distro.base_url}simple/shelf-reader/")
72
72
  assert r.status_code == 200
@@ -86,11 +86,11 @@ def test_pull_through_filter(python_remote_factory, python_distribution_factory)
86
86
 
87
87
  r = requests.get(f"{distro.base_url}simple/django/")
88
88
  assert r.status_code == 404
89
- assert r.json() == {"detail": "django does not exist."}
89
+ assert r.text == "django does not exist."
90
90
 
91
91
  r = requests.get(f"{distro.base_url}simple/pulpcore/")
92
- assert r.status_code == 502
93
- assert r.text == f"Failed to fetch pulpcore from {remote.url}."
92
+ assert r.status_code == 404
93
+ assert r.text == "pulpcore does not exist."
94
94
 
95
95
  r = requests.get(f"{distro.base_url}simple/shelf-reader/")
96
96
  assert r.status_code == 200
@@ -138,3 +138,49 @@ def test_pull_through_with_repo(
138
138
  assert r.status_code == 200
139
139
  tasks = pulpcore_bindings.TasksApi.list(reserved_resources=repo.prn)
140
140
  assert tasks.count == 3
141
+
142
+
143
+ @pytest.mark.parallel
144
+ def test_pull_through_local_only(
145
+ python_remote_factory, python_distribution_factory, python_repo_with_sync
146
+ ):
147
+ """Tests that pull-through checks the repository if the package is not present on the remote."""
148
+ remote = python_remote_factory(url=PYPI_URL, includes=["pulpcore"])
149
+ repo = python_repo_with_sync(remote=remote)
150
+ remote2 = python_remote_factory(includes=[]) # Fixtures does not have pulpcore
151
+ distro = python_distribution_factory(repository=repo.pulp_href, remote=remote2.pulp_href)
152
+
153
+ url = f"{distro.base_url}simple/pulpcore/"
154
+ r = requests.get(url)
155
+ assert r.status_code == 200
156
+ assert "?redirect=" not in r.text
157
+
158
+ url = f"{distro.base_url}simple/shelf-reader/"
159
+ r = requests.get(url)
160
+ assert r.status_code == 200
161
+ assert "?redirect=" in r.text
162
+
163
+ url = f"{distro.base_url}simple/pulp_python/"
164
+ r = requests.get(url)
165
+ assert r.status_code == 404
166
+ assert r.text == "pulp-python does not exist."
167
+
168
+
169
+ @pytest.mark.parallel
170
+ def test_pull_through_filtering_bad_names(python_remote_factory, python_distribution_factory):
171
+ """Tests that pull-through handles packages with invalid names gracefully."""
172
+ # ipython version 0.13.X has improper named bdist_wininst, e.g ipython-0.13.py2-win-amd64.exe
173
+ # pypi-simple expects the platform to go before the pyversion (for .exe), so when parsed the
174
+ # version and package type will be None.
175
+ remote = python_remote_factory(url=PYPI_URL, includes=["ipython"])
176
+ distro = python_distribution_factory(remote=remote.pulp_href)
177
+
178
+ url = f"{distro.base_url}simple/ipython/"
179
+ response = requests.get(url)
180
+
181
+ assert response.status_code == 200
182
+
183
+ project_page = ProjectPage.from_response(response, "ipython")
184
+ # Should have no packages with None version (they get filtered out)
185
+ assert len(project_page.packages) > 0
186
+ assert all(package.version is not None for package in project_page.packages)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pulp-python
3
- Version: 3.19.2
3
+ Version: 3.19.3
4
4
  Summary: pulp-python plugin for the Pulp Project
5
5
  Author-email: Pulp Team <pulp-list@redhat.com>
6
6
  Project-URL: Homepage, https://pulpproject.org
@@ -1,6 +1,6 @@
1
1
  pulp_python/__init__.py,sha256=GIuTLoBTc-07dSLJUh8xrZPRz8x-jJ61pfR0J1IjnzI,65
2
2
  pulp_python/pytest_plugin.py,sha256=KqzB8Xv22_mA6itx0N1tYg9qXgEhHiOkX1ookAaJB8g,7525
3
- pulp_python/app/__init__.py,sha256=2B25Wu7fJHqNg9m8hmlZQmzvjZKyVzO2WYXb5xfA3vQ,2490
3
+ pulp_python/app/__init__.py,sha256=JdmTFYu4U2rQFWWsQ_OoOYU_nYutRMPftjW8D7HH-8s,2490
4
4
  pulp_python/app/global_access_conditions.py,sha256=MZJtyoVsr-4hRaty6mKDqh3caOHd5UKJjEWLV2crOLs,1080
5
5
  pulp_python/app/modelresource.py,sha256=4SFAdqk6lozi_cZz4uqDIqhqPAZF-7l5jJwPn-xGZFs,1249
6
6
  pulp_python/app/models.py,sha256=Puvl1VhuCubtf_V0sq6U5nWAb94sUAVk_wTv-FkuvSs,11258
@@ -8,7 +8,7 @@ pulp_python/app/replica.py,sha256=cFMNdTDX_6k87PzEffDDN4Moh2iUu89rSqYgv0-Ta8c,18
8
8
  pulp_python/app/serializers.py,sha256=zHFxpmKQPJrKWaBADVbUsZKpxLuGqjyKpCDm_CHxfzU,19712
9
9
  pulp_python/app/settings.py,sha256=HXJK3rr0LVTOv1xBS5cZvVtz6j4SvFZl0PH3sLTcu2w,227
10
10
  pulp_python/app/urls.py,sha256=bnuW89roIlPipROo3QcJktvRPAxikI1tV7-XX425QQg,1089
11
- pulp_python/app/utils.py,sha256=eh9da0-iynwQRblmtwdDq6pFwFy7CJgjvnHkj3znXAk,18280
11
+ pulp_python/app/utils.py,sha256=Xlxbv5oGahoEeK28uRjG__Tul9yox6NSyupa2cQiTtI,18293
12
12
  pulp_python/app/viewsets.py,sha256=S0VQIv4_pmDYzpsEwlze-pvyQ2yaT4Hpq3GeBiUdL3g,25103
13
13
  pulp_python/app/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  pulp_python/app/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -32,7 +32,7 @@ pulp_python/app/migrations/0015_alter_pythonpackagecontent_options.py,sha256=Ox2
32
32
  pulp_python/app/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  pulp_python/app/pypi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  pulp_python/app/pypi/serializers.py,sha256=qU3lZEVs0luqMlYrG1KxxfGpNo9exYzWool1bERtLIY,3310
35
- pulp_python/app/pypi/views.py,sha256=u3WXI-VbJiW9ciu5Wq8t8FuWJVTpCFPP9b8C8c4eVZQ,16214
35
+ pulp_python/app/pypi/views.py,sha256=y2HAzN-tZYgB6zTmonBpmc2bSmE220b5T_AQ8LrXVis,16126
36
36
  pulp_python/app/tasks/__init__.py,sha256=bG7P-IVJ_-tHJ6ciCeahrc8woIanAVOZ59_S_aQRVBE,212
37
37
  pulp_python/app/tasks/publish.py,sha256=PKiWDtGkOOvJwzbNIIhjvo77SXvKibcpAcYzZ3woncc,4153
38
38
  pulp_python/app/tasks/repair.py,sha256=58DEBhvdrBeMCjOdLrM7jUN5yjjWESz19iIlo1mb1EE,6988
@@ -54,7 +54,7 @@ pulp_python/tests/functional/api/test_crud_remotes.py,sha256=clFFhgG5udyKzWOLwxp
54
54
  pulp_python/tests/functional/api/test_domains.py,sha256=vMm7rZD96nlmVdpU-Y7mZVtj5j9xHfTs_NYgLJuRhAc,10469
55
55
  pulp_python/tests/functional/api/test_download_content.py,sha256=5IuaHXyLakPkjm5sLTxtTl7Dq0yl7N36HpObnIa0Sks,4950
56
56
  pulp_python/tests/functional/api/test_export_import.py,sha256=Lf_RS_WfQwVqA5FHeGrKtjVcqgGcGu78p0UdIjt64wg,4620
57
- pulp_python/tests/functional/api/test_full_mirror.py,sha256=f3PBGMv7e4OxYkIOYN7oANGUNYjNb7o3OxCl6v69Gqw,5583
57
+ pulp_python/tests/functional/api/test_full_mirror.py,sha256=bY76kkKUyreRA_P2d4aCPNUlN11WwMvs4AyCDZICXK0,7481
58
58
  pulp_python/tests/functional/api/test_pypi_apis.py,sha256=lMPh7CbSNJqZaVkg6xZCs3CZa1YZsUkPQYJMbqLxx7k,12179
59
59
  pulp_python/tests/functional/api/test_rbac.py,sha256=-xNWqvKKU-v1uC6tCRGBK0aWaff25K9C-AfzQkdHhhI,10513
60
60
  pulp_python/tests/functional/api/test_repair.py,sha256=jqt6DFX4X45fYVT_xcrsSxEGEoiwdPOfd3K2QFjIbE4,7867
@@ -62,9 +62,9 @@ pulp_python/tests/functional/api/test_sync.py,sha256=oE2gJx9bnbQudq45dGVB7xE_ZBi
62
62
  pulp_python/tests/functional/api/test_upload.py,sha256=XJ6zUffw9A1avOJND5CfwL4xM0_ejiL_NCWszPe7fZY,1853
63
63
  pulp_python/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
64
  pulp_python/tests/unit/test_models.py,sha256=TBI0yKsrdbnJSPeBFfxSqhXK7zaNvR6qg5JehGH3Pds,229
65
- pulp_python-3.19.2.dist-info/licenses/LICENSE,sha256=2ylvL381vKOhdO-w6zkrOxe9lLNBhRQpo9_0EbHC_HM,18046
66
- pulp_python-3.19.2.dist-info/METADATA,sha256=Du2-VutZpd2KuVJVnJbngzYdEIQ-X94o-VzPELd0Q7M,1702
67
- pulp_python-3.19.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
68
- pulp_python-3.19.2.dist-info/entry_points.txt,sha256=HvqLEXjw_dS5jqAwnE5JiRZFE6f-y5SRtitKLPml2To,115
69
- pulp_python-3.19.2.dist-info/top_level.txt,sha256=X0hXgXc_bpbiKqVrkt8jD5_QEiQviKbHDwveQcOcJjo,12
70
- pulp_python-3.19.2.dist-info/RECORD,,
65
+ pulp_python-3.19.3.dist-info/licenses/LICENSE,sha256=2ylvL381vKOhdO-w6zkrOxe9lLNBhRQpo9_0EbHC_HM,18046
66
+ pulp_python-3.19.3.dist-info/METADATA,sha256=3k148Rqt1ExmBuz72SGQzD0cUZvhu3CAM8V3R_bBR2c,1702
67
+ pulp_python-3.19.3.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
68
+ pulp_python-3.19.3.dist-info/entry_points.txt,sha256=HvqLEXjw_dS5jqAwnE5JiRZFE6f-y5SRtitKLPml2To,115
69
+ pulp_python-3.19.3.dist-info/top_level.txt,sha256=X0hXgXc_bpbiKqVrkt8jD5_QEiQviKbHDwveQcOcJjo,12
70
+ pulp_python-3.19.3.dist-info/RECORD,,