Skip to content

Commit

Permalink
Update pkginfo library to support newer python packages
Browse files Browse the repository at this point in the history
closes #689
  • Loading branch information
dralley committed Jul 8, 2024
1 parent 2380ab8 commit c490361
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGES/689.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support Python package metadata version 2.3
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.10 on 2024-07-08 00:47

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('python', '0013_add_rbac_permissions'),
]

operations = [
migrations.AddField(
model_name='pythonpackagecontent',
name='dynamic',
field=models.JSONField(default=list, null=True),
),
migrations.AddField(
model_name='pythonpackagecontent',
name='provides_extra',
field=models.JSONField(default=list, null=True),
),
]
8 changes: 8 additions & 0 deletions pulp_python/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ class PythonPackageContent(Content):

PROTECTED_FROM_RECLAIM = False

# TODO: it appears we've set the default (usually empty-string) for each of these fields
# manually in the migrations rather than setting them declaratively. That's not ideal.
# At some point we should add proper default values and probably make some fields nullable.

TYPE = "python"
repo_key_fields = ("filename",)
# Required metadata
Expand Down Expand Up @@ -177,7 +181,11 @@ class PythonPackageContent(Content):
requires_external = models.JSONField(default=list)
classifiers = models.JSONField(default=list)
project_urls = models.JSONField(default=dict)
# Metadata 2.1
description_content_type = models.TextField()
provides_extra = models.JSONField(default=list, null=True)
# Metadata 2.2
dynamic = models.JSONField(default=list, null=True)
# Pulp Domains
_pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT)

Expand Down
31 changes: 22 additions & 9 deletions pulp_python/app/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,6 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
required=False, allow_blank=True,
help_text=_('A longer description of the package that can run to several paragraphs.')
)
description_content_type = serializers.CharField(
required=False, allow_blank=True,
help_text=_('A string stating the markup syntax (if any) used in the distribution’s'
' description, so that tools can intelligently render the description.')
)
keywords = serializers.CharField(
required=False, allow_blank=True,
help_text=_('Additional keywords to be used to assist searching for the '
Expand Down Expand Up @@ -195,6 +190,23 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
required=False, default=list,
help_text=_('A JSON list containing classification values for a Python package.')
)
# Metadata 2.1
description_content_type = serializers.CharField(
required=False, allow_blank=True,
help_text=_('A string stating the markup syntax (if any) used in the distribution’s'
' description, so that tools can intelligently render the description.')
)
provides_extra = serializers.JSONField(
required=False, default=list,
help_text=_('A JSON list containing names of optional features provided by the package.')
)
# Metadata 2.2
dynamic = serializers.JSONField(
required=False, default=list,
help_text=_('A JSON list containing names of other core metadata fields which are '
'permitted to vary between sdist and bdist packages. Fields NOT marked '
'dynamic MUST be the same between bdist and sdist.')
)

def deferred_validate(self, data):
"""
Expand Down Expand Up @@ -251,10 +263,11 @@ def retrieve(self, validated_data):
class Meta:
fields = core_serializers.SingleArtifactContentUploadSerializer.Meta.fields + (
'filename', 'packagetype', 'name', 'version', 'sha256', 'metadata_version', 'summary',
'description', 'description_content_type', 'keywords', 'home_page', 'download_url',
'author', 'author_email', 'maintainer', 'maintainer_email', 'license',
'requires_python', 'project_url', 'project_urls', 'platform', 'supported_platform',
'requires_dist', 'provides_dist', 'obsoletes_dist', 'requires_external', 'classifiers'
'description', 'keywords', 'home_page', 'download_url', 'author', 'author_email',
'maintainer', 'maintainer_email', 'license', 'requires_python', 'project_url',
'project_urls', 'platform', 'supported_platform', 'requires_dist', 'provides_dist',
'obsoletes_dist', 'requires_external', 'classifiers', 'description_content_type',
'provides_extra', 'dynamic',
)
model = python_models.PythonPackageContent

Expand Down
7 changes: 5 additions & 2 deletions pulp_python/app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ def parse_project_metadata(project):
package['obsoletes_dist'] = json.dumps(project.get('obsoletes_dist', []))
package['requires_external'] = json.dumps(project.get('requires_external', []))
package['classifiers'] = json.dumps(project.get('classifiers', []))
package['project_urls'] = json.dumps(project.get('project_urls', {}))
package['description_content_type'] = project.get('description_content_type') or ""
package['provides_extra'] = project.get('provides_extra', None)
package['dynamic'] = project.get('dynamic') or None

return package

Expand Down Expand Up @@ -219,7 +220,6 @@ def python_content_to_info(content):
"summary": content.summary or "",
"keywords": content.keywords or "",
"description": content.description or "",
"description_content_type": content.description_content_type or "",
"bugtrack_url": None, # These two are basically never used
"docs_url": None,
"downloads": {"last_day": -1, "last_month": -1, "last_week": -1},
Expand All @@ -240,6 +240,9 @@ def python_content_to_info(content):
"classifiers": json_to_dict(content.classifiers) or None,
"yanked": False, # These are no longer used on PyPI, but are still present
"yanked_reason": None,
"description_content_type": content.description_content_type or "",
"provides_extra": content.provides_extra,
"dynamic": content.dynamic,
}


Expand Down

0 comments on commit c490361

Please sign in to comment.