[Python-modules-commits] [python-django-crispy-forms] 01/09: Import python-django-crispy-forms_1.5.2.orig.tar.gz

Michael Fladischer fladi at moszumanska.debian.org
Wed Oct 14 11:05:03 UTC 2015


This is an automated email from the git hooks/post-receive script.

fladi pushed a commit to branch master
in repository python-django-crispy-forms.

commit 344c07764ac3ae019953240edfdc5045a4af1dc9
Author: Michael Fladischer <FladischerMichael at fladi.at>
Date:   Wed Oct 14 11:54:49 2015 +0200

    Import python-django-crispy-forms_1.5.2.orig.tar.gz
---
 .coveragerc                                        |    2 +
 .editorconfig                                      |   18 +
 .gitignore                                         |    1 +
 .travis.yml                                        |   37 +-
 CHANGELOG.md                                       |   74 +-
 CONTRIBUTORS.txt                                   |   20 +-
 LICENSE.txt                                        |    2 +-
 MANIFEST.in                                        |    2 +-
 Makefile                                           |    6 +-
 README.rst                                         |    5 +-
 crispy_forms/__init__.py                           |    2 +-
 crispy_forms/base.py                               |   43 +-
 crispy_forms/bootstrap.py                          |  205 ++--
 crispy_forms/compatibility.py                      |   33 +
 crispy_forms/helper.py                             |   77 +-
 crispy_forms/layout.py                             |  181 ++--
 crispy_forms/layout_slice.py                       |    4 +-
 crispy_forms/templates/bootstrap/display_form.html |    1 +
 crispy_forms/templates/bootstrap/field.html        |   16 +-
 crispy_forms/templates/bootstrap/layout/alert.html |    4 +-
 .../{uni_form => bootstrap}/layout/div.html        |    2 +-
 .../templates/bootstrap/layout/fieldset.html       |    6 +
 .../bootstrap/layout/prepended_appended_text.html  |    4 +-
 .../templates/bootstrap/table_inline_formset.html  |   26 +-
 crispy_forms/templates/bootstrap/uni_form.html     |   13 +-
 .../templates/bootstrap3/display_form.html         |    1 +
 crispy_forms/templates/bootstrap3/field.html       |   30 +-
 crispy_forms/templates/bootstrap3/field.html.bk    |   49 -
 .../templates/bootstrap3/field.strict.html         |   31 -
 crispy_forms/templates/bootstrap3/inputs.html      |   13 +
 .../templates/bootstrap3/layout/alert.html         |    4 +
 .../bootstrap3/layout/checkboxselectmultiple.html  |    5 +-
 .../{uni_form => bootstrap3}/layout/div.html       |    2 +-
 .../templates/bootstrap3/layout/fieldset.html      |    6 +
 .../templates/bootstrap3/layout/formactions.html   |   10 +-
 .../templates/bootstrap3/layout/inline_field.html  |    2 +-
 .../bootstrap3/layout/prepended_appended_text.html |   14 +-
 .../templates/bootstrap3/layout/radioselect.html   |    4 +-
 .../bootstrap3/layout/radioselect_inline.html      |    2 +-
 .../templates/bootstrap3/table_inline_formset.html |   33 +-
 crispy_forms/templates/bootstrap3/uni_form.html    |   13 +-
 .../templates/bootstrap3/whole_uni_form.html       |    9 +-
 crispy_forms/templates/uni_form/display_form.html  |    1 +
 .../templates/uni_form/layout/baseinput.html       |   16 +-
 crispy_forms/templates/uni_form/layout/div.html    |    2 +-
 crispy_forms/templates/uni_form/multifield.html    |    2 +-
 crispy_forms/templates/uni_form/uni_form.html      |    1 +
 crispy_forms/templatetags/crispy_forms_field.py    |   40 +-
 crispy_forms/templatetags/crispy_forms_filters.py  |   13 +-
 crispy_forms/templatetags/crispy_forms_tags.py     |   72 +-
 crispy_forms/templatetags/crispy_forms_utils.py    |   47 +-
 crispy_forms/tests/__init__.py                     |    5 -
 crispy_forms/tests/base.py                         |   35 -
 crispy_forms/tests/compatibility.py                |    9 +
 crispy_forms/tests/conftest.py                     |   42 +
 crispy_forms/tests/forms.py                        |   33 +-
 crispy_forms/tests/runtests.py                     |   15 -
 crispy_forms/tests/runtests_bootstrap.py           |   32 -
 crispy_forms/tests/runtests_bootstrap3.py          |   33 -
 crispy_forms/tests/runtests_uniform.py             |   29 -
 crispy_forms/tests/test_dynamic_api.py             | 1017 +++++++++----------
 crispy_forms/tests/test_form_helper.py             | 1023 ++++++++++---------
 crispy_forms/tests/test_layout.py                  | 1025 ++++++++++----------
 crispy_forms/tests/test_layout_objects.py          |  411 ++++----
 crispy_forms/tests/test_settings.py                |   22 +-
 crispy_forms/tests/test_tags.py                    |  231 ++---
 crispy_forms/tests/urls.py                         |   12 +-
 crispy_forms/tests/utils.py                        |   68 --
 crispy_forms/utils.py                              |   63 +-
 docs/.DS_Store                                     |  Bin 6148 -> 0 bytes
 docs/conf.py                                       |    5 +-
 docs/contributing.rst                              |    5 +-
 docs/crispy_tag_forms.rst                          |   34 +-
 docs/crispy_tag_formsets.rst                       |   10 +-
 docs/dynamic_layouts.rst                           |   10 +-
 docs/faq.rst                                       |    6 +-
 docs/form_helper.rst                               |   15 +-
 docs/index.rst                                     |    1 +
 docs/install.rst                                   |    6 +-
 docs/template_packs.rst                            |   70 ++
 requirements.txt                                   |    8 +-
 setup.py                                           |   24 +-
 tox.ini                                            |   14 +
 83 files changed, 2894 insertions(+), 2625 deletions(-)

diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 0000000..398ff08
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,2 @@
+[run]
+branch = True
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..57f7c78
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,18 @@
+# http://editorconfig.org
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.{html,py,rst}]
+indent_style = space
+indent_size = 4
+
+[*.{html,rst}]
+trim_trailing_whitespace = false
+
+[Makefile]
+indent_style = tab
+insert_final_newline = false
diff --git a/.gitignore b/.gitignore
index e8f4b75..64ad0a6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,7 @@ tempfile
 
 # coverage 
 .coverage
+htmlcov
 _build
 
 # OSX
diff --git a/.travis.yml b/.travis.yml
index 2e23f94..754e1ed 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,23 +1,44 @@
 language: python
+
+sudo: false
+
 python:
   - "2.6"
   - "2.7"
+  - "3.2"
   - "3.3"
+  - "3.4"
 env:
-  - DJANGO=1.3.7
-  - DJANGO=1.4.5
-  - DJANGO=1.5.1
+  - DJANGO='django>=1.4.0,<1.5.0'
+  - DJANGO='django>=1.7.0,<1.8.0'
+  - DJANGO='django>=1.8.0,<1.9.0'
+  - DJANGO='https://github.com/django/django/archive/master.tar.gz'
 install:
-  - pip install Django==$DJANGO
-  - pip install "file://`pwd`#egg=django-crispy-forms[tests]"
-  - pip install -e . --use-mirrors
+  - pip install $DJANGO
+  - pip install -e .
 script:
   - make test
 notifications:
   email: false
 matrix:
   exclude:
+    - python: "3.2"
+      env: DJANGO='django>=1.4.0,<1.5.0'
+    - python: "3.2"
+      env: DJANGO='https://github.com/django/django/archive/master.tar.gz'
     - python: "3.3"
-      env: DJANGO=1.4.5
+      env: DJANGO='django>=1.4.0,<1.5.0'
     - python: "3.3"
-      env: DJANGO=1.3.7
+      env: DJANGO='https://github.com/django/django/archive/master.tar.gz'
+    - python: "3.4"
+      env: DJANGO='django>=1.4.0,<1.5.0'
+    - python: "2.6"
+      env: DJANGO='django>=1.7.0,<1.8.0'
+    - python: "2.6"
+      env: DJANGO='django>=1.8.0,<1.9.0'
+    - python: "2.6"
+      env: DJANGO='https://github.com/django/django/archive/master.tar.gz'
+  allow_failures:
+    - env: DJANGO='https://github.com/django/django/archive/master.tar.gz'
+after_success:
+  - bash <(curl -s https://codecov.io/bash)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 389661d..f407784 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,52 @@
 # CHANGELOG for django-crispy-forms
 
-## 1.4.0
+## 1.5.2 (2015/9/10)
+
+  * Fix: KeyError: u'wrapper_class' when clearing template context. #511, #512
+  * Fix: Alignment of stacked checkboxes and radio buttons in Bootstrap 3 #358
+
+See [1.5.2 Milestone](https://github.com/maraujop/django-crispy-forms/issues?utf8=✓&q=milestone%3A1.5.2+) for full issue list.
+
+
+## 1.5.1 (2015/8/21)
+
+Special thanks in this release to Dmitry Dygalo @Stranger6667 for a marathon effort updating the
+test suite and code base.
+
+  * Switched to py.test. Modernised test suite. Enabled tox, code coverage and Travis for all
+    supported Python/Django versions. [See list of Merged "Testing/Process" PRs here](https://github.com/maraujop/django-crispy-forms/pulls?q=is%3Apr+is%3Amerged+milestone%3A1.5.1+label%3ATesting%2FProcess)
+  * Added compatibility with Python 3.2
+  * Fix: Allow LayoutObject & BaseInputs to accept custom template #493
+
+
+## 1.5.0 (2015/8/16)
+
+Special thanks in this release for all the **<a href="http://flattr.com/thing/512037/django-crispy-forms">supporters and donators</a>**.
+
+ * Fixed compatibility with: Python 3, Django 1.7, Django 1.8 and Django 1.4.16. Merged PR #417, but thanks to PRs #369, #368 and #310. Closes also #383.
+ * Updated test suite for compatibility with all supported Django versions 1.4, 1.7, 1.8 and run CI against these and Django `master`. See #451, #455.
+ * Bug fix for specifying `template_pack` in `{% crispy %}` tag, `bootstrap3` couldn't be set that way.
+ * New doc section for creating custom template packs.
+ * Fixed Bootstrap3 checkbox alignment issues with label texts, see #275.
+ * First `AccordionGroup` can now be set to `active=False`, see #246.
+ * Fixed Bootstrap3 checkbox alignment issues for all device sizes, see #225 and #267.
+ * All forms are now rendered with {{ form.media }}, this makes forms containing widgets with `Media` meta class work, see #263.
+ * Adjusted `{% specialspaceless %}` to avoid breaking intended spaces and be less aggressive, see #250.
+ * Fixed inputs rendering for bootstrap3 and redo `FormActions` layout object bootstrap3 template for correct alignment, see #279.
+ * `MultiField` now obeys `form_show_labels`, see #278.
+ * Added `wrapper_class` to `bootstrap.InlineRadios`, see #272.
+ * Render label for checkboxes within `table_inline_formset.html`, see #262.
+ * Removed deprecated layout object `AppendedPrependedText`, replaced by `PrependedAppendedText`.
+ * Fixed `PrependedAppendedText` when rendering a select widget, in bootstrap and bootstrap3 template packs, see #258.
+ * Added support to `{% crispy_addon %}` tag for `form_show_labels`, see #256.
+ * Major cleanup and refactor of the template pack system thanks to @tepez, see #217 and #237:
+    - Template packs are now self contained/independent, removing dangerous cross references. If you have a custom template pack this can cause backwards incompatibility, but it will pay in the future to adjust to this changes.
+    - `MultiField` cannot be used with `bootstrap` or `bootstrap3` template packs.
+    - Added `template_pack` `FormHelper` attribute, so that template packs can be specified at form helper level. This changes layout objects `render` behavior.
+ * Default template pack is now `bootstrap3`.
+ * Make `CRISPY_TEMPLATE_PACK` setting optional, see #237 and #244.
+
+## 1.4.0 (2013/9/1)
 
 Special thanks in this release to **James Friedman <a href="https://github.com/jamesmfriedman">@jamesmfriedman</a>**, for his amazing support in PR #213, adding initial Bootstrap 3 support.
 
@@ -12,7 +58,7 @@ Special thanks in this release to **James Friedman <a href="https://github.com/j
  * Added support for horizontal forms in bootstrap3, see #209.
  * Fixed spaces missing when rendering several submit inputs continued, see #211.
  * Fixed checkboxes and radios for Bootstrap3, adjusted multiple inline radios and checkboxes, see #225.
- * Update accordion markup for bootstrap3 compatibilty, see #229.
+ * Update accordion markup for bootstrap3 compatibility, see #229.
  * Moved `UneditableField` to bootstrap module, place where it should live, no backwards compatible import left behind.
  * Added `bootstrap3` template pack thanks to James Friedman, see #213 and #209.
  * `RadioSelect` and `CheckboxSelectMultiple` widget values and texts were being localized, when they shouldn't bee, see #214.
@@ -40,7 +86,7 @@ Special thanks in this release to **Charlie Denton <a href="https://github.com/m
  * Added a settings variable named `CRISPY_ALLOWED_TEMPLATE_PACKS` for adding easily support for new template packs, see #192.
  * Added `{% crispy_addon %}` tag, see #195.
  * Make `CRISPY_TEMPLATE_PACK` optional for tests
- * Make tests run the same exacty way with `runtests.py` and `manage.py test`, see #183.
+ * Make tests run the same exactly way with `runtests.py` and `manage.py test`, see #183.
  * Bug fix for `wrap_together` when using it with partial slices.
  * Fixes for `KeepContext` context manager, see #180.
  * Added `FormHelper.field_template` attribute, for easily override field template for a specific form/formset, see docs.
@@ -133,7 +179,7 @@ Special thanks in this release to **Charlie Denton <a href="https://github.com/m
  * Fixed some flaws in new testing structure by Markus Hametner.
  * Added helper attribute `error_text_inline` thanks to Lee Semel for controlling how to render form errors, as a block or inline, see #GH-87.
  * Support `ModelMultipleChoiceField` on `checkboxselectmultiple`, see #GH-86.
- * Redoing testing structure a litte bit, to run uni_form and bootstrap tests separately. They share most of the code base, but templates pack are separate and we need to care both have the same quality assurance.
+ * Redoing testing structure a little bit, to run uni_form and bootstrap tests separately. They share most of the code base, but templates pack are separate and we need to care both have the same quality assurance.
  * `AppendedText`, `PrependedText` and `AppendedPrependedText` were not respecting `form_show_errors` helper attribute, see #GH-77.
  * Added a version string to the app under root __init__, see #GH-76.
  * Added `html5_required` helper attribute for rendering required fields using HTML5 required attribute within the input, see #GH-72. Thanks to Lloyd Philbrook.
@@ -194,18 +240,18 @@ Special thanks in this release to **Charlie Denton <a href="https://github.com/m
 ## 1.1.0
 
  * Fixing produced html by a checkbox field, closing label the right way and rendering checkbox in the right place.
- * Passing full context to field rendering, to be consistent and having acess in `field.html` template to helper attributes.
+ * Passing full context to field rendering, to be consistent and having access in `field.html` template to helper attributes.
  * Custom helper attributes can now be set and will be part of templates context, this way you can define custom specific behavior.
  * Adding @kennethlove bootstrap template pack into django-crispy-forms core.
  * Adding `CRISPY_TEMPLATE_PACK` setting variable to easily switch between different template packs. Default template pack is now bootstrap.
  * Upgrading bootstrap templates, fixing some bugs and redoing the hierarchy.
- * Upgrading tests for multiple template packs. 
+ * Upgrading tests for multiple template packs.
  * Renaming `UNIFORM_FAIL_SILENTLY` setting variable to `CRISPY_FAIL_SILENTLY`, upgrading migration instructions.
  * Redoing bootstrap `field.html` template to render `radioselect` and `checkboxselectmultiple` Django widgets a la bootstrap.
  * Adding a `render_unmentioned_fields` helper attribute, that renders all fields in a form, no matter what the layout is. Default is `False`.
  * Adding a `|css_class` filter that renders field classes in an elegant way.
  * Turning `|with_class` filter into `{% crispy_field %}` tag, so that parameters for rendering the field can be passed.
- * Adding a `help_text_inline` helper attribute, that controls wether to render help texts in bootstrap with "help-inline" or "help-block".
+ * Adding a `help_text_inline` helper attribute, that controls whether to render help texts in bootstrap with "help-inline" or "help-block".
  * Adding a `flat_attrs` variable to the context passed to `field.html` to be able to do all kind of html attributes when rendering a field, using `Field` layout object.
  * Adding a `template` kwarg to `Field` layout object that allows to override template used for rendering a field.
  * Adding a `bootstrap.py` module that holds bootstrap specific layout objects, for higher bootstrap integration.
@@ -214,7 +260,7 @@ Special thanks in this release to **Charlie Denton <a href="https://github.com/m
 ## 1.0.0
 
  * Using `baseinput.html` template within `whole_uni_form.html`, to be DRY and consistent.
- * `BaseInput` subclasses like `Submit` can now have ids set, ussing `css_id`
+ * `BaseInput` subclasses like `Submit` can now have ids set, using `css_id`
  * Adding a simplified alternative syntax for `{% uni_form %}` tag. We can now do `{% uni_form form %}` for rendering a form using a helper, instead of `{% uni_form form form.helper %}`, if the `FormHelper` attribute attached to the form is named `helper`.
  * Improving `rendered_fields` checking performance.
  * Layouts are now rendered strictly. We don't render fields missed in the layout. If the form has a Meta class with `fields` or `exclude`, then we follow Django standards.
@@ -222,7 +268,7 @@ Special thanks in this release to **Charlie Denton <a href="https://github.com/m
  * Fixed #GH-111 we were not rendering all the classes in `|with_class` filter
  * Moving django-uni-form to django-crispy-forms. Renaming tags, filters and modules. Updating tests and so on. Adding migration instructions.
  * More work on simpler and easier docs.
- * Adding `form_show_errors` helper attribute, that controls wether to render or not `form.errors`
+ * Adding `form_show_errors` helper attribute, that controls whether to render or not `form.errors`
  * Improving template hierarchy for more template code reusability.
 
 # CHANGELOG for django-uni-form
@@ -236,11 +282,11 @@ http://tothinkornottothink.com/post/10398684502/django-uni-form-0-9-0-is-out-sec
  * Fixed a problem on Fieldset's legends internationalization. Thanks to Bojan Mihelac, see #GH-90.
  * Fixed XSS bug thanks to Charlie Denton, see #GH-98. Errors cannot be rendered safe, because field's input can be part of the error message, that would mean XSS.
  * Updating and improving docs, adding more use case examples.
- * Split `helpers.py` file into `helper.py`, `layout.py` and `utils.py`. Added a deprecation warning. 
+ * Split `helpers.py` file into `helper.py`, `layout.py` and `utils.py`. Added a deprecation warning.
  * Improved testing coverage, specially for formsets and i18n.
  * Improved rendering performance of `{% uni_form %}` tag and `|as_uni_form` filter avoiding reloading templates every time, see #GH-81.
  * Added support for Django `Form.error_css_class` and `Form.required_css_class` custom CSS classes, see #GH-87.
- * Moved template code in Layout objects into separate files in `uni_form/layout` directory. Layout objects templates can now be easily overriden, see #GH-37.
+ * Moved template code in Layout objects into separate files in `uni_form/layout` directory. Layout objects templates can now be easily overridden, see #GH-37.
  * `form_style` can now be used without having to set a helper Layout, see #GH-85.
  * `form_action` is not lowered anymore and `form_action` is set to "" by default instead of "." thanks to Jianbo Guo, see #GH-84.
  * `Multifield` field template `multifield.html` markup fixed, adding `help_text` support and removing `labelclass` from labels.
@@ -249,7 +295,7 @@ http://tothinkornottothink.com/post/10398684502/django-uni-form-0-9-0-is-out-sec
  * Improved `MultiField` performance avoiding instantiating BoundFields twice.
  * Fixed a bug in `MultiField` that raised an exception when internal fields had errors, because of `self.css` not existing.
  * Added an extra optional parameter to `render_field` called `layout_object`, used for storing in it a list of bound fields.
- * Refactor all Layout objects to use templates and not having hardcoded HTML in the code, based on Jonas Obrist work. Resolves Issue #GH-37 
+ * Refactor all Layout objects to use templates and not having hardcoded HTML in the code, based on Jonas Obrist work. Resolves Issue #GH-37
  * Added a Layout object called `Div`. `Row` and `Column` both inherit from `Div`
  * `Layout` can now be a child of `Layout`, see issue #GH-76.
 
@@ -278,13 +324,13 @@ http://tothinkornottothink.com/post/7339670508/new-kung-fu-in-django-uni-form-0-
  * Turning `Layout` and `Fieldset` fields attributes into lists, so that they can be changed dynamically.
  * Changing formHints from paragraphs to divs, so ul or ol can be placed within.
  * Removing slugify filter from form ids, so they can be set as user's preferences.
- * Added CSS class 'asteriskField' for asterisks. Added CSS class 'fieldRequired' for required input labels. 
+ * Added CSS class 'asteriskField' for asterisks. Added CSS class 'fieldRequired' for required input labels.
  * `UNIFORM_FAIL_SILENTLY` variable setting has been added for making django-uni-form log errors and fail silently, based on Adam Cupiał's work.
  * Several bug fixes in `MultiField`.
  * Added unicode support for layout field names and improved error handling.
  * Refactored testing system and raised testing coverage.
  * Clean part of the code base and comments. All old CSRF code for supporting old versions of Django has been removed.
- * Refactored BasicNode for better readability and reducing lines of code. 
+ * Refactored BasicNode for better readability and reducing lines of code.
  * Added formsets support based on Victor Nagy's (nagyv) and Antti Kaihola's (akahiola) work.
  * Bug fix in `{% uni_form %}` tag that didn't work without a helper and it was meant to be optional.
  * CSS classes can be set in Submit buttons.
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 31e1f7f..7d2ced0 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -2,10 +2,11 @@
 Contributors
 ============
 
-django-crispy-forms Project Lead
-================================
+django-crispy-forms Project Maintainers
+=======================================
 
 * Miguel Araujo <miguel.araujo.perez at gmail.com>
+* Carlton Gibson <carlton.gibson at noumenal.es>
 
 django-uni-form Project Founder
 ===============================
@@ -85,10 +86,23 @@ Contributors
 * Chris Vigelius <chrisv2>
 * David Cramer <dcramer>
 * Stas Rudakou <nott>
-* <tepez>
+* Tom Yam <tepez>
 * Svyatoslav Bulbakha <ssbb>
 * Andres Vargas <zodman>
 * Gabe Jackson <gabejackson>
 * Camilo Nova <camilonova>
 * <mrkre>
 * Daniel Mascarenhas <danielmt>
+* Paras Kuhad <pkuhad>
+* Kevin Trad <hekevintran>
+* Steven Klass <rh0dium>
+* David Fischer <davidfischer-ch>
+* Stefan Tjarks <stj>
+* Jan Dittberner <jandd>
+* Michael Nielsen <K0den>
+* Stephen Mitchell <scuml>
+* <pySilver>
+* Christopher Adams <adamsc64>
+* John Comeau <jcomeauictx>
+* Yoong Kang Lim <yoongkang>
+* Dmitry Dygalo <Stranger6667>
diff --git a/LICENSE.txt b/LICENSE.txt
index a75b1bf..223cabc 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2009-2011 Miguel Araujo and contributors.
+Copyright (c) 2009-2015 Miguel Araujo and contributors.
 
 Permission is hereby granted, free of charge, to any person
 obtaining a copy of this software and associated documentation
diff --git a/MANIFEST.in b/MANIFEST.in
index ed746e6..eef8ef4 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -4,4 +4,4 @@ include MANIFEST.in
 include README.rst
 recursive-include crispy_forms/static *
 recursive-include crispy_forms/templates *
-recursive-include crispy_forms/tests *
+recursive-include crispy_forms/tests *.py
diff --git a/Makefile b/Makefile
index 101d911..0ab96b5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 .PHONY: develop test
 
 develop:
-	pip install -q "file://`pwd`#egg=django-crispy-forms[tests]"
-	pip install -q -e . --use-mirrors
+	pip install -q -r requirements.txt
+	pip install -q -e .
 
 test: develop
-	cd crispy_forms/tests && python runtests.py
\ No newline at end of file
+	DJANGO_SETTINGS_MODULE=crispy_forms.tests.test_settings py.test crispy_forms/tests --cov=crispy_forms
\ No newline at end of file
diff --git a/README.rst b/README.rst
index f56849c..35e7f6e 100644
--- a/README.rst
+++ b/README.rst
@@ -2,10 +2,13 @@
 django-crispy-forms
 ===================
 
-.. image:: https://travis-ci.org/maraujop/django-crispy-forms.png?branch=master
+.. image:: https://travis-ci.org/maraujop/django-crispy-forms.png?branch=dev
    :alt: Build Status
    :target: https://travis-ci.org/maraujop/django-crispy-forms
 
+.. image:: http://codecov.io/github/maraujop/django-crispy-forms/coverage.svg?branch=master
+   :target: http://codecov.io/github/maraujop/django-crispy-forms?branch=master
+
 The best way to have Django_ DRY forms. Build programmatic reusable layouts out of components, having full control of the rendered HTML without writing HTML in templates. All this without breaking the standard way of doing things in Django, so it plays nice with any other form application.
 
 The application mainly provides:
diff --git a/crispy_forms/__init__.py b/crispy_forms/__init__.py
index 22cc68a..4ffded2 100644
--- a/crispy_forms/__init__.py
+++ b/crispy_forms/__init__.py
@@ -1,3 +1,3 @@
 # -*- coding: utf-8 -*-
 
-__version__ = '1.4.0'
+__version__ = '1.5.2'
diff --git a/crispy_forms/base.py b/crispy_forms/base.py
index ab5c3b5..9d46f94 100644
--- a/crispy_forms/base.py
+++ b/crispy_forms/base.py
@@ -1,42 +1,23 @@
-# -*- coding: utf-8 -*-
-
-
-def from_iterable(iterables):
-    """
-    Backport of `itertools.chain.from_iterable` compatible with Python 2.5
-    """
-    for it in iterables:
-        for element in it:
-            if isinstance(element, dict):
-                for key in element:
-                    yield key
-            else:
-                yield element
 
 
 class KeepContext(object):
     """
-    Context manager that receives a `django.template.Context` instance, tracks its changes
-    and rolls them back when exiting the context manager, leaving the context unchanged.
+    Context manager that receives a `django.template.Context` instance and a list of keys
 
-    Layout objects can introduce context variables, that may cause side effects in later
-    layout objects. This avoids that situation, without copying context every time.
+    Once the context manager is exited, it removes `keys` from the context, to avoid
+    side effects in later layout objects that may use the same context variables.
+
+    Layout objects should use `extra_context` to introduce context variables, never
+    touch context object themselves, that could introduce side effects.
     """
-    def __init__(self, context):
+    def __init__(self, context, keys):
         self.context = context
+        self.keys = keys
 
     def __enter__(self):
-        self.old_set_keys = set(from_iterable(self.context.dicts))
+        pass
 
     def __exit__(self, type, value, traceback):
-        current_set_keys = set(from_iterable(self.context.dicts))
-        diff_keys = current_set_keys - self.old_set_keys
-
-        # We remove added keys for rolling back changes
-        for key in diff_keys:
-            self._delete_key_from_context(key)
-
-    def _delete_key_from_context(self, key):
-        for d in self.context.dicts:
-            if key in d:
-                del d[key]
+        for key in list(self.keys):
+            if key in self.context:
+                del self.context[key]
diff --git a/crispy_forms/bootstrap.py b/crispy_forms/bootstrap.py
index e11046b..a9c9bbd 100644
--- a/crispy_forms/bootstrap.py
+++ b/crispy_forms/bootstrap.py
@@ -1,7 +1,7 @@
-import warnings
+from __future__ import unicode_literals
 from random import randint
 
-from django.template import Context, Template
+from django.template import Template
 from django.template.loader import render_to_string
 from django.template.defaultfilters import slugify
 
@@ -10,9 +10,8 @@ from .layout import LayoutObject, Field, Div
 from .utils import render_field, flatatt, TEMPLATE_PACK
 
 
-
 class PrependedAppendedText(Field):
-    template = "%s/layout/prepended_appended_text.html" % TEMPLATE_PACK
+    template = "%s/layout/prepended_appended_text.html"
 
     def __init__(self, field, prepended_text=None, appended_text=None, *args, **kwargs):
         self.field = field
@@ -23,24 +22,26 @@ class PrependedAppendedText(Field):
 
         self.input_size = None
         css_class = kwargs.get('css_class', '')
-        if css_class.find('input-lg') != -1: self.input_size = 'input-lg'
-        if css_class.find('input-sm') != -1: self.input_size = 'input-sm'
+        if 'input-lg' in css_class:
+            self.input_size = 'input-lg'
+        if 'input-sm' in css_class:
+            self.input_size = 'input-sm'
 
         super(PrependedAppendedText, self).__init__(field, *args, **kwargs)
 
-    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK):
-        context.update({'crispy_appended_text': self.appended_text,
-                        'crispy_prepended_text': self.prepended_text,
-                        'input_size' : self.input_size,
-                        'active': getattr(self, "active", False)})
-        return render_field(self.field, form, form_style, context, template=self.template, attrs=self.attrs, template_pack=template_pack)
-
-
-class AppendedPrependedText(PrependedAppendedText):
-    def __init__(self, *args, **kwargs):
-        warnings.warn("AppendedPrependedText has been renamed to PrependedAppendedText, \
-            it will be removed in 1.3.0", PendingDeprecationWarning)
-        super(AppendedPrependedText, self).__init__(*args, **kwargs)
+    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, extra_context=None, **kwargs):
+        extra_context = {
+            'crispy_appended_text': self.appended_text,
+            'crispy_prepended_text': self.prepended_text,
+            'input_size': self.input_size,
+            'active': getattr(self, "active", False)
+        }
+        template = self.template % template_pack
+        return render_field(
+            self.field, form, form_style, context,
+            template=template, attrs=self.attrs,
+            template_pack=template_pack, extra_context=extra_context, **kwargs
+        )
 
 
 class AppendedText(PrependedAppendedText):
@@ -70,7 +71,7 @@ class FormActions(LayoutObject):
             Submit('Save', 'Save', css_class='btn-primary')
         )
     """
-    template = "%s/layout/formactions.html" % TEMPLATE_PACK
+    template = "%s/layout/formactions.html"
 
     def __init__(self, *fields, **kwargs):
         self.fields = list(fields)
@@ -79,12 +80,14 @@ class FormActions(LayoutObject):
         if 'css_class' in self.attrs:
             self.attrs['class'] = self.attrs.pop('css_class')
 
-    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK):
-        html = u''
-        for field in self.fields:
-            html += render_field(field, form, form_style, context, template_pack=template_pack)
-
-        return render_to_string(self.template, Context({'formactions': self, 'fields_output': html}))
+    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
+        html = self.get_rendered_fields(form, form_style, context, template_pack, **kwargs)
+        extra_context = {
+            'formactions': self,
+            'fields_output': html
+        }
+        template = self.template % template_pack
+        return render_to_string(template, extra_context, context)
 
     def flat_attrs(self):
         return flatatt(self.attrs)
@@ -96,11 +99,13 @@ class InlineCheckboxes(Field):
 
         InlineCheckboxes('field_name')
     """
-    template = "%s/layout/checkboxselectmultiple_inline.html" % TEMPLATE_PACK
+    template = "%s/layout/checkboxselectmultiple_inline.html"
 
-    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK):
-        context.update({'inline_class': 'inline'})
-        return super(InlineCheckboxes, self).render(form, form_style, context)
+    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
+        return super(InlineCheckboxes, self).render(
+            form, form_style, context, template_pack=template_pack,
+            extra_context={'inline_class': 'inline'}
+        )
 
 
 class InlineRadios(Field):
@@ -109,45 +114,55 @@ class InlineRadios(Field):
 
         InlineRadios('field_name')
     """
-    template = "%s/layout/radioselect_inline.html" % TEMPLATE_PACK
+    template = "%s/layout/radioselect_inline.html"
 
-    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK):
-        context.update({'inline_class': 'inline'})
-        return super(InlineRadios, self).render(form, form_style, context)
+    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
+        return super(InlineRadios, self).render(
+            form, form_style, context, template_pack=template_pack,
+            extra_context={'inline_class': 'inline'}
+        )
 
 
 class FieldWithButtons(Div):
-    template = '%s/layout/field_with_buttons.html' % TEMPLATE_PACK
+    template = '%s/layout/field_with_buttons.html'
+    field_template = '%s/layout/field.html'
 
-    def render(self, form, form_style, context):
+    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, extra_context=None, **kwargs):
         # We first render the buttons
-        buttons = ''
-        for field in self.fields[1:]:
-            buttons += render_field(
+        field_template = self.field_template % template_pack
+        buttons = ''.join(
+            render_field(
                 field, form, form_style, context,
-                '%s/layout/field.html' % TEMPLATE_PACK, layout_object=self
-            )
+                field_template, layout_object=self,
+                template_pack=template_pack, **kwargs
+            ) for field in self.fields[1:]
+        )
 
-        context.update({'div': self, 'buttons': buttons})
+        extra_context = {'div': self, 'buttons': buttons}
+        template = self.template % template_pack
 
         if isinstance(self.fields[0], Field):
             # FieldWithButtons(Field('field_name'), StrictButton("go"))
             # We render the field passing its name and attributes
             return render_field(
                 self.fields[0][0], form, form_style, context,
-                self.template, attrs=self.fields[0].attrs
+                template, attrs=self.fields[0].attrs,
+                template_pack=template_pack, extra_context=extra_context, **kwargs
             )
         else:
-            return render_field(self.fields[0], form, form_style, context, self.template)
+            return render_field(
+                self.fields[0], form, form_style, context, template,
+                extra_context=extra_context, **kwargs
+            )
 
 
 class StrictButton(object):
     """
-    Layout oject for rendering an HTML button::
+    Layout object for rendering an HTML button::
 
         Button("button content", css_class="extra")
     """
-    template = '%s/layout/button.html' % TEMPLATE_PACK
+    template = '%s/layout/button.html'
     field_classes = 'btn'
 
     def __init__(self, content, **kwargs):
@@ -165,9 +180,10 @@ class StrictButton(object):
 
         self.flat_attrs = flatatt(kwargs)
 
-    def render(self, form, form_style, context):
+    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
         self.content = Template(text_type(self.content)).render(context)
-        return render_to_string(self.template, Context({'button': self}))
+        template = self.template % template_pack
+        return render_to_string(template, {'button': self}, context)
 
 
 class Container(Div):
@@ -180,6 +196,7 @@ class Container(Div):
         super(Container, self).__init__(*fields, **kwargs)
         self.template = kwargs.pop('template', self.template)
         self.name = name
+        self._active_originally_included = "active" in kwargs
         self.active = kwargs.pop("active", False)
         if not self.css_id:
             self.css_id = slugify(self.name)
@@ -190,13 +207,13 @@ class Container(Div):
         """
         return field_name in map(lambda pointer: pointer[1], self.get_field_names())
 
-    def render(self, form, form_style, context):
+    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
         if self.active:
             if not 'active' in self.css_class:
                 self.css_class += ' active'
         else:
             self.css_class = self.css_class.replace('active', '')
-        return super(Container, self).render(form, form_style, context)
+        return super(Container, self).render(form, form_style, context, template_pack)
 
 
 class ContainerHolder(Div):
@@ -205,14 +222,30 @@ class ContainerHolder(Div):
     """
     def first_container_with_errors(self, errors):
         """
-        Returns the first container with errors, otherwise returns the first one
+        Returns the first container with errors, otherwise returns None.
         """
         for tab in self.fields:
             errors_here = any(error in tab for error in errors)
             if errors_here:
                 return tab
+        return None
 
-        return self.fields[0]
+    def open_target_group_for_form(self, form):
+        """
+        Makes sure that the first group that should be open is open.
+        This is either the first group with errors or the first group
+        in the container, unless that first group was originally set to
+        active=False.
+        """
+        target = self.first_container_with_errors(form.errors.keys())
+        if target is None:
+            target = self.fields[0]
+            if not target._active_originally_included:
+                target.active = True
+            return target
+
+        target.active = True
+        return target
 
 
 class Tab(Container):
@@ -223,14 +256,15 @@ class Tab(Container):
         Tab('tab_name', 'form_field_1', 'form_field_2', 'form_field_3')
     """
     css_class = 'tab-pane'
-    link_template = '%s/layout/tab-link.html' % TEMPLATE_PACK
+    link_template = '%s/layout/tab-link.html'
 
-    def render_link(self):
+    def render_link(self, template_pack=TEMPLATE_PACK, **kwargs):
         """
         Render the link for the tab-pane. It must be called after render so css_class is updated
         with active if needed.
         """
-        return render_to_string(self.link_template, Context({'link': self}))
+        link_template = self.link_template % template_pack
+        return render_to_string(link_template, {'link': self})
 
 
 class TabHolder(ContainerHolder):
@@ -242,25 +276,24 @@ class TabHolder(ContainerHolder):
             Tab('form_field_3')
         )
     """
-    template = '%s/layout/tab.html' % TEMPLATE_PACK
+    template = '%s/layout/tab.html'
 
-    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK):
-        links, content = '', ''
+    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
         for tab in self.fields:
             tab.active = False
 
-        # The first tab with errors will be active
-        self.first_container_with_errors(form.errors.keys()).active = True
+        # Open the group that should be open.
+        self.open_target_group_for_form(form)
+        content = self.get_rendered_fields(form, form_style, context, template_pack)
+        links = ''.join(tab.render_link(template_pack) for tab in self.fields)
 
-        for tab in self.fields:
-            content += render_field(
-                tab, form, form_style, context, template_pack=template_pack
-            )
-            links += tab.render_link()
-
-        return render_to_string(self.template, Context({
-            'tabs': self, 'links': links, 'content': content
-        }))
+        extra_context = {
+            'tabs': self,
+            'links': links,
+            'content': content
+        }
+        template = self.template % template_pack
+        return render_to_string(template, extra_context, context)
 
 
 class AccordionGroup(Container):
@@ -270,7 +303,7 @@ class AccordionGroup(Container):
 
         AccordionGroup("group name", "form_field_1", "form_field_2")
     """
-    template = "%s/accordion-group.html" % TEMPLATE_PACK
+    template = "%s/accordion-group.html"
     data_parent = ""  # accordion parent div id.
 
 
@@ -283,9 +316,9 @@ class Accordion(ContainerHolder):
             AccordionGroup("another group name", "form_field")
         )
     """
-    template = "%s/accordion.html" % TEMPLATE_PACK
+    template = "%s/accordion.html"
 
-    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK):
+    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
         content = ''
 
         # accordion group needs the parent div id to set `data-parent` (I don't
@@ -293,18 +326,20 @@ class Accordion(ContainerHolder):
         if not self.css_id:
             self.css_id = "-".join(["accordion", text_type(randint(1000, 9999))])
 
-        # first group with errors or first groupt will be visible, others will be collapsed
-        self.first_container_with_errors(form.errors.keys()).active = True
+        # Open the group that should be open.
+        self.open_target_group_for_form(form)
 
         for group in self.fields:
             group.data_parent = self.css_id
             content += render_field(
-                group, form, form_style, context, template_pack=template_pack
+                group, form, form_style, context, template_pack=template_pack, **kwargs
             )
 
+        template = self.template % template_pack
         return render_to_string(
-            self.template,
-            Context({'accordion': self, 'content': content})
+            template,
+            {'accordion': self, 'content': content},
+            context
         )
 
 
@@ -314,7 +349,7 @@ class Alert(Div):
 
         Alert(content='<strong>Warning!</strong> Best check yo self, you're not looking too good.')
     """
-    template = "bootstrap/layout/alert.html"
+    template = "%s/layout/alert.html"
     css_class = "alert"
 
     def __init__(self, content, dismiss=True, block=False, **kwargs):
@@ -326,11 +361,13 @@ class Alert(Div):
         self.content = content
         self.dismiss = dismiss
 
-    def render(self, form, form_style, context):
+    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
+        template = self.template % template_pack
         return render_to_string(
-            self.template,
-            Context({'alert': self, 'content': self.content, 'dismiss': self.dismiss
-        }))
+            template,
+            {'alert': self, 'content': self.content, 'dismiss': self.dismiss},
+            context
+        )
 
 
 class UneditableField(Field):
@@ -341,7 +378,7 @@ class UneditableField(Field):
 
         UneditableField('field_name', css_class="input-xlarge")
     """
-    template = "%s/layout/uneditable_input.html" % TEMPLATE_PACK
+    template = "%s/layout/uneditable_input.html"
 
     def __init__(self, field, *args, **kwargs):
         self.attrs = {'class': 'uneditable-input'}
@@ -349,4 +386,4 @@ class UneditableField(Field):
 
 
 class InlineField(Field):
-    template = "%s/layout/inline_field.html" % TEMPLATE_PACK
+    template = "%s/layout/inline_field.html"
diff --git a/crispy_forms/compatibility.py b/crispy_forms/compatibility.py
index 96ab5ba..6a5cc3d 100644
--- a/crispy_forms/compatibility.py
+++ b/crispy_forms/compatibility.py
@@ -1,5 +1,23 @@
 import sys
 
+import django
+
+if (1, 4) <= django.VERSION <= (1, 5):
+    from django.utils.functional import SimpleLazyObject as DefaultSimpleLazyObject
+
+    class SimpleLazyObject(DefaultSimpleLazyObject):
+
+        def __contains__(self, item):
+            if self._wrapped is None:
+                self._setup()
+            return self._wrapped.__contains__(item)
+else:
+    from django.utils.functional import SimpleLazyObject
+
+try:
+    basestring
+except:
+    basestring = str  # Python3
 
 PY2 = sys.version_info[0] == 2
 if not PY2:
@@ -12,3 +30,18 @@ else:
     binary_type = str
     string_types = basestring
     integer_types = (int, long)
+
+try:
+    # avoid RemovedInDjango19Warning by using lru_cache where available
+    from django.utils.lru_cache import lru_cache
+except ImportError:
+    from django.utils.functional import memoize
+
+    def lru_cache():
+
+        def decorator(function, cache_dict=None):
+            if cache_dict is None:
+                cache_dict = {}
+            return memoize(function, cache_dict, 1)
+
+        return decorator
diff --git a/crispy_forms/helper.py b/crispy_forms/helper.py
index 0217788..c4bb468 100644
--- a/crispy_forms/helper.py
+++ b/crispy_forms/helper.py
@@ -202,7 +202,6 @@ class FormHelper(DynamicLayoutHandler):
     field_template = None
     disable_csrf = False
     label_class = ''
-    label_size = ''
     field_class = ''
 
     def __init__(self, form=None):
@@ -216,65 +215,63 @@ class FormHelper(DynamicLayoutHandler):
     def build_default_layout(self, form):
         return Layout(*form.fields.keys())
 
-    def get_form_method(self):
+    @property
+    def form_method(self):
         return self._form_method
 
-    def set_form_method(self, method):
+    @form_method.setter
+    def form_method(self, method):
         if method.lower() not in ('get', 'post'):
... 6696 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-django-crispy-forms.git



More information about the Python-modules-commits mailing list