pulp-python 3.10.0__tar.gz → 3.10.1__tar.gz

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.
Files changed (80) hide show
  1. {pulp-python-3.10.0 → pulp_python-3.10.1}/CHANGES.rst +17 -0
  2. {pulp-python-3.10.0 → pulp_python-3.10.1}/MANIFEST.in +1 -0
  3. pulp_python-3.10.1/PKG-INFO +44 -0
  4. {pulp-python-3.10.0 → pulp_python-3.10.1}/functest_requirements.txt +5 -3
  5. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/__init__.py +1 -1
  6. pulp_python-3.10.1/pulp_python/app/fields.py +12 -0
  7. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/models.py +5 -1
  8. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/pypi/serializers.py +4 -3
  9. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/pypi/views.py +2 -1
  10. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/serializers.py +7 -6
  11. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/tasks/sync.py +24 -3
  12. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/api/test_crud_content_unit.py +15 -0
  13. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/api/test_download_content.py +32 -1
  14. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/api/test_full_mirror.py +13 -8
  15. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/api/test_sync.py +17 -0
  16. pulp_python-3.10.1/pulp_python/tests/functional/conftest.py +185 -0
  17. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/constants.py +7 -4
  18. pulp_python-3.10.1/pulp_python.egg-info/PKG-INFO +44 -0
  19. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python.egg-info/SOURCES.txt +1 -0
  20. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python.egg-info/entry_points.txt +0 -1
  21. pulp_python-3.10.1/pulp_python.egg-info/requires.txt +5 -0
  22. pulp_python-3.10.1/pyproject.toml +72 -0
  23. pulp_python-3.10.1/requirements.txt +6 -0
  24. {pulp-python-3.10.0 → pulp_python-3.10.1}/setup.py +1 -1
  25. pulp_python-3.10.1/test_requirements.txt +3 -0
  26. pulp-python-3.10.0/PKG-INFO +0 -28
  27. pulp-python-3.10.0/pulp_python/tests/functional/conftest.py +0 -94
  28. pulp-python-3.10.0/pulp_python.egg-info/PKG-INFO +0 -28
  29. pulp-python-3.10.0/pulp_python.egg-info/requires.txt +0 -4
  30. pulp-python-3.10.0/pyproject.toml +0 -27
  31. pulp-python-3.10.0/requirements.txt +0 -4
  32. pulp-python-3.10.0/test_requirements.txt +0 -10
  33. {pulp-python-3.10.0 → pulp_python-3.10.1}/COMMITMENT +0 -0
  34. {pulp-python-3.10.0 → pulp_python-3.10.1}/COPYRIGHT +0 -0
  35. {pulp-python-3.10.0 → pulp_python-3.10.1}/LICENSE +0 -0
  36. {pulp-python-3.10.0 → pulp_python-3.10.1}/README.md +0 -0
  37. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/__init__.py +0 -0
  38. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/migrations/0001_initial.py +0 -0
  39. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/migrations/0002_pythonpackagecontent_python_version.py +0 -0
  40. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/migrations/0003_new_sync_filters.py +0 -0
  41. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/migrations/0004_DATA_swap_distribution_model.py +0 -0
  42. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/migrations/0005_pythonpackagecontent_sha256.py +0 -0
  43. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/migrations/0006_pythonrepository_autopublish.py +0 -0
  44. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/migrations/0007_pythonpackagecontent_mv-2-1.py +0 -0
  45. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/migrations/0008_pythonpackagecontent_unique_sha256.py +0 -0
  46. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/migrations/0009_pythondistribution_allow_uploads.py +0 -0
  47. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/migrations/0010_update_json_field.py +0 -0
  48. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/migrations/0011_alter_pythondistribution_distribution_ptr_and_more.py +0 -0
  49. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/migrations/__init__.py +0 -0
  50. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/pypi/__init__.py +0 -0
  51. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/settings.py +0 -0
  52. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/tasks/__init__.py +0 -0
  53. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/tasks/publish.py +0 -0
  54. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/tasks/upload.py +0 -0
  55. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/urls.py +0 -0
  56. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/utils.py +0 -0
  57. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/viewsets.py +0 -0
  58. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/webserver_snippets/__init__.py +0 -0
  59. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/webserver_snippets/apache.conf +0 -0
  60. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/app/webserver_snippets/nginx.conf +0 -0
  61. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/__init__.py +0 -0
  62. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/__init__.py +0 -0
  63. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/api/__init__.py +0 -0
  64. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/api/test_auto_publish.py +0 -0
  65. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/api/test_consume_content.py +0 -0
  66. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/api/test_crud_publications.py +0 -0
  67. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/api/test_crud_remotes.py +0 -0
  68. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/api/test_pypi_apis.py +0 -0
  69. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/functional/utils.py +0 -0
  70. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/unit/__init__.py +0 -0
  71. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/unit/test_models.py +0 -0
  72. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/upgrade/__init__.py +0 -0
  73. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/upgrade/post/__init__.py +0 -0
  74. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/upgrade/post/test_publish.py +0 -0
  75. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/upgrade/pre/__init__.py +0 -0
  76. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python/tests/upgrade/pre/test_publish.py +0 -0
  77. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python.egg-info/dependency_links.txt +0 -0
  78. {pulp-python-3.10.0 → pulp_python-3.10.1}/pulp_python.egg-info/top_level.txt +0 -0
  79. {pulp-python-3.10.0 → pulp_python-3.10.1}/setup.cfg +0 -0
  80. {pulp-python-3.10.0 → pulp_python-3.10.1}/unittest_requirements.txt +0 -0
@@ -13,6 +13,23 @@ Changelog
13
13
 
14
14
  .. towncrier release notes start
15
15
 
16
+ 3.10.1 (2025-07-23)
17
+
18
+ #### Bugfixes {: #3.10.1-bugfix }
19
+
20
+ - Fixed tls_validation not being disabled when set to false on the remote.
21
+ `#653 <https://github.com/pulp/pulp_python/issues/653>`__
22
+ - Fixed uploads not supporting packages using metadata spec 2.3
23
+ `#682 <https://github.com/pulp/pulp_python/issues/682>`__
24
+ - Fixed the `package_types` filter breaking other remote filters.
25
+ `#691 <https://github.com/pulp/pulp_python/issues/691>`__
26
+ - Fixed package name normalization issue preventing syncing packages with "." or "_" in their names.
27
+ `#716 <https://github.com/pulp/pulp_python/issues/716>`__
28
+ - Fixed the JSONField specification so it doesn't break ruby bindings.
29
+ See context [here](https://github.com/pulp/pulp_rpm/issues/3639).
30
+
31
+ ---
32
+
16
33
  3.10.0 (2023-05-17)
17
34
  ===================
18
35
 
@@ -8,3 +8,4 @@ include functest_requirements.txt
8
8
  include test_requirements.txt
9
9
  include unittest_requirements.txt
10
10
  include pulp_python/app/webserver_snippets/*
11
+ exclude releasing.md
@@ -0,0 +1,44 @@
1
+ Metadata-Version: 2.4
2
+ Name: pulp-python
3
+ Version: 3.10.1
4
+ Summary: pulp-python plugin for the Pulp Project
5
+ Home-page: https://www.pulpproject.org
6
+ Author: Pulp Project Developers
7
+ Author-email: pulp-list@redhat.com
8
+ License: GPLv2+
9
+ Classifier: License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)
10
+ Classifier: Operating System :: POSIX :: Linux
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Framework :: Django
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: pulpcore<3.40,>=3.28.0
21
+ Requires-Dist: pkginfo<1.12.0,>=1.10.0
22
+ Requires-Dist: bandersnatch<6.2,>=6.1
23
+ Requires-Dist: pypi-simple<1.0.0,>=0.9.0
24
+ Requires-Dist: azure-storage-blob<12.26.0
25
+ Dynamic: author
26
+ Dynamic: author-email
27
+ Dynamic: classifier
28
+ Dynamic: description
29
+ Dynamic: description-content-type
30
+ Dynamic: home-page
31
+ Dynamic: license
32
+ Dynamic: license-file
33
+ Dynamic: requires-dist
34
+ Dynamic: requires-python
35
+ Dynamic: summary
36
+
37
+ # pulp_python
38
+
39
+ ![Pulp Nightly CI/CD](https://github.com/pulp/pulp_python/actions/workflows/nightly.yml/badge.svg)
40
+
41
+ A Pulp plugin to support hosting your own pip compatible Python packages.
42
+
43
+ For more information, please see the [documentation](https://docs.pulpproject.org/pulp_python/) or the
44
+ [Pulp project page](https://pulpproject.org).
@@ -1,7 +1,9 @@
1
1
  git+https://github.com/pulp/pulp-smash.git#egg=pulp-smash
2
- pytest
2
+ pytest<9
3
+ pytest-custom_exit_code
4
+ pytest-xdist
3
5
  lxml
4
6
  twine
5
7
  pypi-simple
6
- pulpcore-client
7
- pulp-python-client
8
+ trustme~=1.2.0
9
+ pytest-timeout
@@ -8,5 +8,5 @@ class PulpPythonPluginAppConfig(PulpPluginAppConfig):
8
8
 
9
9
  name = "pulp_python.app"
10
10
  label = "python"
11
- version = "3.10.0"
11
+ version = "3.10.1"
12
12
  python_package_name = "pulp-python"
@@ -0,0 +1,12 @@
1
+ from drf_spectacular.utils import extend_schema_field
2
+ from drf_spectacular.types import OpenApiTypes
3
+ from rest_framework import serializers
4
+
5
+
6
+ @extend_schema_field(OpenApiTypes.OBJECT)
7
+ class JSONObjectField(serializers.JSONField):
8
+ """A drf JSONField override to force openapi schema to use 'object' type.
9
+
10
+ Not strictly correct, but we relied on that for a long time.
11
+ See: https://github.com/tfranzel/drf-spectacular/issues/1095
12
+ """
@@ -16,6 +16,7 @@ from pulpcore.plugin.responses import ArtifactResponse
16
16
 
17
17
  from pathlib import PurePath
18
18
  from .utils import (
19
+ canonicalize_name,
19
20
  get_project_metadata_from_artifact,
20
21
  parse_project_metadata,
21
22
  python_content_to_json,
@@ -84,6 +85,8 @@ class PythonDistribution(Distribution):
84
85
  ).latest("pulp_created")
85
86
  except ObjectDoesNotExist:
86
87
  return None
88
+ if len(path.parts) == 2:
89
+ path = PurePath(f"simple/{canonicalize_name(path.parts[1])}")
87
90
  rel_path = f"{path}/index.html"
88
91
  try:
89
92
  ca = (
@@ -100,8 +103,9 @@ class PythonDistribution(Distribution):
100
103
  return ArtifactResponse(ca.artifact, headers=headers)
101
104
 
102
105
  if name:
106
+ normalized = canonicalize_name(name)
103
107
  package_content = PythonPackageContent.objects.filter(
104
- pk__in=self.publication.repository_version.content, name__iexact=name
108
+ pk__in=self.publication.repository_version.content, name__normalize=normalized
105
109
  )
106
110
  # TODO Change this value to the Repo's serial value when implemented
107
111
  headers = {PYPI_LAST_SERIAL: str(PYPI_SERIAL_CONSTANT)}
@@ -3,6 +3,7 @@ from gettext import gettext as _
3
3
 
4
4
  from rest_framework import serializers
5
5
  from pulp_python.app.utils import DIST_EXTENSIONS
6
+ from pulp_python.app import fields
6
7
  from pulpcore.plugin.models import Artifact
7
8
  from django.db.utils import IntegrityError
8
9
 
@@ -27,9 +28,9 @@ class PackageMetadataSerializer(serializers.Serializer):
27
28
  """
28
29
 
29
30
  last_serial = serializers.IntegerField(help_text=_("Cache value from last PyPI sync"))
30
- info = serializers.JSONField(help_text=_("Core metadata of the package"))
31
- releases = serializers.JSONField(help_text=_("List of all the releases of the package"))
32
- urls = serializers.JSONField()
31
+ info = fields.JSONObjectField(help_text=_("Core metadata of the package"))
32
+ releases = fields.JSONObjectField(help_text=_("List of all the releases of the package"))
33
+ urls = fields.JSONObjectField()
33
34
 
34
35
 
35
36
  class PackageUploadSerializer(serializers.Serializer):
@@ -278,7 +278,8 @@ class MetadataView(ViewSet, PyPIMixin):
278
278
  elif meta_path.match("*/json"):
279
279
  name = meta_path.parts[0]
280
280
  if name:
281
- package_content = content.filter(name__iexact=name)
281
+ normalized = canonicalize_name(name)
282
+ package_content = content.filter(name__normalize=normalized)
282
283
  # TODO Change this value to the Repo's serial value when implemented
283
284
  headers = {PYPI_LAST_SERIAL: str(PYPI_SERIAL_CONSTANT)}
284
285
  json_body = python_content_to_json(path, package_content, version=version)
@@ -7,6 +7,7 @@ from pulpcore.plugin import models as core_models
7
7
  from pulpcore.plugin import serializers as core_serializers
8
8
 
9
9
  from pulp_python.app import models as python_models
10
+ from pulp_python.app import fields
10
11
  from pulp_python.app.utils import get_project_metadata_from_artifact, parse_project_metadata
11
12
 
12
13
 
@@ -154,7 +155,7 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
154
155
  required=False, allow_blank=True,
155
156
  help_text=_('A browsable URL for the project and a label for it, separated by a comma.')
156
157
  )
157
- project_urls = serializers.JSONField(
158
+ project_urls = fields.JSONObjectField(
158
159
  required=False, default=dict,
159
160
  help_text=_('A dictionary of labels and URLs for the project.')
160
161
  )
@@ -167,28 +168,28 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
167
168
  required=False, allow_blank=True,
168
169
  help_text=_('Field to specify the OS and CPU for which the binary package was compiled. ')
169
170
  )
170
- requires_dist = serializers.JSONField(
171
+ requires_dist = fields.JSONObjectField(
171
172
  required=False, default=list,
172
173
  help_text=_('A JSON list containing names of some other distutils project '
173
174
  'required by this distribution.')
174
175
  )
175
- provides_dist = serializers.JSONField(
176
+ provides_dist = fields.JSONObjectField(
176
177
  required=False, default=list,
177
178
  help_text=_('A JSON list containing names of a Distutils project which is contained'
178
179
  ' within this distribution.')
179
180
  )
180
- obsoletes_dist = serializers.JSONField(
181
+ obsoletes_dist = fields.JSONObjectField(
181
182
  required=False, default=list,
182
183
  help_text=_('A JSON list containing names of a distutils project\'s distribution which '
183
184
  'this distribution renders obsolete, meaning that the two projects should not '
184
185
  'be installed at the same time.')
185
186
  )
186
- requires_external = serializers.JSONField(
187
+ requires_external = fields.JSONObjectField(
187
188
  required=False, default=list,
188
189
  help_text=_('A JSON list containing some dependency in the system that the distribution '
189
190
  'is to be used.')
190
191
  )
191
- classifiers = serializers.JSONField(
192
+ classifiers = fields.JSONObjectField(
192
193
  required=False, default=list,
193
194
  help_text=_('A JSON list containing classification values for a Python package.')
194
195
  )
@@ -1,5 +1,7 @@
1
1
  import logging
2
+ from typing import Optional, Any, AsyncGenerator
2
3
 
4
+ import aiohttp
3
5
  from aiohttp import ClientResponseError, ClientError
4
6
  from lxml.etree import LxmlError
5
7
  from gettext import gettext as _
@@ -80,7 +82,7 @@ def create_bandersnatch_config(remote):
80
82
  config["plugins"]["enabled"] += "prerelease_release\n"
81
83
  if remote.package_types:
82
84
  rrfm = "regex_release_file_metadata"
83
- config["plugins"]["enabled"] += rrfm
85
+ config["plugins"]["enabled"] += f"{rrfm}\n"
84
86
  if not config.has_section(rrfm):
85
87
  config.add_section(rrfm)
86
88
  config[rrfm]["any:release_file.packagetype"] = "\n".join(remote.package_types)
@@ -126,7 +128,7 @@ class PythonBanderStage(Stage):
126
128
  # Bandersnatch includes leading slash when forming API urls
127
129
  url = self.remote.url.rstrip("/")
128
130
  # local & global timeouts defaults to 10secs and 5 hours
129
- async with Master(url) as master:
131
+ async with PulpMaster(url, tls=self.remote.tls_validation) as master:
130
132
  deferred_download = self.remote.policy != Remote.IMMEDIATE
131
133
  workers = self.remote.download_concurrency or self.remote.DEFAULT_DOWNLOAD_CONCURRENCY
132
134
  async with ProgressReport(
@@ -148,6 +150,25 @@ class PythonBanderStage(Stage):
148
150
  await pmirror.synchronize(packages_to_sync)
149
151
 
150
152
 
153
+ class PulpMaster(Master):
154
+ """
155
+ Pulp Master Class for Pulp specific overrides
156
+ """
157
+
158
+ def __init__(self, *args, tls=True, **kwargs):
159
+ self.tls = tls
160
+ super().__init__(*args, **kwargs)
161
+
162
+ async def get(
163
+ self, path: str, required_serial: Optional[int], **kw: Any
164
+ ) -> AsyncGenerator[aiohttp.ClientResponse, None]:
165
+ """Support tls=false"""
166
+ if not self.tls:
167
+ kw["ssl"] = False
168
+ async for r in super().get(path, required_serial, **kw):
169
+ yield r
170
+
171
+
151
172
  class PulpMirror(Mirror):
152
173
  """
153
174
  Pulp Mirror Class to perform syncing using Bandersnatch
@@ -257,4 +278,4 @@ class PulpMirror(Mirror):
257
278
  TODO
258
279
  This should have some error checking
259
280
  """
260
- pass
281
+ logger.error("Sync encountered an error: ", exc_info=exception)
@@ -1,5 +1,6 @@
1
1
  # coding=utf-8
2
2
  """Tests that perform actions over content unit."""
3
+ import pytest
3
4
  from pulp_smash.pulp3.bindings import delete_orphans, monitor_task, PulpTaskError
4
5
 
5
6
  from pulp_python.tests.functional.utils import (
@@ -12,6 +13,7 @@ from pulp_python.tests.functional.utils import (
12
13
  from pulp_python.tests.functional.utils import set_up_module as setUpModule # noqa:F401
13
14
  from tempfile import NamedTemporaryFile
14
15
  from urllib.parse import urljoin
16
+ from pypi_simple import PyPISimple
15
17
 
16
18
  from pulp_smash.utils import http_get
17
19
  from pulp_python.tests.functional.constants import (
@@ -227,3 +229,16 @@ class ContentUnitTestCase(TestCaseUsingBindings, TestHelpersMixin):
227
229
  for k, v in expected.items():
228
230
  with self.subTest(key=k):
229
231
  self.assertEqual(content_unit[k], v)
232
+
233
+
234
+ @pytest.mark.parallel
235
+ def test_upload_metadata_23_spec(python_content_factory):
236
+ """Test that packages using metadata spec 2.3 can be uploaded to pulp."""
237
+ filename = "urllib3-2.2.2-py3-none-any.whl"
238
+ with PyPISimple() as client:
239
+ page = client.get_project_page("urllib3")
240
+ for package in page.packages:
241
+ if package.filename == filename:
242
+ content = python_content_factory(filename, url=package.url)
243
+ assert content.metadata_version == "2.3"
244
+ break
@@ -14,6 +14,7 @@ from pulp_python.tests.functional.constants import (
14
14
  PYTHON_MD_PROJECT_SPECIFIER,
15
15
  PYTHON_MD_FIXTURE_SUMMARY,
16
16
  PYTHON_LG_FIXTURE_SUMMARY,
17
+ PYTHON_LG_FIXTURE_PRERELEASES_SUMMARY,
17
18
  PYTHON_LG_PROJECT_SPECIFIER,
18
19
  )
19
20
  from pulp_python.tests.functional.utils import (
@@ -126,7 +127,9 @@ class PublishPyPIJSON(TestCaseUsingBindings, TestHelpersMixin):
126
127
  """
127
128
  remote = self._create_remote(includes=[], prereleases=True)
128
129
  repo = self._create_repo_and_sync_with_remote(remote)
129
- self.assertEqual(get_content_summary(repo.to_dict()), PYTHON_LG_FIXTURE_SUMMARY)
130
+ self.assertEqual(
131
+ get_content_summary(repo.to_dict()), PYTHON_LG_FIXTURE_PRERELEASES_SUMMARY
132
+ )
130
133
 
131
134
  def test_full_pulp_to_pulp_sync(self):
132
135
  """
@@ -149,3 +152,31 @@ class PublishPyPIJSON(TestCaseUsingBindings, TestHelpersMixin):
149
152
 
150
153
  repo3 = self._create_repo_and_sync_with_remote(remote)
151
154
  self.assertEqual(get_content_summary(repo3.to_dict()), PYTHON_MD_FIXTURE_SUMMARY)
155
+
156
+
157
+ def test_pulp2pulp_sync_with_oddities(
158
+ python_repo_with_sync,
159
+ python_remote_factory,
160
+ python_publication_factory,
161
+ python_distribution_factory,
162
+ python_content_summary,
163
+ ):
164
+ """Test that Pulp can handle syncing packages with wierd names."""
165
+ remote = python_remote_factory(includes=["oslo.utils"], url="https://pypi.org")
166
+ repo = python_repo_with_sync(remote)
167
+ distro = python_distribution_factory(repository=repo.pulp_href)
168
+ summary = python_content_summary(repository_version=repo.latest_version_href)
169
+ # Test pulp 2 pulp full sync w/ live pypi apis
170
+ remote2 = python_remote_factory(includes=[], url=distro.base_url)
171
+ repo2 = python_repo_with_sync(remote2)
172
+ summary2 = python_content_summary(repository_version=repo2.latest_version_href)
173
+ assert summary2.present["python.python"]["count"] > 0
174
+ assert summary.present["python.python"]["count"] == summary2.present["python.python"]["count"]
175
+ # Test w/ publication
176
+ pub = python_publication_factory(repository=repo)
177
+ distro2 = python_distribution_factory(publication=pub.pulp_href)
178
+ remote3 = python_remote_factory(includes=[], url=distro2.base_url)
179
+ repo3 = python_repo_with_sync(remote3)
180
+ summary3 = python_content_summary(repository_version=repo3.latest_version_href)
181
+ assert summary3.present["python.python"]["count"] > 0
182
+ assert summary.present["python.python"]["count"] == summary3.present["python.python"]["count"]
@@ -108,21 +108,26 @@ class PullThroughMirror(TestCaseUsingBindings, TestHelpersMixin):
108
108
  remote = self._create_remote(url=PYPI_URL)
109
109
  distro = self._create_distribution(remote=remote.pulp_href)
110
110
 
111
- if self.cli_client.run(("pip", "list")).stdout.find("numpy") == -1:
112
- content = self.content_api.list(name="numpy")
113
- self.assertEqual(content.count, 0, msg="numpy content already present in test")
111
+ PACKAGE = "sampleproject"
112
+ if self.cli_client.run(("pip", "list")).stdout.find(PACKAGE) == -1:
113
+ content = self.content_api.list(name=PACKAGE)
114
+ self.assertEqual(
115
+ content.count, 0, msg=f"{PACKAGE} content already present in test"
116
+ )
114
117
  host = urlsplit(PULP_CONTENT_BASE_URL).hostname
115
118
  url = urljoin(self.PYPI_HOST, f"{distro.base_path}/simple/")
116
119
  out = self.cli_client.run(
117
- ("pip", "install", "--trusted-host", host, "-i", url, "numpy")
120
+ ("pip", "install", "--trusted-host", host, "-i", url, PACKAGE)
118
121
  )
119
122
  self.addCleanup(delete_orphans)
120
- self.assertTrue(self.cli_client.run(("pip", "list")).stdout.find("numpy") != -1, out)
121
- self.addCleanup(self.cli_client.run, ("pip", "uninstall", "numpy", "-y"))
122
- content = self.content_api.list(name="numpy")
123
+ self.assertTrue(
124
+ self.cli_client.run(("pip", "list")).stdout.find(PACKAGE) != -1, out
125
+ )
126
+ self.addCleanup(self.cli_client.run, ("pip", "uninstall", PACKAGE, "-y"))
127
+ content = self.content_api.list(name=PACKAGE)
123
128
  self.assertEqual(content.count, 1)
124
129
  else:
125
- self.skipTest("Uninstall numpy before running this test")
130
+ self.skipTest(f"Uninstall {PACKAGE} before running this test")
126
131
 
127
132
  def test_pull_through_simple(self):
128
133
  """Tests that the simple page is properly modified when requesting a pull-through."""
@@ -641,6 +641,23 @@ class PlatformExcludeTestCase(unittest.TestCase):
641
641
  )
642
642
 
643
643
 
644
+ @pytest.mark.parallel
645
+ def test_sync_multiple_filters(
646
+ python_repo_with_sync, python_remote_factory, python_content_summary
647
+ ):
648
+ """Tests sync with multiple filters."""
649
+ remote = python_remote_factory(
650
+ includes=PYTHON_LG_PROJECT_SPECIFIER,
651
+ package_types=["bdist_wheel"],
652
+ keep_latest_packages=1,
653
+ prereleases=False
654
+ )
655
+ repo = python_repo_with_sync(remote)
656
+
657
+ summary = python_content_summary(repository_version=repo.latest_version_href)
658
+ assert summary.present["python.python"]["count"] == PYTHON_LG_FIXTURE_COUNTS["multi"]
659
+
660
+
644
661
  @pytest.mark.parallel
645
662
  def test_proxy_sync(
646
663
  python_repo,
@@ -0,0 +1,185 @@
1
+ import pytest
2
+ import uuid
3
+
4
+ from pulp_smash.pulp3.utils import gen_distribution, gen_repo
5
+ from pulp_python.tests.functional.constants import PYTHON_EGG_FILENAME, PYTHON_URL
6
+ from pulp_python.tests.functional.utils import gen_python_remote
7
+
8
+ from pulpcore.client.pulp_python import (
9
+ ApiClient,
10
+ ContentPackagesApi,
11
+ DistributionsPypiApi,
12
+ PublicationsPypiApi,
13
+ RepositoriesPythonApi,
14
+ RepositoriesPythonVersionsApi,
15
+ RemotesPythonApi,
16
+ )
17
+
18
+
19
+ # Bindings API Fixtures
20
+
21
+ @pytest.fixture
22
+ def python_bindings_client(cid, bindings_cfg):
23
+ """Provides the python bindings client object."""
24
+ api_client = ApiClient(bindings_cfg)
25
+ api_client.default_headers["Correlation-ID"] = cid
26
+ return api_client
27
+
28
+
29
+ @pytest.fixture
30
+ def python_repo_api_client(python_bindings_client):
31
+ """Provides the Python Repository API client object."""
32
+ return RepositoriesPythonApi(python_bindings_client)
33
+
34
+
35
+ @pytest.fixture
36
+ def python_repo_version_api_client(python_bindings_client):
37
+ """Provides the Python Repository Version API client object."""
38
+ return RepositoriesPythonVersionsApi(python_bindings_client)
39
+
40
+
41
+ @pytest.fixture
42
+ def python_distro_api_client(python_bindings_client):
43
+ """Provides the Python Distribution API client object."""
44
+ return DistributionsPypiApi(python_bindings_client)
45
+
46
+
47
+ @pytest.fixture
48
+ def python_content_api_client(python_bindings_client):
49
+ """Provides the Python Package Content API client object."""
50
+ return ContentPackagesApi(python_bindings_client)
51
+
52
+
53
+ @pytest.fixture
54
+ def python_remote_api_client(python_bindings_client):
55
+ """Provides the Python Remotes API client object."""
56
+ return RemotesPythonApi(python_bindings_client)
57
+
58
+
59
+ @pytest.fixture
60
+ def python_publication_api_client(python_bindings_client):
61
+ """Proves the Python Publication API client object."""
62
+ return PublicationsPypiApi(python_bindings_client)
63
+
64
+
65
+ # Object Generation Fixtures
66
+
67
+ @pytest.fixture
68
+ def python_repo_factory(python_repo_api_client, gen_object_with_cleanup):
69
+ """A factory to generate a Python Repository with auto-cleanup."""
70
+ def _gen_python_repo(**kwargs):
71
+ kwargs.setdefault("name", str(uuid.uuid4()))
72
+ return gen_object_with_cleanup(python_repo_api_client, kwargs)
73
+
74
+ return _gen_python_repo
75
+
76
+
77
+ @pytest.fixture
78
+ def python_repo(python_repo_api_client, gen_object_with_cleanup):
79
+ """Creates a Python Repository and deletes it at test cleanup time."""
80
+ return gen_object_with_cleanup(python_repo_api_client, gen_repo())
81
+
82
+
83
+ @pytest.fixture
84
+ def python_distribution_factory(python_distro_api_client, gen_object_with_cleanup):
85
+ """A factory to generate a Python Distribution with auto-cleanup."""
86
+ def _gen_python_distribution(**kwargs):
87
+ distro_data = gen_distribution(**kwargs)
88
+ return gen_object_with_cleanup(python_distro_api_client, distro_data)
89
+
90
+ yield _gen_python_distribution
91
+
92
+
93
+ @pytest.fixture
94
+ def python_publication_factory(python_publication_api_client, gen_object_with_cleanup):
95
+ """A factory to generate a Python Publication with auto-cleanup."""
96
+ def _gen_python_publication(repository, version=None):
97
+ if version:
98
+ body = {"repository_version": f"{repository.versions_href}{version}/"}
99
+ else:
100
+ body = {"repository": repository.pulp_href}
101
+ return gen_object_with_cleanup(python_publication_api_client, body)
102
+
103
+ yield _gen_python_publication
104
+
105
+
106
+ @pytest.fixture
107
+ def python_remote_factory(python_remote_api_client, gen_object_with_cleanup):
108
+ """A factory to generate a Python Remote with auto-cleanup."""
109
+ def _gen_python_remote(**kwargs):
110
+ body = gen_python_remote(**kwargs)
111
+ return gen_object_with_cleanup(python_remote_api_client, body)
112
+
113
+ yield _gen_python_remote
114
+
115
+
116
+ @pytest.fixture
117
+ def python_repo_with_sync(
118
+ python_repo_api_client, python_repo_factory, python_remote_factory, monitor_task
119
+ ):
120
+ """A factory to generate a Python Repository synced with the passed in Remote."""
121
+ def _gen_python_repo_sync(remote=None, mirror=False, repository=None, **body):
122
+ kwargs = {}
123
+ if pulp_domain := body.get("pulp_domain"):
124
+ kwargs["pulp_domain"] = pulp_domain
125
+ remote = remote or python_remote_factory(**kwargs)
126
+ repo = repository or python_repo_factory(**body)
127
+ sync_body = {"mirror": mirror, "remote": remote.pulp_href}
128
+ monitor_task(python_repo_api_client.sync(repo.pulp_href, sync_body).task)
129
+ return python_repo_api_client.read(repo.pulp_href)
130
+
131
+ yield _gen_python_repo_sync
132
+
133
+
134
+ @pytest.fixture
135
+ def download_python_file(tmp_path, http_get):
136
+ """Download a Python file and return its path."""
137
+ def _download_python_file(relative_path, url):
138
+ file_path = tmp_path / relative_path
139
+ with open(file_path, mode="wb") as f:
140
+ f.write(http_get(url))
141
+ return file_path
142
+
143
+ yield _download_python_file
144
+
145
+
146
+ @pytest.fixture
147
+ def python_content_factory(python_content_api_client, download_python_file, monitor_task):
148
+ """A factory to create a Python Package Content."""
149
+ def _gen_python_content(relative_path=PYTHON_EGG_FILENAME, url=None, **body):
150
+ body["relative_path"] = relative_path
151
+ if url:
152
+ body["file"] = download_python_file(relative_path, url)
153
+ elif not any(x in body for x in ("artifact", "file", "upload")):
154
+ body["file"] = download_python_file(PYTHON_EGG_FILENAME, PYTHON_URL)
155
+ if repo := body.get("repository"):
156
+ repo_href = repo if isinstance(repo, str) else repo.pulp_href
157
+ body["repository"] = repo_href
158
+
159
+ task = python_content_api_client.create(**body).task
160
+ response = monitor_task(task)
161
+ return python_content_api_client.read(response.created_resources[0])
162
+
163
+ yield _gen_python_content
164
+
165
+
166
+ @pytest.fixture
167
+ def python_content_summary(python_repo_api_client, python_repo_version_api_client):
168
+ """Get a summary of the repository version's content."""
169
+ def _gen_summary(repository_version=None, repository=None, version=None):
170
+ if repository_version is None:
171
+ repo_href = get_href(repository)
172
+ if version:
173
+ repo_ver_href = f"{repo_href}versions/{version}/"
174
+ else:
175
+ repo_ver_href = python_repo_api_client.read(repo_href).latest_version_href
176
+ else:
177
+ repo_ver_href = get_href(repository_version)
178
+ return python_repo_version_api_client.read(repo_ver_href).content_summary
179
+
180
+ yield _gen_summary
181
+
182
+
183
+ def get_href(item):
184
+ """Tries to get the href from the given item, whether it is a string or object."""
185
+ return item if isinstance(item, str) else item.pulp_href
@@ -145,14 +145,17 @@ PYTHON_LG_PROJECT_SPECIFIER = [
145
145
  "celery", # matches 13
146
146
  "Django", # matches 31
147
147
  "scipy", # matches 23
148
+ "setuptools", # matches 2
148
149
  "shelf-reader", # matches 2
149
150
  ]
150
- PYTHON_LG_PACKAGE_COUNT = 76
151
+ PYTHON_LG_PACKAGE_COUNT = 78
151
152
  PYTHON_LG_FIXTURE_SUMMARY = {PYTHON_CONTENT_NAME: PYTHON_LG_PACKAGE_COUNT}
153
+ PYTHON_LG_FIXTURE_PRERELEASES_SUMMARY = {PYTHON_CONTENT_NAME: 92}
152
154
  PYTHON_LG_FIXTURE_COUNTS = {
153
- "latest_3": 35,
154
- "sdist": 23,
155
- "bdist_wheel": 53,
155
+ "latest_3": 37,
156
+ "sdist": 24,
157
+ "bdist_wheel": 54,
158
+ "multi": 26, # keep_latest=1, package_types="bdist_wheel", prereleases=False
156
159
  }
157
160
 
158
161
  DJANGO_LATEST_3 = 4 # latest version has 2 dists, each other has 1
@@ -0,0 +1,44 @@
1
+ Metadata-Version: 2.4
2
+ Name: pulp-python
3
+ Version: 3.10.1
4
+ Summary: pulp-python plugin for the Pulp Project
5
+ Home-page: https://www.pulpproject.org
6
+ Author: Pulp Project Developers
7
+ Author-email: pulp-list@redhat.com
8
+ License: GPLv2+
9
+ Classifier: License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)
10
+ Classifier: Operating System :: POSIX :: Linux
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Framework :: Django
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: pulpcore<3.40,>=3.28.0
21
+ Requires-Dist: pkginfo<1.12.0,>=1.10.0
22
+ Requires-Dist: bandersnatch<6.2,>=6.1
23
+ Requires-Dist: pypi-simple<1.0.0,>=0.9.0
24
+ Requires-Dist: azure-storage-blob<12.26.0
25
+ Dynamic: author
26
+ Dynamic: author-email
27
+ Dynamic: classifier
28
+ Dynamic: description
29
+ Dynamic: description-content-type
30
+ Dynamic: home-page
31
+ Dynamic: license
32
+ Dynamic: license-file
33
+ Dynamic: requires-dist
34
+ Dynamic: requires-python
35
+ Dynamic: summary
36
+
37
+ # pulp_python
38
+
39
+ ![Pulp Nightly CI/CD](https://github.com/pulp/pulp_python/actions/workflows/nightly.yml/badge.svg)
40
+
41
+ A Pulp plugin to support hosting your own pip compatible Python packages.
42
+
43
+ For more information, please see the [documentation](https://docs.pulpproject.org/pulp_python/) or the
44
+ [Pulp project page](https://pulpproject.org).
@@ -18,6 +18,7 @@ pulp_python.egg-info/entry_points.txt
18
18
  pulp_python.egg-info/requires.txt
19
19
  pulp_python.egg-info/top_level.txt
20
20
  pulp_python/app/__init__.py
21
+ pulp_python/app/fields.py
21
22
  pulp_python/app/models.py
22
23
  pulp_python/app/serializers.py
23
24
  pulp_python/app/settings.py
@@ -1,3 +1,2 @@
1
1
  [pulpcore.plugin]
2
2
  pulp_python = pulp_python:default_app_config
3
-
@@ -0,0 +1,5 @@
1
+ pulpcore<3.40,>=3.28.0
2
+ pkginfo<1.12.0,>=1.10.0
3
+ bandersnatch<6.2,>=6.1
4
+ pypi-simple<1.0.0,>=0.9.0
5
+ azure-storage-blob<12.26.0
@@ -0,0 +1,72 @@
1
+ [tool.towncrier]
2
+ package = "pulp_python"
3
+ filename = "CHANGES.rst"
4
+ directory = "CHANGES/"
5
+ title_format = "{version} ({project_date})"
6
+ template = "CHANGES/.TEMPLATE.md"
7
+ issue_format = "`#{issue} <https://github.com/pulp/pulp_python/issues/{issue}>`__"
8
+
9
+ [tool.check-manifest]
10
+ ignore = [
11
+ ".bumpversion.cfg",
12
+ ".pep8speaks.yml",
13
+ "CHANGES/**",
14
+ "CONTRIBUTING.rst",
15
+ "HISTORY.rst",
16
+ "dev_requirements.txt",
17
+ "doc_requirements.txt",
18
+ "docs/**",
19
+ "template_config.yml",
20
+ ".travis/**",
21
+ ".travis.yml",
22
+ "shelf_reader-0.1-py2-none-any.whl",
23
+ ".github/**",
24
+ ".ci/**",
25
+ "lint_requirements.txt",
26
+ ".flake8",
27
+ ]
28
+
29
+ [tool.bumpversion]
30
+ # This section is managed by the plugin template. Do not edit manually.
31
+
32
+ current_version = "3.10.1"
33
+ commit = false
34
+ tag = false
35
+ parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<alpha>0a)?(?P<patch>\\d+)(\\.(?P<release>[a-z]+))?"
36
+ serialize = [
37
+ "{major}.{minor}.{patch}.{release}",
38
+ "{major}.{minor}.{patch}",
39
+ "{major}.{minor}.{alpha}{patch}.{release}",
40
+ "{major}.{minor}.{alpha}{patch}",
41
+ ]
42
+
43
+ [tool.bumpversion.parts.alpha]
44
+ # This section is managed by the plugin template. Do not edit manually.
45
+
46
+ # This is sort of a hack. In PEP440 prerelease markers work quite differently.
47
+ # But this fits best with the way we have been doing release versions.
48
+ optional_value = "final"
49
+ values = [
50
+ "0a",
51
+ "final",
52
+ ]
53
+ independent = true
54
+
55
+ [tool.bumpversion.parts.release]
56
+ # This section is managed by the plugin template. Do not edit manually.
57
+
58
+ optional_value = "prod"
59
+ values = [
60
+ "dev",
61
+ "prod",
62
+ ]
63
+
64
+ [[tool.bumpversion.files]]
65
+ # This section is managed by the plugin template. Do not edit manually.
66
+
67
+ filename = "./pulp_python/app/__init__.py"
68
+ search = "version = \"{current_version}\""
69
+ replace = "version = \"{new_version}\""
70
+
71
+ [[tool.bumpversion.files]]
72
+ filename = "./setup.py"
@@ -0,0 +1,6 @@
1
+ pulpcore>=3.28.0,<3.40
2
+ pkginfo>=1.10.0,<1.12.0 # Twine has <1.11 in their requirements
3
+ bandersnatch>=6.1,<6.2
4
+ pypi-simple>=0.9.0,<1.0.0
5
+ # pinned until https://github.com/Azure/Azurite/issues/2562 is resolved
6
+ azure-storage-blob<12.26.0
@@ -10,7 +10,7 @@ with open("README.md") as f:
10
10
 
11
11
  setup(
12
12
  name="pulp-python",
13
- version="3.10.0",
13
+ version="3.10.1",
14
14
  description="pulp-python plugin for the Pulp Project",
15
15
  long_description=long_description,
16
16
  long_description_content_type="text/markdown",
@@ -0,0 +1,3 @@
1
+ # All test requirements
2
+ -r functest_requirements.txt
3
+ -r unittest_requirements.txt
@@ -1,28 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: pulp-python
3
- Version: 3.10.0
4
- Summary: pulp-python plugin for the Pulp Project
5
- Home-page: https://www.pulpproject.org
6
- Author: Pulp Project Developers
7
- Author-email: pulp-list@redhat.com
8
- License: GPLv2+
9
- Description: # pulp_python
10
-
11
- ![Pulp Nightly CI/CD](https://github.com/pulp/pulp_python/actions/workflows/nightly.yml/badge.svg)
12
-
13
- A Pulp plugin to support hosting your own pip compatible Python packages.
14
-
15
- For more information, please see the [documentation](https://docs.pulpproject.org/pulp_python/) or the
16
- [Pulp project page](https://pulpproject.org).
17
-
18
- Platform: UNKNOWN
19
- Classifier: License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)
20
- Classifier: Operating System :: POSIX :: Linux
21
- Classifier: Development Status :: 5 - Production/Stable
22
- Classifier: Framework :: Django
23
- Classifier: Programming Language :: Python
24
- Classifier: Programming Language :: Python :: 3
25
- Classifier: Programming Language :: Python :: 3.8
26
- Classifier: Programming Language :: Python :: 3.9
27
- Requires-Python: >=3.8
28
- Description-Content-Type: text/markdown
@@ -1,94 +0,0 @@
1
- import pytest
2
-
3
- from pulp_smash.pulp3.utils import gen_distribution, gen_repo
4
- from pulp_python.tests.functional.utils import gen_python_remote
5
-
6
- from pulpcore.client.pulp_python import (
7
- ApiClient,
8
- ContentPackagesApi,
9
- DistributionsPypiApi,
10
- PublicationsPypiApi,
11
- RepositoriesPythonApi,
12
- RemotesPythonApi,
13
- )
14
-
15
-
16
- # Bindings API Fixtures
17
-
18
- @pytest.fixture
19
- def python_bindings_client(cid, bindings_cfg):
20
- """Provides the python bindings client object."""
21
- api_client = ApiClient(bindings_cfg)
22
- api_client.default_headers["Correlation-ID"] = cid
23
- return api_client
24
-
25
-
26
- @pytest.fixture
27
- def python_repo_api_client(python_bindings_client):
28
- """Provides the Python Repository API client object."""
29
- return RepositoriesPythonApi(python_bindings_client)
30
-
31
-
32
- @pytest.fixture
33
- def python_distro_api_client(python_bindings_client):
34
- """Provides the Python Distribution API client object."""
35
- return DistributionsPypiApi(python_bindings_client)
36
-
37
-
38
- @pytest.fixture
39
- def python_content_api_client(python_bindings_client):
40
- """Provides the Python Package Content API client object."""
41
- return ContentPackagesApi(python_bindings_client)
42
-
43
-
44
- @pytest.fixture
45
- def python_remote_api_client(python_bindings_client):
46
- """Provides the Python Remotes API client object."""
47
- return RemotesPythonApi(python_bindings_client)
48
-
49
-
50
- @pytest.fixture
51
- def python_publication_api_client(python_bindings_client):
52
- """Proves the Python Publication API client object."""
53
- return PublicationsPypiApi(python_bindings_client)
54
-
55
-
56
- # Object Generation Fixtures
57
-
58
- @pytest.fixture
59
- def python_repo(python_repo_api_client, gen_object_with_cleanup):
60
- """Creates a Python Repository and deletes it at test cleanup time."""
61
- return gen_object_with_cleanup(python_repo_api_client, gen_repo())
62
-
63
-
64
- @pytest.fixture
65
- def python_distribution_factory(python_distro_api_client, gen_object_with_cleanup):
66
- """A factory to generate a Python Distribution with auto-cleanup."""
67
- def _gen_python_distribution(**kwargs):
68
- distro_data = gen_distribution(**kwargs)
69
- return gen_object_with_cleanup(python_distro_api_client, distro_data)
70
-
71
- yield _gen_python_distribution
72
-
73
-
74
- @pytest.fixture
75
- def python_publication_factory(python_publication_api_client, gen_object_with_cleanup):
76
- """A factory to generate a Python Publication with auto-cleanup."""
77
- def _gen_python_publication(repository, version=None):
78
- if version:
79
- body = {"repository_version": f"{repository.versions_href}{version}/"}
80
- else:
81
- body = {"repository": repository.pulp_href}
82
- return gen_object_with_cleanup(python_publication_api_client, body)
83
-
84
- yield _gen_python_publication
85
-
86
-
87
- @pytest.fixture
88
- def python_remote_factory(python_remote_api_client, gen_object_with_cleanup):
89
- """A factory to generate a Python Remote with auto-cleanup."""
90
- def _gen_python_remote(**kwargs):
91
- body = gen_python_remote(**kwargs)
92
- return gen_object_with_cleanup(python_remote_api_client, body)
93
-
94
- yield _gen_python_remote
@@ -1,28 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: pulp-python
3
- Version: 3.10.0
4
- Summary: pulp-python plugin for the Pulp Project
5
- Home-page: https://www.pulpproject.org
6
- Author: Pulp Project Developers
7
- Author-email: pulp-list@redhat.com
8
- License: GPLv2+
9
- Description: # pulp_python
10
-
11
- ![Pulp Nightly CI/CD](https://github.com/pulp/pulp_python/actions/workflows/nightly.yml/badge.svg)
12
-
13
- A Pulp plugin to support hosting your own pip compatible Python packages.
14
-
15
- For more information, please see the [documentation](https://docs.pulpproject.org/pulp_python/) or the
16
- [Pulp project page](https://pulpproject.org).
17
-
18
- Platform: UNKNOWN
19
- Classifier: License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)
20
- Classifier: Operating System :: POSIX :: Linux
21
- Classifier: Development Status :: 5 - Production/Stable
22
- Classifier: Framework :: Django
23
- Classifier: Programming Language :: Python
24
- Classifier: Programming Language :: Python :: 3
25
- Classifier: Programming Language :: Python :: 3.8
26
- Classifier: Programming Language :: Python :: 3.9
27
- Requires-Python: >=3.8
28
- Description-Content-Type: text/markdown
@@ -1,4 +0,0 @@
1
- pulpcore<3.40,>=3.25.0
2
- pkginfo<1.9.7,>=1.8.2
3
- bandersnatch<6.2,>=6.1
4
- pypi-simple<1.0.0,>=0.9.0
@@ -1,27 +0,0 @@
1
- [tool.towncrier]
2
- package = "pulp_python"
3
- filename = "CHANGES.rst"
4
- directory = "CHANGES/"
5
- title_format = "{version} ({project_date})"
6
- template = "CHANGES/.TEMPLATE.rst"
7
- issue_format = "`#{issue} <https://github.com/pulp/pulp_python/issues/{issue}>`__"
8
-
9
- [tool.check-manifest]
10
- ignore = [
11
- ".bumpversion.cfg",
12
- ".pep8speaks.yml",
13
- "CHANGES/**",
14
- "CONTRIBUTING.rst",
15
- "HISTORY.rst",
16
- "dev_requirements.txt",
17
- "doc_requirements.txt",
18
- "docs/**",
19
- "template_config.yml",
20
- ".travis/**",
21
- ".travis.yml",
22
- "shelf_reader-0.1-py2-none-any.whl",
23
- ".github/**",
24
- ".ci/**",
25
- "lint_requirements.txt",
26
- ".flake8",
27
- ]
@@ -1,4 +0,0 @@
1
- pulpcore>=3.25.0,<3.40
2
- pkginfo>=1.8.2,<1.9.7
3
- bandersnatch>=6.1,<6.2
4
- pypi-simple>=0.9.0,<1.0.0
@@ -1,10 +0,0 @@
1
- coveralls
2
- coverage
3
- flake8
4
- flake8-docstrings
5
- flake8-tuple
6
- flake8-quotes
7
- mock
8
- git+https://github.com/pulp/pulp-smash.git#egg=pulp-smash
9
- pydocstyle<4
10
- pytest
File without changes
File without changes
File without changes
File without changes
File without changes