Hello community, here is the log from the commit of package python-django-crispy-forms for openSUSE:Factory checked in at 2020-06-10 00:51:01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-django-crispy-forms (Old) and /work/SRC/openSUSE:Factory/.python-django-crispy-forms.new.3606 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-django-crispy-forms" Wed Jun 10 00:51:01 2020 rev:8 rq:812876 version:1.9.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-django-crispy-forms/python-django-crispy-forms.changes 2020-04-04 12:27:15.988041743 +0200 +++ /work/SRC/openSUSE:Factory/.python-django-crispy-forms.new.3606/python-django-crispy-forms.changes 2020-06-10 00:51:02.799357881 +0200 @@ -1,0 +2,8 @@ +Tue Jun 9 11:00:22 UTC 2020 - Ondřej Súkup <mimi...@gmail.com> + +- Update to 1.9.1 + * Added Bootstrap 4 styling for clearable file widget. + * Fixed FileField UI bug + * Project now uses GitHub actions for testing + +------------------------------------------------------------------- Old: ---- django-crispy-forms-1.9.0.tar.gz New: ---- django-crispy-forms-1.9.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-django-crispy-forms.spec ++++++ --- /var/tmp/diff_new_pack.gF9Bw1/_old 2020-06-10 00:51:03.919360811 +0200 +++ /var/tmp/diff_new_pack.gF9Bw1/_new 2020-06-10 00:51:03.923360821 +0200 @@ -20,7 +20,7 @@ %define skip_python2 1 %define mod_name django-crispy-forms Name: python-%{mod_name} -Version: 1.9.0 +Version: 1.9.1 Release: 0 Summary: Django DRY Forms License: MIT ++++++ django-crispy-forms-1.9.0.tar.gz -> django-crispy-forms-1.9.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/PKG-INFO new/django-crispy-forms-1.9.1/PKG-INFO --- old/django-crispy-forms-1.9.0/PKG-INFO 2020-02-28 22:09:00.729307400 +0100 +++ new/django-crispy-forms-1.9.1/PKG-INFO 2020-05-16 08:06:42.649849400 +0200 @@ -1,6 +1,6 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.2 Name: django-crispy-forms -Version: 1.9.0 +Version: 1.9.1 Summary: Best way to have Django DRY forms Home-page: https://github.com/django-crispy-forms/django-crispy-forms Author: Miguel Araujo @@ -10,9 +10,7 @@ django-crispy-forms =================== - .. image:: https://travis-ci.org/django-crispy-forms/django-crispy-forms.png?branch=master - :alt: Build Status - :target: https://travis-ci.org/django-crispy-forms/django-crispy-forms + .. image:: https://github.com/django-crispy-forms/django-crispy-forms/workflows/C/I%20Testing./badge.svg .. image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/psf/black @@ -98,3 +96,4 @@ Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Python: >=3.5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/README.rst new/django-crispy-forms-1.9.1/README.rst --- old/django-crispy-forms-1.9.0/README.rst 2020-02-26 22:32:32.000000000 +0100 +++ new/django-crispy-forms-1.9.1/README.rst 2020-05-09 08:58:05.000000000 +0200 @@ -2,9 +2,7 @@ django-crispy-forms =================== -.. image:: https://travis-ci.org/django-crispy-forms/django-crispy-forms.png?branch=master - :alt: Build Status - :target: https://travis-ci.org/django-crispy-forms/django-crispy-forms +.. image:: https://github.com/django-crispy-forms/django-crispy-forms/workflows/C/I%20Testing./badge.svg .. image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/psf/black diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/crispy_forms/__init__.py new/django-crispy-forms-1.9.1/crispy_forms/__init__.py --- old/django-crispy-forms-1.9.0/crispy_forms/__init__.py 2020-02-26 23:13:22.000000000 +0100 +++ new/django-crispy-forms-1.9.1/crispy_forms/__init__.py 2020-05-16 08:03:53.000000000 +0200 @@ -1 +1 @@ -__version__ = "1.9.0" +__version__ = "1.9.1" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/crispy_forms/helper.py new/django-crispy-forms-1.9.1/crispy_forms/helper.py --- old/django-crispy-forms-1.9.0/crispy_forms/helper.py 2020-02-26 22:32:32.000000000 +0100 +++ new/django-crispy-forms-1.9.1/crispy_forms/helper.py 2020-05-01 20:02:08.000000000 +0200 @@ -337,10 +337,12 @@ if template_pack == "bootstrap4": if "form-horizontal" in self.form_class.split(): - bootstrap_size_match = re.findall(r"col-(xl|lg|md|sm)-(\d+)", self.label_class) + bootstrap_size_match = re.findall(r"col(-(xl|lg|md|sm))?-(\d+)", self.label_class) if bootstrap_size_match: - offset_pattern = "offset-%s-%s" - items["bootstrap_checkbox_offsets"] = [offset_pattern % m for m in bootstrap_size_match] + offset_pattern = "offset%s-%s" + items["bootstrap_checkbox_offsets"] = [ + offset_pattern % (m[0], m[-1]) for m in bootstrap_size_match + ] else: bootstrap_size_match = re.findall(r"col-(lg|md|sm|xs)-(\d+)", self.label_class) if bootstrap_size_match: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/crispy_forms/templates/bootstrap4/field.html new/django-crispy-forms-1.9.1/crispy_forms/templates/bootstrap4/field.html --- old/django-crispy-forms-1.9.0/crispy_forms/templates/bootstrap4/field.html 2020-02-16 08:47:31.000000000 +0100 +++ new/django-crispy-forms-1.9.1/crispy_forms/templates/bootstrap4/field.html 2020-05-09 09:00:14.000000000 +0200 @@ -35,7 +35,7 @@ {{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %} </label> {% include 'bootstrap4/layout/help_text_and_errors.html' %} - {% elif field|is_file and not field|is_clearable_file and use_custom_control %} + {% elif field|is_file and use_custom_control %} {% include 'bootstrap4/layout/field_file.html' %} {% else %} <div class="{{ field_class }}"> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/crispy_forms/templates/bootstrap4/layout/field_file.html new/django-crispy-forms-1.9.1/crispy_forms/templates/bootstrap4/layout/field_file.html --- old/django-crispy-forms-1.9.0/crispy_forms/templates/bootstrap4/layout/field_file.html 2020-02-01 23:10:41.000000000 +0100 +++ new/django-crispy-forms-1.9.1/crispy_forms/templates/bootstrap4/layout/field_file.html 2020-05-16 08:03:46.000000000 +0200 @@ -1,16 +1,52 @@ {% load crispy_forms_field %} -<div class="custom-file {{ field_class }}"> - {% crispy_field field 'class' 'custom-file-input' %} - <label class="custom-file-label" for="{{ field.id_for_label }}">Choose file</label> +<div class="{{ field_class }} mb-2"> +{% for widget in field.subwidgets %} +{% if widget.data.is_initial %} +<div class="input-group mb-2"> + <div class="input-group-prepend"> + <span class="input-group-text">{{ widget.data.initial_text }}</span> + </div> + <div class="form-control d-flex"> + <span style="flex-grow: 1;"> + <a href="{{ field.value.url }}">{{ field.value }}</a> + </span> + {% if not widget.data.required %} + <span class=" "> + <span class="custom-control custom-checkbox"> + <input type="checkbox" name="{{ widget.data.checkbox_name }}" id="{{ widget.data.checkbox_id }}" class="custom-control-input"{% if field.field.disabled %} disabled{% endif %} > + <label class="custom-control-label mb-0" for="{{ widget.data.checkbox_id }}">{{ widget.data.clear_checkbox_label }}</label> + </span> + </span> + {% endif %} + </div> +</div> +<div class="input-group mb-0"> + <div class="input-group-prepend"> + <span class="input-group-text">{{ widget.data.input_text }}</span> + </div> +{% endif %} + <div class="form-control custom-file{% if field.errors %} is-invalid{%endif%}" style="border:0"> + <input type="{{ widget.data.type }}" name="{{ widget.data.name }}" class="custom-file-input{% if field.errors %} is-invalid{%endif%}" {% if field.field.disabled %}disabled{% endif %} {% for name, value in field.field.widget.attrs.items %}{% if value is not False %} {{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}{% endfor %}> + <label class="custom-file-label" for="{{ field.id_for_label }}">---</label> + <script type="text/javascript" id="script-{{ field.id_for_label }}"> + document.getElementById("script-{{ field.id_for_label }}").parentNode.querySelector('.custom-file-input').onchange = function (e){ + var filenames = ""; + for (let i=0;i<e.target.files.length;i++){ + filenames+=(i>0?", ":"")+e.target.files[i].name; + } + e.target.parentNode.querySelector('.custom-file-label').textContent=filenames; + } + </script> + </div> + {% if not widget.data.is_initial %} {% include 'bootstrap4/layout/help_text_and_errors.html' %} - <script type="text/javascript" id="script-{{ field.id_for_label }}"> - document.getElementById("script-{{ field.id_for_label }}").parentNode.querySelector('.custom-file-input').onchange = function (e){ - var filenames = ""; - for (let i=0;i<e.target.files.length;i++){ - filenames+=(i>0?", ":"")+e.target.files[0].name; - } - e.target.parentNode.querySelector('.custom-file-label').innerHTML=filenames; - } - </script> + {% endif %} +{% if widget.data.is_initial %} +</div> +<div class="input-group mb-0"> +{% include 'bootstrap4/layout/help_text_and_errors.html' %} +</div> +{% endif %} +{% endfor %} </div> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/crispy_forms/templates/bootstrap4/layout/formactions.html new/django-crispy-forms-1.9.1/crispy_forms/templates/bootstrap4/layout/formactions.html --- old/django-crispy-forms-1.9.0/crispy_forms/templates/bootstrap4/layout/formactions.html 2020-02-01 23:10:41.000000000 +0100 +++ new/django-crispy-forms-1.9.1/crispy_forms/templates/bootstrap4/layout/formactions.html 2020-05-01 20:02:08.000000000 +0200 @@ -1,4 +1,4 @@ -<div{% if formactions.attrs %} {{ formactions.flat_attrs|safe }}{% endif %} class="form-group"> +<div{% if formactions.attrs %} {{ formactions.flat_attrs|safe }}{% endif %} class="form-group{% if 'form-horizontal' in form_class %} row{% endif %}"> {% if label_class %} <div class="aab {{ label_class }}"></div> {% endif %} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/crispy_forms/tests/forms.py new/django-crispy-forms-1.9.1/crispy_forms/tests/forms.py --- old/django-crispy-forms-1.9.0/crispy_forms/tests/forms.py 2020-02-26 22:32:32.000000000 +0100 +++ new/django-crispy-forms-1.9.1/crispy_forms/tests/forms.py 2020-05-09 09:00:14.000000000 +0200 @@ -144,3 +144,20 @@ class Meta: model = CrispyTestModel fields = ("email", "password2", "password") + + +class FakeFieldFile: + """ + Quacks like a FieldFile (has a .url and string representation), but + doesn't require us to care about storages etc. + """ + + url = "something" + + def __str__(self): + return self.url + + +class FileForm(forms.Form): + file_field = forms.FileField(widget=forms.FileInput) + clearable_file = forms.FileField(widget=forms.ClearableFileInput, required=False, initial=FakeFieldFile()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/crispy_forms/tests/test_form_helper.py new/django-crispy-forms-1.9.1/crispy_forms/tests/test_form_helper.py --- old/django-crispy-forms-1.9.0/crispy_forms/tests/test_form_helper.py 2020-02-26 22:32:32.000000000 +0100 +++ new/django-crispy-forms-1.9.1/crispy_forms/tests/test_form_helper.py 2020-05-01 20:02:08.000000000 +0200 @@ -851,6 +851,7 @@ @only_bootstrap4 def test_label_class_and_field_class_bs4_offset_when_horizontal(): + # Test col-XX-YY pattern form = SampleForm() form.helper = FormHelper() form.helper.label_class = "col-lg-2" @@ -862,13 +863,18 @@ assert '<div class="offset-lg-2 col-lg-8">' in html assert html.count("col-lg-8") == 7 - form.helper.label_class = "col-sm-3 col-md-4" - form.helper.field_class = "col-sm-8 col-md-6" + # Test multi col-XX-YY pattern and col-X pattern + + form.helper.label_class = "col-sm-3 col-md-4 col-5 col-lg-4" + form.helper.field_class = "col-sm-8 col-md-6 col-7 col-lg-8" html = render_crispy_form(form) assert '<div class="form-group row">' in html - assert '<div class="offset-sm-3 offset-md-4 col-sm-8 col-md-6">' in html + assert '<div class="offset-sm-3 offset-md-4 offset-5 offset-lg-4 col-sm-8 col-md-6 col-7 col-lg-8">' in html assert html.count("col-sm-8") == 7 + assert html.count("col-md-6") == 7 + assert html.count("col-7") == 7 + assert html.count("col-lg-8") == 7 @only_bootstrap4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/crispy_forms/tests/test_layout.py new/django-crispy-forms-1.9.1/crispy_forms/tests/test_layout.py --- old/django-crispy-forms-1.9.0/crispy_forms/tests/test_layout.py 2020-02-26 22:32:32.000000000 +0100 +++ new/django-crispy-forms-1.9.1/crispy_forms/tests/test_layout.py 2020-05-16 08:03:46.000000000 +0200 @@ -18,6 +18,7 @@ CheckboxesSampleForm, CrispyEmptyChoiceTestModel, CrispyTestModel, + FileForm, SampleForm, SampleForm2, SampleForm3, @@ -598,3 +599,33 @@ form.helper["password1"].update_attributes(css_class="hello2") html = render_crispy_form(form) assert html.count(' class="hello hello2 textinput') == 1 + + +@only_bootstrap4 +def test_file_field(): + form = FileForm() + form.helper = FormHelper() + form.helper.layout = Layout("clearable_file") + html = render_crispy_form(form) + assert '<span class="custom-control custom-checkbox">' in html + assert '<input type="file" name="clearable_file" class="custom-file-input" >' in html + + form.helper.use_custom_control = False + html = render_crispy_form(form) + assert '<input type="checkbox" name="clearable_file-clear" id="clearable_file-clear_id">' in html + assert '<input type="file" name="clearable_file" class="custom-file-input" >' not in html + + form.helper.use_custom_control = True + form.helper.layout = Layout("file_field") + html = render_crispy_form(form) + assert ( + '<div class="form-control custom-file" style="border:0"> <input type="file" name="file_field" ' + 'class="custom-file-input" > <label class="custom-file-label" for="id_file_field">---</label>' in html + ) + + form.helper.use_custom_control = False + html = render_crispy_form(form) + assert ( + '<div class="form-control custom-file" style="border:0"> <input type="file" name="file_field" ' + 'class="custom-file-input" > <label class="custom-file-label" for="id_file_field">---</label>' not in html + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/crispy_forms/tests/test_utils.py new/django-crispy-forms-1.9.1/crispy_forms/tests/test_utils.py --- old/django-crispy-forms-1.9.0/crispy_forms/tests/test_utils.py 2020-02-26 22:32:32.000000000 +0100 +++ new/django-crispy-forms-1.9.1/crispy_forms/tests/test_utils.py 2020-05-09 09:00:14.000000000 +0200 @@ -1,9 +1,11 @@ from django import forms from django.template.base import Template from django.template.context import Context +from django.test import SimpleTestCase from crispy_forms.helper import FormHelper from crispy_forms.layout import Layout +from crispy_forms.tests.utils import contains_partial from crispy_forms.utils import list_difference, list_intersection, render_field @@ -46,3 +48,34 @@ rendered = template.render(Context({"form": MyForm(data={"f": "something"})})) assert extra in rendered + + +def test_contains_partial(): + c = SimpleTestCase() + needle = "<span></span>" + html = "<form>%s</form>" + c.assertTrue(contains_partial(html % needle, needle)) + + needle = "<span></span><b></b>" + c.assertRaises(NotImplementedError, contains_partial, html % needle, needle) + + needle = "<span>a</span>" + c.assertRaises(NotImplementedError, contains_partial, html % needle, needle) + + needle = '<span id="e"></span>' + html = '<form id="tt"><span id="f"></span>%s</form>' + c.assertTrue(contains_partial(html % needle, needle)) + + missing = "<script></script>" + c.assertFalse(contains_partial(html % missing, needle)) + + needle = '<span id="e"></span>' + html = '<form id="tt"><span id="f"></span>%s</form>' + missing = '<span id="g"></span>' + c.assertFalse(contains_partial(html % missing, needle)) + + needle = '<div id="r"><span>toto</span></div>' + html = '<form><div id="r"></div></form>' + c.assertRaises(NotImplementedError, contains_partial, html, needle) + # as we do not look at the children, needle is equivalent to <div id="r"></div> which IS in html + c.assertTrue(contains_partial(html, needle, ignore_needle_children=True)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/crispy_forms/tests/utils.py new/django-crispy-forms-1.9.1/crispy_forms/tests/utils.py --- old/django-crispy-forms-1.9.0/crispy_forms/tests/utils.py 2020-02-26 22:32:32.000000000 +0100 +++ new/django-crispy-forms-1.9.1/crispy_forms/tests/utils.py 2020-05-09 09:00:14.000000000 +0200 @@ -1,7 +1,7 @@ from django.test.html import Element, parse_html -def contains_partial(haystack, needle): +def contains_partial(haystack, needle, ignore_needle_children=False): """Search for a html element with at least the corresponding elements (other elements may be present in the matched element from the haystack) """ @@ -10,6 +10,13 @@ if not isinstance(needle, Element): needle = parse_html(needle) + if len(needle.children) > 0 and not ignore_needle_children: + raise NotImplementedError("contains_partial does not check needle's children:%s" % str(needle.children)) + if needle.name == haystack.name and set(needle.attributes).issubset(haystack.attributes): return True - return any(contains_partial(child, needle) for child in haystack.children if isinstance(child, Element)) + return any( + contains_partial(child, needle, ignore_needle_children=ignore_needle_children) + for child in haystack.children + if isinstance(child, Element) + ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/django_crispy_forms.egg-info/PKG-INFO new/django-crispy-forms-1.9.1/django_crispy_forms.egg-info/PKG-INFO --- old/django-crispy-forms-1.9.0/django_crispy_forms.egg-info/PKG-INFO 2020-02-28 22:08:59.000000000 +0100 +++ new/django-crispy-forms-1.9.1/django_crispy_forms.egg-info/PKG-INFO 2020-05-16 08:06:42.000000000 +0200 @@ -1,6 +1,6 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.2 Name: django-crispy-forms -Version: 1.9.0 +Version: 1.9.1 Summary: Best way to have Django DRY forms Home-page: https://github.com/django-crispy-forms/django-crispy-forms Author: Miguel Araujo @@ -10,9 +10,7 @@ django-crispy-forms =================== - .. image:: https://travis-ci.org/django-crispy-forms/django-crispy-forms.png?branch=master - :alt: Build Status - :target: https://travis-ci.org/django-crispy-forms/django-crispy-forms + .. image:: https://github.com/django-crispy-forms/django-crispy-forms/workflows/C/I%20Testing./badge.svg .. image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/psf/black @@ -98,3 +96,4 @@ Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Software Development :: Libraries :: Python Modules +Requires-Python: >=3.5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/pyproject.toml new/django-crispy-forms-1.9.1/pyproject.toml --- old/django-crispy-forms-1.9.0/pyproject.toml 2020-02-26 22:32:32.000000000 +0100 +++ new/django-crispy-forms-1.9.1/pyproject.toml 2020-05-01 20:02:08.000000000 +0200 @@ -1,3 +1,4 @@ [tool.black] line-length = 119 target-version = ['py35'] +include = '(crispy_forms)\/(.+)(py?$)' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-crispy-forms-1.9.0/setup.py new/django-crispy-forms-1.9.1/setup.py --- old/django-crispy-forms-1.9.0/setup.py 2020-02-26 22:32:32.000000000 +0100 +++ new/django-crispy-forms-1.9.1/setup.py 2020-05-09 08:58:05.000000000 +0200 @@ -50,4 +50,5 @@ packages=find_packages(exclude=['docs']), include_package_data=True, zip_safe=False, + python_requires='>=3.5', )