Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/467.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed package name normalization issue preventing installing packages with "." or "_" in their names.
9 changes: 9 additions & 0 deletions pulp_python/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ class Meta:
default_related_name = "%(app_label)s_%(model_name)s"


class NormalizeName(models.Transform):
"""A transform field to normalize package names according to PEP426."""

function = "REGEXP_REPLACE"
template = "LOWER(%(function)s(%(expressions)s, '(\.|_|-)', '-', 'ig'))" # noqa:W605
lookup_name = "normalize"


class PythonPackageContent(Content):
"""
A Content Type representing Python's Distribution Package.
Expand All @@ -142,6 +150,7 @@ class PythonPackageContent(Content):
filename = models.TextField(db_index=True)
packagetype = models.TextField(choices=PACKAGE_TYPES)
name = models.TextField()
name.register_lookup(NormalizeName)
version = models.TextField()
sha256 = models.CharField(unique=True, db_index=True, max_length=64)
# Optional metadata
Expand Down
24 changes: 18 additions & 6 deletions pulp_python/app/pypi/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
)
from drf_spectacular.utils import extend_schema
from dynaconf import settings
from itertools import chain
from urllib.parse import urljoin
from pathlib import PurePath
from packaging.utils import canonicalize_name

from pulpcore.plugin.tasking import dispatch
from pulp_python.app.models import (
Expand Down Expand Up @@ -188,14 +190,24 @@ def list(self, request, path):
def retrieve(self, request, path, package):
"""Retrieves the simple api html page for a package."""
distro, repo_ver, content = self.get_drvc(path)
# Should I redirect if the normalized name is different?
normalized = canonicalize_name(package)
if self.should_redirect(distro, repo_version=repo_ver):
# Maybe this name needs to be normalized?
return redirect(urljoin(BASE_CONTENT_URL, f'{path}/simple/{package}/'))
packages = content.filter(name__iexact=package).values_list('filename', 'sha256').iterator()
detail_packages = ((f, urljoin(BASE_CONTENT_URL, f'{path}/{f}'), d) for f, d in packages)
return StreamingHttpResponse(
write_simple_detail(package, detail_packages, streamed=True)
return redirect(urljoin(BASE_CONTENT_URL, f'{path}/simple/{normalized}/'))
packages = (
content.filter(name__normalize=normalized)
.values_list('filename', 'sha256', 'name')
.iterator()
)
try:
present = next(packages)
except StopIteration:
raise Http404(f"{normalized} does not exist.")
else:
packages = chain([present], packages)
name = present[2]
releases = ((f, urljoin(BASE_CONTENT_URL, f'{path}/{f}'), d) for f, d, _ in packages)
return StreamingHttpResponse(write_simple_detail(name, releases, streamed=True))

@extend_schema(request=PackageUploadSerializer,
responses={200: PackageUploadTaskSerializer},
Expand Down