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

Issue:
Rounding inprecision in wagtailimages template tag image
With
{% image self.photo fill-200x200 %}
the returned image is sometimes 200x199 instead of 200x200. Without focal point.

The solution could be to check in FillOperation whether the to-be-cropped area matches the requested area and increase with one pixel line if required.



Discussion:
The image operations code has been changed quite a bit in the next version of Wagtail. Are you using Wagtail's git-master or a pip-installed version?

Also, what is the original size of the image that you are resizing?

Oh wow, true. Yes I'm using 0.8.x. The original size is 539x720.

I'm using 0.8.x version too.


Resolving patch:
diff --git a/wagtail/wagtailimages/image_operations.py b/wagtail/wagtailimages/image_operations.py
--- a/wagtail/wagtailimages/image_operations.py
+++ b/wagtail/wagtailimages/image_operations.py
@@ -158,22 +158,16 @@ def run(self, willow, image):
         # Crop!
         willow.crop(int(left), int(top), int(right), int(bottom))
 
-        # Resize the final image
+        # Get scale for resizing
+        # The scale should be the same for both the horizontal and
+        # vertical axes
         aftercrop_width, aftercrop_height = willow.get_size()
-        horz_scale = self.width / aftercrop_width
-        vert_scale = self.height / aftercrop_height
+        scale = self.width / aftercrop_width
 
-        if aftercrop_width <= self.width or aftercrop_height <= self.height:
-            return
-
-        if horz_scale > vert_scale:
-            width = self.width
-            height = int(aftercrop_height * horz_scale)
-        else:
-            width = int(aftercrop_width * vert_scale)
-            height = self.height
-
-        willow.resize(width, height)
+        # Only resize if the image is too big
+        if scale < 1.0:
+            # Resize!
+            willow.resize(self.width, self.height)
 
     def get_vary(self, image):
         focal_point = image.get_focal_point()


Test patch:
diff --git a/wagtail/wagtailimages/tests/test_image_operations.py b/wagtail/wagtailimages/tests/test_image_operations.py
--- a/wagtail/wagtailimages/tests/test_image_operations.py
+++ b/wagtail/wagtailimages/tests/test_image_operations.py
@@ -151,6 +151,13 @@ class TestFillOperation(ImageOperationTestCase):
             ('resize', (800, 600), {}),
         ]),
 
+        # Basic usage with an oddly-sized original image
+        # This checks for a rounding precision issue (#968)
+        ('fill-200x200', Image(width=539, height=720), [
+            ('crop', (0, 90, 539, 629), {}),
+            ('resize', (200, 200), {}),
+        ]),
+
         # Closeness shouldn't have any effect when used without a focal point
         ('fill-800x600-c100', Image(width=1000, height=1000), [
             ('crop', (0, 125, 1000, 875), {}),
Repository: wagtail/wagtail

Issue:
Remove built dependencies
This commit removes libsass and Pillow from the setup.py dependency list. This greatly improves install performance and also means that the basic Wagtail installation is pure-python (so no build tools need to be on the end users host machine).

None of these dependencies are directly called from within Wagtail so the start project command continues to work correctly.



Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -30,11 +30,9 @@
 install_requires = [
     "Django>=1.7.0,<1.8",
     "django-compressor>=1.4",
-    "django-libsass>=0.2",
     "django-modelcluster>=0.5",
     "django-taggit==0.12.2",
     "django-treebeard==3.0",
-    "Pillow>=2.6.1",
     "beautifulsoup4>=4.3.2",
     "html5lib==0.999",
     "Unidecode>=0.04.14",


Test patch:
Repository: wagtail/wagtail

Issue:
'Sites' menu item is displayed for non-admin users
If you create a user that is only a member of the 'Editors' group, and log in as them, the left-hand menu includes the Settings menu, with 'Sites' as the only item. This should be hidden from non-admins.

On current wagtaildemo, clicking on this redirects to the broken URL `http://localhost:8111/admin/sites/django.contrib.auth.views.login?next=/admin/sites/`, which makes me suspect that this is a regression from the `LOGIN_URL` change in 0.9.



Discussion:
Sorry, I assigned this to myself thinking I had time to look at it (which I didn't). I'll look into this now.


Resolving patch:
diff --git a/wagtail/wagtailsites/wagtail_hooks.py b/wagtail/wagtailsites/wagtail_hooks.py
--- a/wagtail/wagtailsites/wagtail_hooks.py
+++ b/wagtail/wagtailsites/wagtail_hooks.py
@@ -21,4 +21,4 @@ def is_shown(self, request):
 
 @hooks.register('register_settings_menu_item')
 def register_sites_menu_item():
-    return MenuItem(_('Sites'), urlresolvers.reverse('wagtailsites_index'), classnames='icon icon-site', order=602)
+    return SitesMenuItem(_('Sites'), urlresolvers.reverse('wagtailsites_index'), classnames='icon icon-site', order=602)


Test patch:
Repository: wagtail/wagtail

Issue:
Image feature detection fails on 1.0b1 with "I/O operation on closed file"
As reported here: https://groups.google.com/d/msg/wagtail/5zSvx5g_vhM/LlrxA9Y73ncJ



Discussion:
I'll also see if I can add a test or two for feature detection to hopefully catch these sort of problems in the future


Resolving patch:
diff --git a/wagtail/wagtailimages/models.py b/wagtail/wagtailimages/models.py
--- a/wagtail/wagtailimages/models.py
+++ b/wagtail/wagtailimages/models.py
@@ -88,20 +88,25 @@ def __str__(self):
 
     @contextmanager
     def get_willow_image(self):
+        # Open file if it is closed
+        close_file = False
         try:
-            image_file = self.file.file  # triggers a call to self.storage.open, so IOErrors from missing files will be raised at this point
+            if self.file.closed:
+                self.file.open('rb')
+                close_file = True
         except IOError as e:
             # re-throw this as a SourceImageIOError so that calling code can distinguish
             # these from IOErrors elsewhere in the process
             raise SourceImageIOError(text_type(e))
 
-        image_file.open('rb')
-        image_file.seek(0)
+        # Seek to beginning
+        self.file.seek(0)
 
         try:
-            yield WillowImage.open(image_file)
+            yield WillowImage.open(self.file)
         finally:
-            image_file.close()
+            if close_file:
+                self.file.close()
 
     def get_rect(self):
         return Rect(0, 0, self.width, self.height)


Test patch:
diff --git a/wagtail/wagtailimages/tests/test_models.py b/wagtail/wagtailimages/tests/test_models.py
--- a/wagtail/wagtailimages/tests/test_models.py
+++ b/wagtail/wagtailimages/tests/test_models.py
@@ -231,6 +231,35 @@ def test_with_missing_image(self):
             with bad_image.get_willow_image():
                 self.fail() # Shouldn't get here
 
+    def test_closes_image(self):
+        # This tests that willow closes images after use
+        with self.image.get_willow_image():
+            self.assertFalse(self.image.file.closed)
+
+        self.assertTrue(self.image.file.closed)
+
+    def test_closes_image_on_exception(self):
+        # This tests that willow closes images when the with is exited with an exception
+        try:
+            with self.image.get_willow_image():
+                self.assertFalse(self.image.file.closed)
+                raise ValueError("Something went wrong!")
+        except ValueError:
+            pass
+
+        self.assertTrue(self.image.file.closed)
+
+    def test_doesnt_close_open_image(self):
+        # This tests that when the image file is already open, get_willow_image doesn't close it (#1256)
+        self.image.file.open('rb')
+
+        with self.image.get_willow_image():
+            pass
+
+        self.assertFalse(self.image.file.closed)
+
+        self.image.file.close()
+
 
 class TestIssue573(TestCase):
     """
Repository: wagtail/wagtail

Issue:
AdminAutoHeightTextInput doesn't auto-height on page load
`wagtailadmin.widgets.AdminAutoHeightTextInput` appears now to be the new default widget for `django.db.models.TextField`. It auto-heights when you type into it

![screen shot 2015-04-29 at 15 56 55](https://cloud.githubusercontent.com/assets/1473980/7393980/bbafebaa-ee88-11e4-83d5-01996cb5000a.png)

…but on reloading the page, the auto-heighting appears not to occur. This is four rows of text after reloading the page:

 ![screen shot 2015-04-29 at 15 57 14](https://cloud.githubusercontent.com/assets/1473980/7393979/bbaeeb4c-ee88-11e4-8f25-477b0f84eac9.png)

Three rows, with the exact same widget height:

![screen shot 2015-04-29 at 15 55 51](https://cloud.githubusercontent.com/assets/1473980/7393982/bbb10ac6-ee88-11e4-9892-1b2df7c6176a.png)

But two rows with a reduced widget height:

![screen shot 2015-04-29 at 15 52 37](https://cloud.githubusercontent.com/assets/1473980/7393984/bbb511a2-ee88-11e4-978e-a86c3a133465.png)

@davecranwell suggested an off-by-one error, which seems reasonable, given the slightly different heights above. 



Discussion:
My guess is that the height adjustment is being applied before the CSS has loaded, so it's not taking the margins into account. Maybe hooking it into the real document.onload event rather than the jquery 'ready' one would fix it...

:+1: @gasman 


Resolving patch:
diff --git a/wagtail/wagtailadmin/widgets.py b/wagtail/wagtailadmin/widgets.py
--- a/wagtail/wagtailadmin/widgets.py
+++ b/wagtail/wagtailadmin/widgets.py
@@ -24,7 +24,7 @@ def __init__(self, attrs=None):
         super(AdminAutoHeightTextInput, self).__init__(default_attrs)
 
     def render_js_init(self, id_, name, value):
-        return '$("#{0}").autosize();'.format(id_)
+        return 'autosize($("#{0}"));'.format(id_)
 
 class AdminDateInput(WidgetWithScript, widgets.DateInput):
     # Set a default date format to match the one that our JS date picker expects -


Test patch:
Repository: wagtail/wagtail

Issue:
Add ability to specify the number of related objects in InlinePanel
There are times where you'd want to limit a related object to N instance. Say, I want up to 4 related links. Currently one can accomplish this via a separate property, or `serve` method.

Ideally we would specify the maximum and/or mininum number of objects and the InlinePanel would behave accordingly.



Discussion:
That would be awesome

@gasman: @kaedroho was saying Django 1.7 introduces features equivalent to min/max on inline forms, on which I assume our InlinePanels are based. Could this be integrated here too?

Is this possible by now? I need to be able to limit the number of entries a user is able to add of a specified model field.


Resolving patch:
diff --git a/wagtail/wagtailadmin/edit_handlers.py b/wagtail/wagtailadmin/edit_handlers.py
--- a/wagtail/wagtailadmin/edit_handlers.py
+++ b/wagtail/wagtailadmin/edit_handlers.py
@@ -612,6 +612,10 @@ def required_formsets(cls):
             cls.relation_name: {
                 'fields': child_edit_handler_class.required_fields(),
                 'widgets': child_edit_handler_class.widget_overrides(),
+                'min_num': cls.min_num,
+                'validate_min': cls.min_num is not None,
+                'max_num': cls.max_num,
+                'validate_max': cls.max_num is not None
             }
         }
 
@@ -686,6 +690,8 @@ def __init__(self, *args, **kwargs):
         self.panels = kwargs.pop('panels', None)
         self.label = kwargs.pop('label', '')
         self.help_text = kwargs.pop('help_text', '')
+        self.min_num = kwargs.pop('min_num', None)
+        self.max_num = kwargs.pop('max_num', None)
 
         if kwargs:
             raise TypeError("InlinePanel got an unexpected keyword argument '%s'" % kwargs.keys()[0])
@@ -698,6 +704,8 @@ def bind_to_model(self, model):
             'panels': self.panels,
             'heading': self.label,
             'help_text': self.help_text,  # TODO: can we pick this out of the foreign key definition as an alternative? (with a bit of help from the inlineformset object, as we do for label/heading)
+            'min_num': self.min_num,
+            'max_num': self.max_num
         })
 
 


Test patch:
Repository: wagtail/wagtail

Issue:
Project template needs updating for search promotions changes
The provided view still references the EditorsPick model: https://github.com/torchbox/wagtail/blob/master/wagtail/project_template/search/views.py#L5

Shall we update this to use the new contrib module or remove it completely?



Discussion:
I think remove it. If we're confident enough to relegate modules to contrib, we should be confident enough to remove it. 


Resolving patch:
diff --git a/wagtail/project_template/search/views.py b/wagtail/project_template/search/views.py
--- a/wagtail/project_template/search/views.py
+++ b/wagtail/project_template/search/views.py
@@ -2,7 +2,7 @@
 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
 
 from wagtail.wagtailcore.models import Page
-from wagtail.wagtailsearch.models import Query, EditorsPick
+from wagtail.wagtailsearch.models import Query
 
 
 def search(request):
@@ -16,12 +16,8 @@ def search(request):
 
         # Record hit
         query.add_hit()
-
-        # Get search picks
-        search_picks = query.editors_picks.all()
     else:
         search_results = Page.objects.none()
-        search_picks = EditorsPick.objects.none()
 
     # Pagination
     paginator = Paginator(search_results, 10)
@@ -35,5 +31,4 @@ def search(request):
     return render(request, 'search/search.html', {
         'search_query': search_query,
         'search_results': search_results,
-        'search_picks': search_picks,
     })


Test patch:
Repository: wagtail/wagtail

Issue:
Spurious action buttons in group page permissions admin
Wagtail 0.8:
![screen shot 2015-08-11 at 15 54 42](https://cloud.githubusercontent.com/assets/85097/9200824/a1ed4464-4041-11e5-8661-a133edd83af9.png)

Wagtail 1.0:

![screen shot 2015-08-11 at 15 55 02](https://cloud.githubusercontent.com/assets/85097/9200829/a80bf9f8-4041-11e5-97d9-36a6bbdc169c.png)

(about to run a git bisect to see where the change happened)

The set of buttons on the page chooser widget is dodgy on several counts:
- the vertical layout pushes the widget out of alignment with the 'permission type' dropdown
- When the page is Root, 'Edit this page' leads to a 403 Forbidden error (and the usefulness of being able to edit from here is questionable anyhow)
- On both versions: We shouldn't have 'clear page' as an action (i.e. required should be True), because a page permission for a null page doesn't make sense.



Discussion:
The change was made in 82dc0ab2f6928be28502434c1ddc19d113403f60 (#1014).


Resolving patch:
diff --git a/wagtail/wagtailadmin/widgets.py b/wagtail/wagtailadmin/widgets.py
--- a/wagtail/wagtailadmin/widgets.py
+++ b/wagtail/wagtailadmin/widgets.py
@@ -66,6 +66,7 @@ class AdminChooser(WidgetWithScript, widgets.Input):
     choose_another_text = _("Choose another item")
     clear_choice_text = _("Clear choice")
     link_to_chosen_text = _("Edit this item")
+    show_edit_link = True
 
     def get_instance(self, model_class, value):
         # helper method for cleanly turning 'value' into an instance object
@@ -106,6 +107,8 @@ def __init__(self, **kwargs):
             self.clear_choice_text = kwargs.pop('clear_choice_text')
         if 'link_to_chosen_text' in kwargs:
             self.link_to_chosen_text = kwargs.pop('link_to_chosen_text')
+        if 'show_edit_link' in kwargs:
+            self.show_edit_link = kwargs.pop('show_edit_link')
         super(AdminChooser, self).__init__(**kwargs)
 
 
diff --git a/wagtail/wagtailusers/forms.py b/wagtail/wagtailusers/forms.py
--- a/wagtail/wagtailusers/forms.py
+++ b/wagtail/wagtailusers/forms.py
@@ -7,7 +7,7 @@
 from wagtail.wagtailcore import hooks
 from wagtail.wagtailadmin.widgets import AdminPageChooser
 from wagtail.wagtailusers.models import UserProfile
-from wagtail.wagtailcore.models import UserPagePermissionsProxy, GroupPagePermission
+from wagtail.wagtailcore.models import Page, UserPagePermissionsProxy, GroupPagePermission
 
 
 User = get_user_model()
@@ -229,9 +229,8 @@ def save(self):
 
 
 class GroupPagePermissionForm(forms.ModelForm):
-    def __init__(self, *args, **kwargs):
-        super(GroupPagePermissionForm, self).__init__(*args, **kwargs)
-        self.fields['page'].widget = AdminPageChooser()
+    page = forms.ModelChoiceField(queryset=Page.objects.all(),
+        widget=AdminPageChooser(show_edit_link=False))
 
     class Meta:
         model = GroupPagePermission


Test patch:
Repository: wagtail/wagtail

Issue:
AttributeError when passwords do not match on user creation form
Wagtail will crash with the following error if the two passwords don't match on the user creation form:

```
AttributeError at /admin/users/add/

'UserCreationForm' object has no attribute 'error_messages'
```

On this line: https://github.com/torchbox/wagtail/blob/master/wagtail/wagtailusers/forms.py#L92



Discussion:

Resolving patch:
diff --git a/wagtail/wagtailusers/forms.py b/wagtail/wagtailusers/forms.py
--- a/wagtail/wagtailusers/forms.py
+++ b/wagtail/wagtailusers/forms.py
@@ -43,8 +43,13 @@ def separate_username_field(self):
 
 
 class UserCreationForm(UsernameForm):
-
     required_css_class = "required"
+
+    error_messages = {
+        'duplicate_username': _("A user with that username already exists."),
+        'password_mismatch': _("The two password fields didn't match."),
+    }
+
     is_superuser = forms.BooleanField(
         label=_("Administrator"),
         required=False,


Test patch:
Repository: wagtail/wagtail

Issue:
"View live" button after page publish links to old URL if the slug was changed
1. Edit a page
2. Change the slug
3. Save
4. Click the "View live" button that appears in the notification bar at the top

It will take you to the old slug.



Discussion:

Resolving patch:
diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py
--- a/wagtail/wagtailadmin/views/pages.py
+++ b/wagtail/wagtailadmin/views/pages.py
@@ -251,6 +251,9 @@ def edit(request, page_id):
             # Publish
             if is_publishing:
                 revision.publish()
+                # Need to reload the page because the url has changed and we
+                # need access to it for the "View Live" button.
+                page = Page.objects.get(pk=page.pk)
 
             # Notifications
             if is_publishing:


Test patch:
diff --git a/wagtail/wagtailadmin/tests/test_pages_views.py b/wagtail/wagtailadmin/tests/test_pages_views.py
--- a/wagtail/wagtailadmin/tests/test_pages_views.py
+++ b/wagtail/wagtailadmin/tests/test_pages_views.py
@@ -671,10 +671,10 @@ def test_page_edit_post_publish(self):
         post_data = {
             'title': "I've been edited!",
             'content': "Some content",
-            'slug': 'hello-world',
+            'slug': 'hello-world-new',
             'action-publish': "Publish",
         }
-        response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data)
+        response = self.client.post(reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )), post_data, follow=True)
 
         # Should be redirected to explorer
         self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, )))
@@ -697,6 +697,11 @@ def test_page_edit_post_publish(self):
         # first_published_at should not change as it was already set
         self.assertEqual(first_published_at, child_page_new.first_published_at)
 
+        # The "View Live" button should have the updated slug.
+        for message in response.context['messages']:
+            self.assertIn('hello-world-new', message.message)
+            break
+
     def test_edit_post_publish_scheduled(self):
         go_live_at = timezone.now() + timedelta(days=1)
         expire_at = timezone.now() + timedelta(days=2)
Repository: wagtail/wagtail

Issue:
Cachebusting query parameter (e.g. _=1441835249458) not ignored by api
From the [documentation for jQuery.ajax, under "cache"](http://api.jquery.com/jquery.ajax/):

> Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_={timestamp}" to the GET parameters. The parameter is not needed for other types of requests, except in IE8 when a POST is made to a URL that has already been requested by a GET.

It seems like it's standard practice to ignore the underscore keyword. Unless I'm mistaken this is an oversight and not a disagreement on the principle of the thing.

Reproduce: make an Ajax call to any wagtail API endpoint with the cache flag set to false. Or just navigate to something like `http://localhost:8000/api/v1/pages/?type=home.HomePage&_=1441835249458`

You'll get this message: 

```
{
    "message": "query parameter is not an operation or a recognised field: _"
}
```



Discussion:

Resolving patch:
diff --git a/wagtail/contrib/wagtailapi/endpoints.py b/wagtail/contrib/wagtailapi/endpoints.py
--- a/wagtail/contrib/wagtailapi/endpoints.py
+++ b/wagtail/contrib/wagtailapi/endpoints.py
@@ -37,6 +37,9 @@ class BaseAPIEndpoint(GenericViewSet):
         'fields',
         'order',
         'search',
+
+        # Used by jQuery for cache-busting. See #1671
+        '_',
     ])
     extra_api_fields = []
     name = None  # Set on subclass.


Test patch:
Repository: wagtail/wagtail

Issue:
wagtailsearch.views.frontend needs updating to use non-deprecated search method
Currently using Page.search, which is deprecated in Wagtail 1.2 - should be updated to use the QuerySet-based mechanism instead.

https://github.com/torchbox/wagtail/blob/master/wagtail/wagtailsearch/views/frontend.py#L41



Discussion:
Is the "QuerySet-based mechanism" already defined, or should it be done ?


Resolving patch:
diff --git a/wagtail/wagtailsearch/views/frontend.py b/wagtail/wagtailsearch/views/frontend.py
--- a/wagtail/wagtailsearch/views/frontend.py
+++ b/wagtail/wagtailsearch/views/frontend.py
@@ -38,13 +38,18 @@ def search(
 
     # Search
     if query_string != '':
-        search_results = models.Page.search(
-            query_string,
-            show_unpublished=show_unpublished,
-            search_title_only=search_title_only,
-            extra_filters=extra_filters,
-            path=path if path else request.site.root_page.path
-        )
+        pages = models.Page.objects.filter(path__startswith=(path or request.site.root_page.path))
+
+        if not show_unpublished:
+            pages = pages.live()
+
+        if extra_filters:
+            pages = pages.filter(**extra_filters)
+
+        if search_title_only:
+            search_results = pages.search(query_string, fields=['title'])
+        else:
+            search_results = pages.search(query_string)
 
         # Get query object
         query = Query.get(query_string)


Test patch: