internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: pulp/pulpcore

Issue:
Add a generic distributions list endpoint



Discussion:

Resolving patch:
diff --git a/pulpcore/app/viewsets/__init__.py b/pulpcore/app/viewsets/__init__.py
--- a/pulpcore/app/viewsets/__init__.py
+++ b/pulpcore/app/viewsets/__init__.py
@@ -47,6 +47,7 @@
     DistributionFilter,
     DistributionViewSet,
     ListContentGuardViewSet,
+    ListDistributionViewSet,
     ListPublicationViewSet,
     PublicationFilter,
     PublicationViewSet,
diff --git a/pulpcore/app/viewsets/publication.py b/pulpcore/app/viewsets/publication.py
--- a/pulpcore/app/viewsets/publication.py
+++ b/pulpcore/app/viewsets/publication.py
@@ -238,6 +238,18 @@ class Meta:
         }
 
 
+class ListDistributionViewSet(NamedModelViewSet, mixins.ListModelMixin):
+    endpoint_name = "distributions"
+    queryset = Distribution.objects.all()
+    serializer_class = DistributionSerializer
+    filterset_class = DistributionFilter
+
+    @classmethod
+    def is_master_viewset(cls):
+        """Do not hide from the routers."""
+        return False
+
+
 class DistributionViewSet(
     NamedModelViewSet,
     mixins.RetrieveModelMixin,


Test patch:
diff --git a/pulpcore/tests/functional/api/using_plugin/test_distributions.py b/pulpcore/tests/functional/api/using_plugin/test_distributions.py
--- a/pulpcore/tests/functional/api/using_plugin/test_distributions.py
+++ b/pulpcore/tests/functional/api/using_plugin/test_distributions.py
@@ -32,6 +32,7 @@
     RepositorySyncURL,
 )
 from pulpcore.tests.functional.api.using_plugin.constants import (
+    BASE_DISTRIBUTION_PATH,
     FILE_CHUNKED_FIXTURE_MANIFEST_URL,
     FILE_CONTENT_NAME,
     FILE_DISTRIBUTION_PATH,
@@ -160,7 +161,13 @@ def test_03_fully_update(self):
                 self.do_fully_update_attr(key)
 
     @skip_if(bool, "distribution", False)
-    def test_04_delete_distribution(self):
+    def test_04_list(self):
+        """Test the generic distribution list endpoint."""
+        distributions = self.client.get(BASE_DISTRIBUTION_PATH)
+        assert self.distribution["pulp_href"] in [distro["pulp_href"] for distro in distributions]
+
+    @skip_if(bool, "distribution", False)
+    def test_05_delete_distribution(self):
         """Delete a distribution."""
         self.client.delete(self.distribution["pulp_href"])
         with self.assertRaises(HTTPError):
Repository: pulp/pulpcore

Issue:
Migration 0040_set_admin_is_staff.py is missing dependency on user model



Discussion:
This may have been triggered by the removal of the django admin app, which in turn lead to reshuffled migration execution.

Resolving patch:
diff --git a/pulpcore/app/migrations/0040_set_admin_is_staff.py b/pulpcore/app/migrations/0040_set_admin_is_staff.py
--- a/pulpcore/app/migrations/0040_set_admin_is_staff.py
+++ b/pulpcore/app/migrations/0040_set_admin_is_staff.py
@@ -1,5 +1,6 @@
 # Generated by Django 2.2.13 on 2020-07-01 21:29
 
+from django.conf import settings
 from django.contrib.auth import get_user_model
 from django.db import migrations
 
@@ -19,8 +20,9 @@ class Migration(migrations.Migration):
 
     dependencies = [
         ('core', '0039_change_download_concurrency'),
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
     ]
 
     operations = [
-        migrations.RunPython(allow_admin_as_staff),
+        migrations.RunPython(allow_admin_as_staff, reverse_code=migrations.RunPython.noop, elidable=True),
     ]


Test patch:
Repository: pulp/pulpcore

Issue:
As a user, I would like to be able to filter all publications for a given repository
Author: wibbit (wibbit)


Redmine Issue: 7036, https://pulp.plan.io/issues/7036

---

As a user, I would like to be able to filter all publications for a given repository.







Discussion:
I believe this is not yet implemented because when I look in [the API docs](https://docs.pulpproject.org/pulpcore/restapi.html#tag/Publications:-File) I see filtering by `repository_version`, but not `repository`.

Resolving patch:
diff --git a/pulpcore/app/viewsets/publication.py b/pulpcore/app/viewsets/publication.py
--- a/pulpcore/app/viewsets/publication.py
+++ b/pulpcore/app/viewsets/publication.py
@@ -11,6 +11,7 @@
     ContentRedirectContentGuard,
     Distribution,
     Publication,
+    Repository,
     Content,
 )
 from pulpcore.app.serializers import (
@@ -55,7 +56,23 @@ def filter(self, qs, value):
         return qs.with_content([content.pk])
 
 
+class RepositoryThroughVersionFilter(Filter):
+    def filter(self, qs, value):
+        if value is None:
+            # user didn't supply a value
+            return qs
+
+        if not value:
+            raise serializers.ValidationError(
+                detail=_("No value supplied for {name} filter").format(name=self.field_name)
+            )
+
+        repository = NamedModelViewSet.get_resource(value, Repository)
+        return qs.filter(repository_version__repository=repository)
+
+
 class PublicationFilter(BaseFilterSet):
+    repository = RepositoryThroughVersionFilter(help_text=_("Repository referenced by HREF"))
     repository_version = RepositoryVersionFilter()
     pulp_created = IsoDateTimeFilter()
     content = PublicationContentFilter()


Test patch:
Repository: pulp/pulpcore

Issue:
Implement chainloading of plugins reusable app conditions
Currently, plugins need to subclass the access policies to be able to use additional conditions in access policies. This is incompatible with the desire to configure the access policy for Pulp globally. The issue can be circumvented by injecting plugin modules in this list:
https://rsinger86.github.io/drf-access-policy/reusable_conditions.html


Discussion:
I meant ap as in AccessPolicy. XD
@rochacbruno can we get some advice on the dynaconf way to accomplish this? The setting is `DRF_ACCESS_POLICY` which is defined [here](https://github.com/pulp/pulpcore/blob/main/pulpcore/app/settings.py#L241) with the value:

`DRF_ACCESS_POLICY = {"reusable_conditions": "pulpcore.app.global_access_conditions"}`

drf-access-policy now supports this type of value instead, so let's assume we'll change the settings.py to be:

`DRF_ACCESS_POLICY = {"reusable_conditions": ["pulpcore.app.global_access_conditions"]}`

Then we want apps, e.g. pulp_ansible to additively provide its settings. For example pulp_ansible has its settings [here](https://github.com/pulp/pulp_ansible/blob/main/pulp_ansible/app/settings.py).

Is this just as simple as using the merge option? I looked through here https://www.dynaconf.com/merging/ but I'm looking for the python version of a merge. Say we wanted to add "pulp_ansible.app.global_access_conditions" as the additional string, we would want the layered option to look like:

`DRF_ACCESS_POLICY = {"reusable_conditions": ["pulpcore.app.global_access_conditions", "pulp_ansible.app.global_access_conditions"]}`
@bmbouter all of that works on python files (same way on any filetype or envvar)

Option 1
```py
DRF_ACCESS_POLICY__reusable_conditions = "@merge pulp_ansible.app.global_access_conditions"
```
> If you want to avoid duplicates use `@merge_unique`

Option 2

```py
DRF_ACCESS_POLICY__reusable_conditions = ["dynaconf_merge", "pulp_ansible.app.global_access_conditions"]
```

> id you want to avoid duplication use `dynaconf_merge_unique`

Option 3

```py
DRF_ACCESS_POLICY = {
    "dynaconf_merge": True, 
    "reusable_conditions": ["pulp_ansible.app.global_access_conditions"]
}
```


Right now dynaconf can only perform **append** to lists, there is yet no way to perform **insert**

Resolving patch:
diff --git a/pulpcore/app/settings.py b/pulpcore/app/settings.py
--- a/pulpcore/app/settings.py
+++ b/pulpcore/app/settings.py
@@ -238,7 +238,7 @@
     },
 }
 
-DRF_ACCESS_POLICY = {"reusable_conditions": "pulpcore.app.global_access_conditions"}
+DRF_ACCESS_POLICY = {"reusable_conditions": ["pulpcore.app.global_access_conditions"]}
 
 CONTENT_PATH_PREFIX = "/pulp/content/"
 CONTENT_APP_TTL = 30


Test patch:
Repository: pulp/pulpcore

Issue:
Implementation of does_batch in DeclarativeContent is wrong
**Describe the bug**
`does_batch` is supposed to decide, whether content can be waited on, or must be evaluated asap. It produces `False` unnecessarily often, leading to performance issues.

**Additional context**
This is suspected to at least one of the reasons for: https://github.com/pulp/pulp_deb/issues/466


Discussion:

Resolving patch:
diff --git a/pulpcore/plugin/stages/models.py b/pulpcore/plugin/stages/models.py
--- a/pulpcore/plugin/stages/models.py
+++ b/pulpcore/plugin/stages/models.py
@@ -136,7 +136,7 @@ def does_batch(self):
         """Whether this content is being awaited on and must therefore not wait forever in batches.
         When overwritten in subclasses, a `True` value must never be turned into `False`.
         """
-        return not self._resolved and self._future is None
+        return self._resolved or self._future is None
 
     async def resolution(self):
         """Coroutine that waits for the content to be saved to database.


Test patch:
Repository: pulp/pulpcore

Issue:
Remove pulpcore.plugin.constants.API_ROOT
This constant is deprecated and is intended to be removed in 3.20.


Discussion:

Resolving patch:
diff --git a/pulpcore/plugin/constants.py b/pulpcore/plugin/constants.py
--- a/pulpcore/plugin/constants.py
+++ b/pulpcore/plugin/constants.py
@@ -6,16 +6,3 @@
     TASK_CHOICES,
     TASK_FINAL_STATES,
 )
-
-
-@property
-def API_ROOT():
-    from django.conf import settings
-    from pulpcore.app.loggers import deprecation_logger
-
-    deprecation_logger.warn(
-        "The API_ROOT constant has been deprecated and turned into a setting. Please use "
-        "`settings.V3_API_ROOT_NO_FRONT_SLASH` instead. This symbol will be deleted with pulpcore "
-        "3.20."
-    )
-    return settings.V3_API_ROOT_NO_FRONT_SLASH


Test patch:
Repository: pulp/pulpcore

Issue:
Make UnsupportedDigestValidationError more informative
**Version**
Current main branch in dev box.

**Describe the bug**
I recently tried to sync a ULN remote, and got the following error:
```
'Content at the url uln://ovm2_2.1.1_i386_patch/repodata/other.xml.gz does not contain at least one trusted hasher which is specified in 'ALLOWED_CONTENT_CHECKSUMS' setting.'
```
The error message comes from the following lines of code:
```
        if self.expected_digests:
            if not set(self.expected_digests).intersection(set(Artifact.DIGEST_FIELDS)):
                raise UnsupportedDigestValidationError(
                    _(
                        "Content at the url {} does not contain at least one trusted hasher which"
                        " is specified in 'ALLOWED_CONTENT_CHECKSUMS' setting."
                    ).format(self.url)
                )
```

**Expected behavior**
It would be great if we could add the `self.expected_digests` (and possibly the `Artifact.DIGEST_FIELDS`) to the error message here, that way the user knows exactly what checksums the repo in question provides. That way I know what checksum I need to enable.

**Additional context**
It looks like `self.expected_digests` is the digests provided by the repo, while `Artifact.DIGEST_FIELDS` is the same as `ALLOWED_CONTENT_CHECKSUMS`.



Discussion:

Resolving patch:
diff --git a/pulpcore/download/base.py b/pulpcore/download/base.py
--- a/pulpcore/download/base.py
+++ b/pulpcore/download/base.py
@@ -102,9 +102,10 @@ def __init__(
             if not set(self.expected_digests).intersection(set(Artifact.DIGEST_FIELDS)):
                 raise UnsupportedDigestValidationError(
                     _(
-                        "Content at the url {} does not contain at least one trusted hasher which"
-                        " is specified in 'ALLOWED_CONTENT_CHECKSUMS' setting."
-                    ).format(self.url)
+                        "Content at the URL '{}' does not contain at least one trusted hasher which"
+                        " is specified in the 'ALLOWED_CONTENT_CHECKSUMS' setting ({}). The"
+                        " downloader expected one of the following hashers: {}"
+                    ).format(self.url, Artifact.DIGEST_FIELDS, set(self.expected_digests))
                 )
 
     def _ensure_writer_has_open_file(self):


Test patch:
Repository: pulp/pulpcore

Issue:
Remove deprecation warning about `ACCESS_POLICY_VIEWSET_NAME` attribute
In the pulpcore 3.18 and 3.19 releases, a deprecation warning was emitted if plugin writers defined a Model attribute named `ACCESS_POLICY_VIEWSET_NAME`. The CI shows deprecation warnings as a failure, so we believe all pulp plugins have discontinued setting this attribute. It's time to remove this deprecation warning with 3.20.


Discussion:

Resolving patch:
diff --git a/pulpcore/app/models/base.py b/pulpcore/app/models/base.py
--- a/pulpcore/app/models/base.py
+++ b/pulpcore/app/models/base.py
@@ -8,8 +8,6 @@
 from django.db.models.base import ModelBase
 from django_lifecycle import LifecycleModel
 
-from pulpcore.app.loggers import deprecation_logger
-
 
 class Label(LifecycleModel):
     """Model for handling resource labels.
@@ -69,14 +67,6 @@ class BaseModel(LifecycleModel):
     class Meta:
         abstract = True
 
-    def __init__(self, *args, **kwargs):
-        if hasattr(self, "ACCESS_POLICY_VIEWSET_NAME"):
-            deprecation_logger.warn(
-                f"The model {self.__class__} defines the 'ACCESS_POLICY_VIEWSET_NAME' class "
-                f"attribute which is no longer required and is discouraged to be set."
-            )
-        return super().__init__(*args, **kwargs)
-
     def __str__(self):
         try:
             # if we have a name, use it


Test patch:
Repository: pulp/pulpcore

Issue:
Improve proxy connection failure error message
Raise a more informative error message when the proxy rejects requests from Pulp

BZ: https://bugzilla.redhat.com/show_bug.cgi?id=2047485


Discussion:

Resolving patch:
diff --git a/pulpcore/download/http.py b/pulpcore/download/http.py
--- a/pulpcore/download/http.py
+++ b/pulpcore/download/http.py
@@ -256,6 +256,17 @@ async def download_wrapper():
                     return await self._run(extra_data=extra_data)
                 except asyncio.TimeoutError:
                     raise TimeoutException(self.url)
+                except aiohttp.ClientHttpProxyError as e:
+                    log.error(
+                        "Proxy {!r} rejected connection request during a request to "
+                        "{!r}, status={}, message={!r}".format(
+                            e.request_info.real_url,
+                            e.request_info.url,
+                            e.status,
+                            e.message,
+                        )
+                    )
+                    raise e
 
             return await download_wrapper()
 


Test patch:
Repository: pulp/pulpcore

Issue:
Add a note about passing `null` to `content_object`



Discussion:
Actually they can. The client needs to explicitly pass `content_object=None` in the POST request body.

i.e. `http <...> content_object:=null`
@pulp/core, please change the name of the issue to "Add a note about passing `null` to `content_object`" or something similar.

Resolving patch:
diff --git a/pulpcore/app/serializers/user.py b/pulpcore/app/serializers/user.py
--- a/pulpcore/app/serializers/user.py
+++ b/pulpcore/app/serializers/user.py
@@ -236,7 +236,10 @@ class UserRoleSerializer(ModelSerializer, NestedHyperlinkedModelSerializer):
     )
 
     content_object = ContentObjectField(
-        help_text=_("Optional pulp_href of the object the permissions are to be asserted on."),
+        help_text=_(
+            "pulp_href of the object for which role permissions should be asserted. "
+            "If set to 'null', permissions will act on the model-level."
+        ),
         source="*",
         allow_null=True,
     )
@@ -300,7 +303,10 @@ class GroupRoleSerializer(ModelSerializer, NestedHyperlinkedModelSerializer):
     )
 
     content_object = ContentObjectField(
-        help_text=_("Optional pulp_href of the object the permissions are to be asserted on."),
+        help_text=_(
+            "pulp_href of the object for which role permissions should be asserted. "
+            "If set to 'null', permissions will act on the model-level."
+        ),
         source="*",
         allow_null=True,
     )


Test patch:
Repository: pulp/pulpcore

Issue:
Append of chunked upload processes raw data
**Version**
Please provide the versions of the pulpcore and plugin packages in use, and how they are installed.  If you are using Pulp via Katello, please provide the Katello version.

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:

**Expected behavior**
A clear and concise description of what you expected to happen.

**Additional context**
Add any other context about the problem here.  Please provide links to any previous discussions via Discourse or Bugzilla.



Discussion:

Resolving patch:
diff --git a/pulpcore/app/models/upload.py b/pulpcore/app/models/upload.py
--- a/pulpcore/app/models/upload.py
+++ b/pulpcore/app/models/upload.py
@@ -1,6 +1,8 @@
 import hashlib
 import os
 
+from gettext import gettext as _
+
 from django.core.files.base import ContentFile
 from django.db import models
 from django.db.models.signals import post_delete
@@ -26,17 +28,18 @@ def append(self, chunk, offset, sha256=None):
         Append a chunk to an upload.
 
         Args:
-            chunk (File): Binary file to append to the upload file.
+            chunk (File): Binary data to append to the upload file.
             offset (int): First byte position to write chunk to.
         """
-        chunk_read = chunk.read()
-        current_sha256 = hashlib.sha256(chunk_read).hexdigest()
-        if sha256 and sha256 != current_sha256:
-            raise serializers.ValidationError("Checksum does not match chunk upload.")
+        chunk = chunk.read()
+        if sha256:
+            current_sha256 = hashlib.sha256(chunk).hexdigest()
+            if sha256 != current_sha256:
+                raise serializers.ValidationError(_("Checksum does not match chunk upload."))
 
         upload_chunk = UploadChunk(upload=self, offset=offset, size=len(chunk))
         filename = os.path.basename(upload_chunk.storage_path(""))
-        upload_chunk.file.save(filename, ContentFile(chunk_read))
+        upload_chunk.file.save(filename, ContentFile(chunk))
 
 
 class UploadChunk(BaseModel):


Test patch:
Repository: pulp/pulpcore

Issue:
Sphinx 5.0 causes docs not to build
Sphinx 5.0.0 was released on May 29th https://pypi.org/project/Sphinx/#history and emits the warning below:

```
extlinks: Sphinx-6.0 will require a caption string to contain exactly one '%s' and all other '%' need to be escaped as '%%'.
```

This is treated as an error due to the Makefile almost all release branches use, e.g. [here's the one for pulpcore:main](https://github.com/pulp/pulpcore/blob/main/docs/Makefile#L6).

## Solutions

We could...

1) have warnings not be treated as errors
2) Fix the extlinks references to get the warnings to stop
3) Pin Sphinx <5.0.0

I am going to try for (2). (1) Seems like a step backwards, and (2) likely won't work because Sphinx gets included from a variety of places as it's installed in the CI currently.


Discussion:

Resolving patch:
diff --git a/docs/conf.py b/docs/conf.py
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -262,8 +262,8 @@
 #texinfo_show_urls = 'footnote'
 
 extlinks = {
-    'github': ('https://github.com/pulp/pulpcore/issues/%s', '#'),
-    'redmine': ('https://pulp.plan.io/issues/%s', '#'),
+    'github': ('https://github.com/pulp/pulpcore/issues/%s', '#%s'),
+    'redmine': ('https://pulp.plan.io/issues/%s', '#%s'),
 }
 
 # napoleon uses .. attribute by default, but :ivar: is more succinct and looks better,


Test patch:
Repository: pulp/pulpcore

Issue:
Doc for default orphan protection time seems conflicting
Reading [the rest api docs for orphan cleanup endpoint](https://docs.pulpproject.org/pulpcore/restapi.html#operation/orphans_cleanup_cleanup) it seems there are conflicting messages. It says both that the default for `orphan_protection_time` is 0 and if `orphan_protection_time` is not specified, ORPHAN_PROTECTION_TIME will be used.


Discussion:

Resolving patch:
diff --git a/pulpcore/app/serializers/orphans.py b/pulpcore/app/serializers/orphans.py
--- a/pulpcore/app/serializers/orphans.py
+++ b/pulpcore/app/serializers/orphans.py
@@ -2,8 +2,6 @@
 
 from rest_framework import fields, serializers
 
-from django.conf import settings
-
 from pulpcore.app.models import Content
 from pulpcore.app.serializers import ValidateFieldsMixin
 
@@ -24,7 +22,6 @@ class OrphansCleanupSerializer(serializers.Serializer, ValidateFieldsMixin):
         ),
         allow_null=True,
         required=False,
-        default=settings.ORPHAN_PROTECTION_TIME,
     )
 
     def validate_content_hrefs(self, value):
diff --git a/pulpcore/app/viewsets/orphans.py b/pulpcore/app/viewsets/orphans.py
--- a/pulpcore/app/viewsets/orphans.py
+++ b/pulpcore/app/viewsets/orphans.py
@@ -1,4 +1,5 @@
 from drf_spectacular.utils import extend_schema
+from django.conf import settings
 from rest_framework.viewsets import ViewSet
 
 from pulpcore.app.response import OperationPostponedResponse
@@ -22,7 +23,9 @@ def cleanup(self, request):
         serializer.is_valid(raise_exception=True)
 
         content_pks = serializer.validated_data.get("content_hrefs", None)
-        orphan_protection_time = serializer.validated_data.get("orphan_protection_time")
+        orphan_protection_time = serializer.validated_data.get(
+            "orphan_protection_time", settings.ORPHAN_PROTECTION_TIME
+        )
 
         task = dispatch(
             orphan_cleanup,


Test patch:
Repository: pulp/pulpcore

Issue:
An error is not raised when exporting remote artifacts



Discussion:

Resolving patch:
diff --git a/pulpcore/app/tasks/export.py b/pulpcore/app/tasks/export.py
--- a/pulpcore/app/tasks/export.py
+++ b/pulpcore/app/tasks/export.py
@@ -50,7 +50,7 @@ def _export_to_file_system(path, content_artifacts, method=FS_EXPORT_METHODS.WRI
         RuntimeError: If Artifacts are not downloaded or when trying to link non-fs files
     """
     if content_artifacts.filter(artifact=None).exists():
-        RuntimeError(_("Cannot export artifacts that haven't been downloaded."))
+        raise RuntimeError(_("Cannot export artifacts that haven't been downloaded."))
 
     if (
         settings.DEFAULT_FILE_STORAGE != "pulpcore.app.models.storage.FileSystem"
@@ -370,7 +370,7 @@ def _do_export(pulp_exporter, tar, the_export):
         # an on_demand repo
         content_artifacts = ContentArtifact.objects.filter(content__in=version.content)
         if content_artifacts.filter(artifact=None).exists():
-            RuntimeError(_("Remote artifacts cannot be exported."))
+            raise RuntimeError(_("Remote artifacts cannot be exported."))
 
         if do_incremental:
             vers_artifacts = version.artifacts.difference(vers_match[version].artifacts).all()


Test patch: