Skip to content

Commit 12b1cc9

Browse files
committed
Update pkginfo library to support newer python packages
closes #689
1 parent 2380ab8 commit 12b1cc9

File tree

5 files changed

+59
-11
lines changed

5 files changed

+59
-11
lines changed

CHANGES/689.feature

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support Python package metadata version 2.3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Generated by Django 4.2.10 on 2024-07-08 00:47
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('python', '0013_add_rbac_permissions'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='pythonpackagecontent',
15+
name='dynamic',
16+
field=models.JSONField(null=True),
17+
),
18+
migrations.AddField(
19+
model_name='pythonpackagecontent',
20+
name='provides_extra',
21+
field=models.JSONField(null=True),
22+
),
23+
]

pulp_python/app/models.py

+8
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ class PythonPackageContent(Content):
145145

146146
PROTECTED_FROM_RECLAIM = False
147147

148+
# TODO: it appears we've set the default (usually empty-string) for each of these fields
149+
# manually in the migrations rather than setting them declaratively. That's not ideal.
150+
# At some point we should add proper default values and probably make some fields nullable.
151+
148152
TYPE = "python"
149153
repo_key_fields = ("filename",)
150154
# Required metadata
@@ -177,7 +181,11 @@ class PythonPackageContent(Content):
177181
requires_external = models.JSONField(default=list)
178182
classifiers = models.JSONField(default=list)
179183
project_urls = models.JSONField(default=dict)
184+
# Metadata 2.1
180185
description_content_type = models.TextField()
186+
provides_extra = models.JSONField(default=list, null=True)
187+
# Metadata 2.2
188+
dynamic = models.JSONField(default=list, null=True)
181189
# Pulp Domains
182190
_pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT)
183191

pulp_python/app/serializers.py

+22-9
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,6 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
108108
required=False, allow_blank=True,
109109
help_text=_('A longer description of the package that can run to several paragraphs.')
110110
)
111-
description_content_type = serializers.CharField(
112-
required=False, allow_blank=True,
113-
help_text=_('A string stating the markup syntax (if any) used in the distribution’s'
114-
' description, so that tools can intelligently render the description.')
115-
)
116111
keywords = serializers.CharField(
117112
required=False, allow_blank=True,
118113
help_text=_('Additional keywords to be used to assist searching for the '
@@ -195,6 +190,23 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
195190
required=False, default=list,
196191
help_text=_('A JSON list containing classification values for a Python package.')
197192
)
193+
# Metadata 2.1
194+
description_content_type = serializers.CharField(
195+
required=False, allow_blank=True,
196+
help_text=_('A string stating the markup syntax (if any) used in the distribution’s'
197+
' description, so that tools can intelligently render the description.')
198+
)
199+
provides_extra = serializers.JSONField(
200+
required=False, default=list,
201+
help_text=_('A JSON list containing names of optional features provided by the package.')
202+
)
203+
# Metadata 2.2
204+
dynamic = serializers.JSONField(
205+
required=False, default=list,
206+
help_text=_('A JSON list containing names of other core metadata fields which are '
207+
'permitted to vary between sdist and bdist packages. Fields NOT marked '
208+
'dynamic MUST be the same between bdist and sdist.')
209+
)
198210

199211
def deferred_validate(self, data):
200212
"""
@@ -251,10 +263,11 @@ def retrieve(self, validated_data):
251263
class Meta:
252264
fields = core_serializers.SingleArtifactContentUploadSerializer.Meta.fields + (
253265
'filename', 'packagetype', 'name', 'version', 'sha256', 'metadata_version', 'summary',
254-
'description', 'description_content_type', 'keywords', 'home_page', 'download_url',
255-
'author', 'author_email', 'maintainer', 'maintainer_email', 'license',
256-
'requires_python', 'project_url', 'project_urls', 'platform', 'supported_platform',
257-
'requires_dist', 'provides_dist', 'obsoletes_dist', 'requires_external', 'classifiers'
266+
'description', 'keywords', 'home_page', 'download_url', 'author', 'author_email',
267+
'maintainer', 'maintainer_email', 'license', 'requires_python', 'project_url',
268+
'project_urls', 'platform', 'supported_platform', 'requires_dist', 'provides_dist',
269+
'obsoletes_dist', 'requires_external', 'classifiers', 'description_content_type',
270+
'provides_extra', 'dynamic',
258271
)
259272
model = python_models.PythonPackageContent
260273

pulp_python/app/utils.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,9 @@ def parse_project_metadata(project):
9191
package['obsoletes_dist'] = json.dumps(project.get('obsoletes_dist', []))
9292
package['requires_external'] = json.dumps(project.get('requires_external', []))
9393
package['classifiers'] = json.dumps(project.get('classifiers', []))
94-
package['project_urls'] = json.dumps(project.get('project_urls', {}))
9594
package['description_content_type'] = project.get('description_content_type') or ""
95+
package['provides_extra'] = project.get('provides_extra', None)
96+
package['dynamic'] = project.get('dynamic', None)
9697

9798
return package
9899

@@ -219,7 +220,6 @@ def python_content_to_info(content):
219220
"summary": content.summary or "",
220221
"keywords": content.keywords or "",
221222
"description": content.description or "",
222-
"description_content_type": content.description_content_type or "",
223223
"bugtrack_url": None, # These two are basically never used
224224
"docs_url": None,
225225
"downloads": {"last_day": -1, "last_month": -1, "last_week": -1},
@@ -240,6 +240,9 @@ def python_content_to_info(content):
240240
"classifiers": json_to_dict(content.classifiers) or None,
241241
"yanked": False, # These are no longer used on PyPI, but are still present
242242
"yanked_reason": None,
243+
"description_content_type": content.description_content_type or "",
244+
"provides_extra": content.provides_extra,
245+
"dynamic": content.dynamic,
243246
}
244247

245248

0 commit comments

Comments
 (0)