[Python-modules-commits] [python-django-treebeard] 05/17: Import python-django-treebeard_4.0+dfsg.orig.tar.gz

Michael Fladischer fladi at moszumanska.debian.org
Sat Jan 2 18:39:22 UTC 2016


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

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

commit 02d1914271cd7f1807f85bfc1db0632cc5fe3133
Author: Michael Fladischer <fladi at debian.org>
Date:   Wed Dec 30 20:33:43 2015 +0100

    Import python-django-treebeard_4.0+dfsg.orig.tar.gz
---
 CHANGES                                          | 10 +++
 PKG-INFO                                         |  5 +-
 django_treebeard.egg-info/PKG-INFO               |  5 +-
 django_treebeard.egg-info/requires.txt           |  2 +-
 docs/_ext/djangodocs.py                          | 10 ---
 docs/conf.py                                     |  8 +--
 docs/index.rst                                   |  2 +-
 docs/install.rst                                 |  2 +-
 docs/mp_tree.rst                                 |  2 +-
 setup.py                                         |  7 ++-
 treebeard/mp_tree.py                             |  4 +-
 treebeard/ns_tree.py                             |  7 ++-
 treebeard/templatetags/__init__.py               | 41 +-----------
 treebeard/templatetags/admin_tree.py             | 80 +++++++++++++++---------
 treebeard/templatetags/admin_tree_list.py        | 28 +++++----
 treebeard/tests/conftest.py                      | 19 ------
 treebeard/tests/jenkins/rm_workspace_coverage.py |  5 +-
 treebeard/tests/jenkins/toxhelper.py             |  4 ++
 treebeard/tests/settings.py                      | 15 ++++-
 treebeard/tests/test_treebeard.py                | 37 ++++++++---
 20 files changed, 148 insertions(+), 145 deletions(-)

diff --git a/CHANGES b/CHANGES
index 280c9ad..718cb0c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,13 @@
+Release 4.0 (Dec 28, 2015)
+--------------------------
+
+* Added support for 3.5 and Django 1.7, 1.8 and 1.9
+* Django 1.6 is no longer supported.
+* Remove deprecated backports needed for now unsupported Django versions
+* Fixed a bug with queryset deletion not handling inheritance correctly.
+* Assorted documentation fixes
+
+
 Release 3.0 (Jan 18, 2015)
 --------------------------
 
diff --git a/PKG-INFO b/PKG-INFO
index d75b590..1409f51 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,7 +1,7 @@
 Metadata-Version: 1.1
 Name: django-treebeard
-Version: 3.0
-Summary: Efficient tree implementations for Django 1.6+
+Version: 4.0
+Summary: Efficient tree implementations for Django 1.7+
 Home-page: https://tabo.pe/projects/django-treebeard/
 Author: Gustavo Picon
 Author-email: tabo at tabo.pe
@@ -45,6 +45,7 @@ Classifier: Framework :: Django
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
 Classifier: Operating System :: OS Independent
 Classifier: Topic :: Software Development :: Libraries
 Classifier: Topic :: Utilities
diff --git a/django_treebeard.egg-info/PKG-INFO b/django_treebeard.egg-info/PKG-INFO
index d75b590..1409f51 100644
--- a/django_treebeard.egg-info/PKG-INFO
+++ b/django_treebeard.egg-info/PKG-INFO
@@ -1,7 +1,7 @@
 Metadata-Version: 1.1
 Name: django-treebeard
-Version: 3.0
-Summary: Efficient tree implementations for Django 1.6+
+Version: 4.0
+Summary: Efficient tree implementations for Django 1.7+
 Home-page: https://tabo.pe/projects/django-treebeard/
 Author: Gustavo Picon
 Author-email: tabo at tabo.pe
@@ -45,6 +45,7 @@ Classifier: Framework :: Django
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
 Classifier: Operating System :: OS Independent
 Classifier: Topic :: Software Development :: Libraries
 Classifier: Topic :: Utilities
diff --git a/django_treebeard.egg-info/requires.txt b/django_treebeard.egg-info/requires.txt
index d08919c..e38f742 100644
--- a/django_treebeard.egg-info/requires.txt
+++ b/django_treebeard.egg-info/requires.txt
@@ -1 +1 @@
-Django>=1.6
+Django>=1.7
diff --git a/docs/_ext/djangodocs.py b/docs/_ext/djangodocs.py
deleted file mode 100644
index 3b59f3c..0000000
--- a/docs/_ext/djangodocs.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# taken from:
-# http://reinout.vanrees.org/weblog/2012/12/01/django-intersphinx.html
-
-
-def setup(app):
-    app.add_crossref_type(
-        directivename="setting",
-        rolename="setting",
-        indextemplate="pair: %s; setting",
-    )
diff --git a/docs/conf.py b/docs/conf.py
index eb2a7b6..689155d 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -37,8 +37,8 @@ source_suffix = '.rst'
 master_doc = 'index'
 project = 'django-treebeard'
 copyright = '2008-2015, Gustavo Picon'
-version = '3.0'
-release = '3.0'
+version = '4.0'
+release = '4.0'
 exclude_trees = ['_build']
 pygments_style = 'sphinx'
 html_theme = 'default'
@@ -53,7 +53,7 @@ latex_documents = [(
 intersphinx_mapping = {
     'python': ('http://docs.python.org/3', None),
     'django': (
-        'https://docs.djangoproject.com/en/1.6/',
-        'https://docs.djangoproject.com/en/1.6/_objects/'
+        'https://docs.djangoproject.com/en/1.7/',
+        'https://docs.djangoproject.com/en/1.7/_objects/'
     ),
 }
diff --git a/docs/index.rst b/docs/index.rst
index 1da346b..82deb4a 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -3,7 +3,7 @@ django-treebeard
 
 `django-treebeard <https://tabo.pe/projects/django-treebeard/>`_
 is a library that implements efficient tree implementations for the
-`Django Web Framework 1.6+ <http://www.djangoproject.com/>`_, written by
+`Django Web Framework 1.7+ <http://www.djangoproject.com/>`_, written by
 `Gustavo Picón <https://tabo.pe>`_ and licensed under the Apache License 2.0.
 
 ``django-treebeard`` is:
diff --git a/docs/install.rst b/docs/install.rst
index ac2d1ab..3e10b9b 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -6,7 +6,7 @@ Prerequisites
 -------------
 
 ``django-treebeard`` needs at least **Python 2.7/3.4** to run, and
-**Django 1.6 or better**.
+**Django 1.7 or better**.
 
 
 Installing
diff --git a/docs/mp_tree.rst b/docs/mp_tree.rst
index 3e530e7..5c186db 100644
--- a/docs/mp_tree.rst
+++ b/docs/mp_tree.rst
@@ -125,7 +125,7 @@ extra steps, materialized path is more efficient than other approaches.
          ================ ================ ====
 
         The default value is MySQL's since it will work in all DBs,
-        but when working with a better databse, changing the
+        but when working with a better database, changing the
         :attr:`alphabet` value is recommended in order to increase the
         density of the paths.
 
diff --git a/setup.py b/setup.py
index f7a7b78..808a2b7 100644
--- a/setup.py
+++ b/setup.py
@@ -26,7 +26,7 @@ class pytest_test(test):
 
 setup_args = dict(
     name='django-treebeard',
-    version='3.0',
+    version='4.0',
     url='https://tabo.pe/projects/django-treebeard/',
     author='Gustavo Picon',
     author_email='tabo at tabo.pe',
@@ -35,10 +35,10 @@ setup_args = dict(
     package_dir={'treebeard': 'treebeard'},
     package_data={
         'treebeard': ['templates/admin/*.html', 'static/treebeard/*']},
-    description='Efficient tree implementations for Django 1.6+',
+    description='Efficient tree implementations for Django 1.7+',
     long_description=codecs.open(root_dir() + '/README.rst', encoding='utf-8').read(),
     cmdclass={'test': pytest_test},
-    install_requires=['Django>=1.6'],
+    install_requires=['Django>=1.7'],
     tests_require=['pytest'],
     classifiers=[
         'Development Status :: 5 - Production/Stable',
@@ -49,6 +49,7 @@ setup_args = dict(
         'Programming Language :: Python',
         'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3.4',
+        'Programming Language :: Python :: 3.5',
         'Operating System :: OS Independent',
         'Topic :: Software Development :: Libraries',
         'Topic :: Utilities'])
diff --git a/treebeard/mp_tree.py b/treebeard/mp_tree.py
index c070d8b..d175678 100644
--- a/treebeard/mp_tree.py
+++ b/treebeard/mp_tree.py
@@ -94,7 +94,7 @@ class MP_NodeQuerySet(models.query.QuerySet):
         # Django will handle this as a SELECT and then a DELETE of
         # ids, and will deal with removing related objects
         if toremove:
-            qset = self.model.objects.filter(reduce(operator.or_, toremove))
+            qset = get_result_class(self.model).objects.filter(reduce(operator.or_, toremove))
             super(MP_NodeQuerySet, qset).delete()
 
 
@@ -713,7 +713,7 @@ class MP_Node(Node):
         :param destructive:
 
             A boolean value. If True, a more agressive fix_tree method will be
-            attemped. If False (the default), it will use a safe (and fast!)
+            attempted. If False (the default), it will use a safe (and fast!)
             fix approach, but it will only solve the ``depth`` and
             ``numchild`` nodes, it won't fix the tree holes or broken path
             ordering.
diff --git a/treebeard/ns_tree.py b/treebeard/ns_tree.py
index 3f5073b..9cdc4b3 100644
--- a/treebeard/ns_tree.py
+++ b/treebeard/ns_tree.py
@@ -53,12 +53,13 @@ class NS_NodeQuerySet(models.query.QuerySet):
 
         :returns: ``None``
         """
+        model = get_result_class(self.model)
         if removed_ranges is not None:
             # we already know the children, let's call the default django
             # delete method and let it handle the removal of the user's
             # foreign keys...
             super(NS_NodeQuerySet, self).delete()
-            cursor = self.model._get_database_cursor('write')
+            cursor = model._get_database_cursor('write')
 
             # Now closing the gap (Celko's trees book, page 62)
             # We do this for every gap that was left in the tree when the nodes
@@ -68,7 +69,7 @@ class NS_NodeQuerySet(models.query.QuerySet):
             # complete reordering of the tree (uses COUNT)...
             for tree_id, drop_lft, drop_rgt in sorted(removed_ranges,
                                                       reverse=True):
-                sql, params = self.model._get_close_gap_sql(drop_lft, drop_rgt,
+                sql, params = model._get_close_gap_sql(drop_lft, drop_rgt,
                                                             tree_id)
                 cursor.execute(sql, params)
         else:
@@ -94,7 +95,7 @@ class NS_NodeQuerySet(models.query.QuerySet):
                                 Q(tree_id=node.tree_id))
                 ranges.append((node.tree_id, node.lft, node.rgt))
             if toremove:
-                self.model.objects.filter(
+                model.objects.filter(
                     reduce(operator.or_,
                            toremove)
                 ).delete(removed_ranges=ranges)
diff --git a/treebeard/templatetags/__init__.py b/treebeard/templatetags/__init__.py
index b67c2a4..450fe44 100644
--- a/treebeard/templatetags/__init__.py
+++ b/treebeard/templatetags/__init__.py
@@ -1,11 +1,5 @@
-import datetime
-import decimal
-
 from django.template import Variable, VariableDoesNotExist
-from django.utils import formats, timezone, six
-from django.utils.encoding import smart_text
-from django.utils.html import conditional_escape
-from django.utils.safestring import mark_safe
+
 
 action_form_var = Variable('action_form')
 
@@ -16,36 +10,3 @@ def needs_checkboxes(context):
     except VariableDoesNotExist:
         return False
 
-
-def display_for_value(value, boolean=False):  # pragma: no cover
-    """ Added for compatibility with django 1.4, copied from django trunk.
-    """
-    from django.contrib.admin.templatetags.admin_list import _boolean_icon
-    from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
-
-    if boolean:
-        return _boolean_icon(value)
-    elif value is None:
-        return EMPTY_CHANGELIST_VALUE
-    elif isinstance(value, datetime.datetime):
-        return formats.localize(timezone.template_localtime(value))
-    elif isinstance(value, (datetime.date, datetime.time)):
-        return formats.localize(value)
-    elif isinstance(value, six.integer_types + (decimal.Decimal, float)):
-        return formats.number_format(value)
-    else:
-        return smart_text(value)
-
-
-def format_html(format_string, *args, **kwargs):  # pragma: no cover
-    """
-    Added for compatibility with django 1.4, copied from django trunk.
-
-    Similar to str.format, but passes all arguments through conditional_escape,
-    and calls 'mark_safe' on the result. This function should be used instead
-    of str.format or % interpolation to build up small HTML fragments.
-    """
-    args_safe = map(conditional_escape, args)
-    kwargs_safe = dict([(k, conditional_escape(v)) for (k, v) in
-                        six.iteritems(kwargs)])
-    return mark_safe(format_string.format(*args_safe, **kwargs_safe))
diff --git a/treebeard/templatetags/admin_tree.py b/treebeard/templatetags/admin_tree.py
index eee38b7..9794ac6 100644
--- a/treebeard/templatetags/admin_tree.py
+++ b/treebeard/templatetags/admin_tree.py
@@ -8,12 +8,17 @@ nodes change list - @jjdelc
 import datetime
 import sys
 
+import django
 from django.db import models
 from django.conf import settings
 from django.contrib.admin.templatetags.admin_list import (
     result_headers, result_hidden_fields)
-from django.contrib.admin.util import lookup_field, display_for_field
-from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
+try:
+    from django.contrib.admin.utils import (
+        lookup_field, display_for_field, display_for_value)
+except ImportError:  # < Django 1.8
+    from django.contrib.admin.util import (
+        lookup_field, display_for_field, display_for_value)
 from django.core.exceptions import ObjectDoesNotExist
 from django.template import Library
 from django.utils.html import conditional_escape
@@ -40,50 +45,62 @@ else:
     from urlparse import urljoin
 
 
-try:
-    from django.contrib.admin.util import display_for_value
-    from django.utils.html import format_html
-except ImportError:
-    from treebeard.templatetags import display_for_value, format_html
+from django.utils.html import format_html
 
 from treebeard.templatetags import needs_checkboxes
 
 
 def get_result_and_row_class(cl, field_name, result):
-    row_class = ''
+    if django.VERSION >= (1, 9):
+        empty_value_display = cl.model_admin.get_empty_value_display()
+    else:
+        from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
+        empty_value_display = EMPTY_CHANGELIST_VALUE
+    row_classes = ['field-%s' % field_name]
     try:
         f, attr, value = lookup_field(field_name, result, cl.model_admin)
     except ObjectDoesNotExist:
-        result_repr = EMPTY_CHANGELIST_VALUE
+        result_repr = empty_value_display
     else:
+        if django.VERSION >= (1, 9):
+            empty_value_display = getattr(
+                attr, 'empty_value_display', empty_value_display)
         if f is None:
             if field_name == 'action_checkbox':
-                row_class = mark_safe(' class="action-checkbox"')
+                row_classes = ['action-checkbox']
             allow_tags = getattr(attr, 'allow_tags', False)
             boolean = getattr(attr, 'boolean', False)
-            if boolean:
-                allow_tags = True
-            result_repr = display_for_value(value, boolean)
+            if django.VERSION >= (1, 9):
+                result_repr = display_for_value(
+                    value, empty_value_display, boolean)
+            else:
+                result_repr = display_for_value(value, boolean)
             # Strip HTML tags in the resulting text, except if the
             # function has an "allow_tags" attribute set to True.
+            # WARNING: this will be deprecated in Django 2.0
             if allow_tags:
                 result_repr = mark_safe(result_repr)
             if isinstance(value, (datetime.date, datetime.time)):
-                row_class = mark_safe(' class="nowrap"')
+                row_classes.append('nowrap')
         else:
             if isinstance(f.rel, models.ManyToOneRel):
                 field_val = getattr(result, f.name)
                 if field_val is None:
-                    result_repr = EMPTY_CHANGELIST_VALUE
+                    result_repr = empty_value_display
                 else:
                     result_repr = field_val
             else:
-                result_repr = display_for_field(value, f)
+                if django.VERSION >= (1, 9):
+                    result_repr = display_for_field(
+                        value, f, empty_value_display)
+                else:
+                    result_repr = display_for_field(value, f)
             if isinstance(f, (models.DateField, models.TimeField,
                               models.ForeignKey)):
-                row_class = mark_safe(' class="nowrap"')
+                row_classes.append('nowrap')
         if force_str(result_repr) == '':
             result_repr = mark_safe(' ')
+        row_class = mark_safe(' class="%s"' % ' '.join(row_classes))
     return result_repr, row_class
 
 
@@ -254,9 +271,11 @@ def treebeard_css():
     """
     Template tag to print out the proper <link/> tag to include a custom .css
     """
-    LINK_HTML = """<link rel="stylesheet" type="text/css" href="%s"/>"""
     css_file = urljoin(get_static_url(), 'treebeard/treebeard-admin.css')
-    return LINK_HTML % css_file
+    return format_html(
+        """<link rel="stylesheet" type="text/css" href="{}"/>""",
+        mark_safe(css_file)
+    )
 
 
 @register.simple_tag
@@ -265,19 +284,18 @@ def treebeard_js():
     Template tag to print out the proper <script/> tag to include a custom .js
     """
     path = get_static_url()
-    SCRIPT_HTML = """<script type="text/javascript" src="%s"></script>"""
-    js_file = '/'.join([path.rstrip('/'), 'treebeard', 'treebeard-admin.js'])
+    js_file = urljoin(path, 'treebeard/treebeard-admin.js')
+    jquery_ui = urljoin(path, 'treebeard/jquery-ui-1.8.5.custom.min.js')
 
     # Jquery UI is needed to call disableSelection() on drag and drop so
     # text selections arent marked while dragging a table row
     # http://www.lokkju.com/blog/archives/143
-    JQUERY_UI = ("<script>"
-                 "(function($){jQuery = $.noConflict(true);})(django.jQuery);"
-                 "</script>"
-                 "<script type=\"text/javascript\" src=\"%s\"></script>")
-    jquery_ui = urljoin(path, 'treebeard/jquery-ui-1.8.5.custom.min.js')
-
-    scripts = [SCRIPT_HTML % 'jsi18n',
-               SCRIPT_HTML % js_file,
-               JQUERY_UI % jquery_ui]
-    return ''.join(scripts)
+    TEMPLATE = (
+        '<script type="text/javascript" src="{}"></script>'
+        '<script type="text/javascript" src="{}"></script>'
+        '<script>'
+            '(function($){{jQuery = $.noConflict(true);}})(django.jQuery);'
+        '</script>'
+        '<script type="text/javascript" src="{}"></script>')
+    return format_html(
+        TEMPLATE, "jsi18n", mark_safe(js_file), mark_safe(jquery_ui))
diff --git a/treebeard/templatetags/admin_tree_list.py b/treebeard/templatetags/admin_tree_list.py
index ae2cd3e..156d9da 100644
--- a/treebeard/templatetags/admin_tree_list.py
+++ b/treebeard/templatetags/admin_tree_list.py
@@ -1,35 +1,40 @@
 # -*- coding: utf-8 -*-
 
 from django.template import Library
+from django.utils.html import format_html
+from django.utils.safestring import mark_safe
 from treebeard.templatetags import needs_checkboxes
 from treebeard.admin import TO_FIELD_VAR
 
 
 register = Library()
-CHECKBOX_TMPL = ('<input type="checkbox" class="action-select" value="%d" '
+CHECKBOX_TMPL = ('<input type="checkbox" class="action-select" value="{}" '
                  'name="_selected_action" />')
 
 
 def _line(context, node, request):
     if TO_FIELD_VAR in request.GET and request.GET[TO_FIELD_VAR] == 'id':
-        raw_id_fields = """
-        onclick="opener.dismissRelatedLookupPopup(window, '%d'); return false;"
-        """ % (node.pk,)
+        raw_id_fields = format_html("""
+        onclick="opener.dismissRelatedLookupPopup(window, '{}'); return false;"
+        """, mark_safe(node.pk))
     else:
         raw_id_fields = ''
     output = ''
     if needs_checkboxes(context):
-        output += CHECKBOX_TMPL % node.pk
-    return output + '<a href="%d/" %s>%s</a>' % (
-        node.pk, raw_id_fields, str(node))
+        output += format_html(CHECKBOX_TMPL, mark_safe(node.pk))
+    return output + format_html(
+        '<a href="{}/" {}>{}</a>',
+        mark_safe(node.pk), mark_safe(raw_id_fields), mark_safe(str(node)))
 
 
 def _subtree(context, node, request):
     tree = ''
     for subnode in node.get_children():
-        tree += '<li>%s</li>' % _subtree(context, subnode, request)
+        tree += format_html(
+            '<li>{}</li>',
+            mark_safe(_subtree(context, subnode, request)))
     if tree:
-        tree = '<ul>%s</ul>' % tree
+        tree = format_html('<ul>{}</ul>', mark_safe(tree))
     return _line(context, node, request) + tree
 
 
@@ -37,5 +42,6 @@ def _subtree(context, node, request):
 def result_tree(context, cl, request):
     tree = ''
     for root_node in cl.model.get_root_nodes():
-        tree += '<li>%s</li>' % _subtree(context, root_node, request)
-    return "<ul>%s</ul>" % tree
+        tree += format_html(
+            '<li>{}</li>', mark_safe(_subtree(context, root_node, request)))
+    return format_html("<ul>{}</ul>", mark_safe(tree))
diff --git a/treebeard/tests/conftest.py b/treebeard/tests/conftest.py
index 073a9cc..d6f2876 100644
--- a/treebeard/tests/conftest.py
+++ b/treebeard/tests/conftest.py
@@ -13,25 +13,6 @@ from django.test.client import Client
 from django.core.management import call_command
 from django.core import mail
 from django.db import connection
-from django.db.models.base import ModelBase
-from _pytest import python as _pytest_python
-
-
-def idmaker(argnames, argvalues):
-    idlist = []
-    for valindex, valset in enumerate(argvalues):
-        this_id = []
-        for nameindex, val in enumerate(valset):
-            argname = argnames[nameindex]
-            if isinstance(val, (float, int, str)):
-                this_id.append(str(val))
-            elif isinstance(val, ModelBase):
-                this_id.append(val.__name__)
-            else:
-                this_id.append("{0}-{1}={2!s}".format(argname, valindex))
-        idlist.append("][".join(this_id))
-    return idlist
-_pytest_python.idmaker = idmaker
 
 
 def pytest_report_header(config):
diff --git a/treebeard/tests/jenkins/rm_workspace_coverage.py b/treebeard/tests/jenkins/rm_workspace_coverage.py
index d56bb05..bcb13e2 100644
--- a/treebeard/tests/jenkins/rm_workspace_coverage.py
+++ b/treebeard/tests/jenkins/rm_workspace_coverage.py
@@ -6,12 +6,13 @@ In Python because of portability with Windows.
 import sys
 
 import os
+import os.path
 
 
 def main():
     workspace = os.environ['WORKSPACE']
-    for filename in os.listdir(workspace):
-        if filename.startswith('.coverage.'):
+    for filename in os.listdir(os.path.join(workspace, ".tests")):
+        if filename.startswith('coverage.'):
             file_full_name = os.path.join(workspace, filename)
             sys.stdout.write(
                 '* Removing old .coverage file: `%s`\n' % file_full_name)
diff --git a/treebeard/tests/jenkins/toxhelper.py b/treebeard/tests/jenkins/toxhelper.py
index b0a1704..402f595 100644
--- a/treebeard/tests/jenkins/toxhelper.py
+++ b/treebeard/tests/jenkins/toxhelper.py
@@ -10,12 +10,16 @@ See https://tabo.pe/jenkins/ for the results.
 import sys
 
 import os
+import os.path
 import pytest
 
 from coverage import coverage
 
 
 def run_the_tests():
+    tests_dir = os.path.join(os.path.dirname(__file__), "../../../.tests")
+    if not os.path.isdir(tests_dir):
+        os.mkdir(tests_dir)
     if 'TOX_DB' in os.environ:
         os.environ['DATABASE_HOST'], os.environ['DATABASE_PORT'] = {
             'pgsql': ('dummy_test_database_server', '5434'),
diff --git a/treebeard/tests/settings.py b/treebeard/tests/settings.py
index e691ace..5a029bf 100644
--- a/treebeard/tests/settings.py
+++ b/treebeard/tests/settings.py
@@ -42,8 +42,7 @@ def get_db_conf():
             }[engine]
         if engine == 'django.db.backends.mysql':
             conf['OPTIONS'] = {
-                'init_command': 'SET storage_engine=INNODB,'
-                                'character_set_connection=utf8,'
+                'init_command': 'SET character_set_connection=utf8,'
                                 'collation_connection=utf8_unicode_ci'}
     set_test_db_name(conf, test_name)
     return conf
@@ -62,6 +61,18 @@ def set_test_db_name(conf, test_name):
 DATABASES = {'default': get_db_conf()}
 SECRET_KEY = '7r33b34rd'
 
+
+class DisableMigrations(object):
+
+    def __contains__(self, item):
+        return True
+
+    def __getitem__(self, item):
+        return "notmigrations"
+
+
+MIGRATION_MODULES = DisableMigrations()
+
 INSTALLED_APPS = [
     'django.contrib.auth',
     'django.contrib.contenttypes',
diff --git a/treebeard/tests/test_treebeard.py b/treebeard/tests/test_treebeard.py
index e0bf0d9..65c9bb5 100644
--- a/treebeard/tests/test_treebeard.py
+++ b/treebeard/tests/test_treebeard.py
@@ -62,53 +62,57 @@ def _prepare_db_test(request):
     return request.param
 
 
+def idfn(fixture_value):
+    return fixture_value.__name__
+
 @pytest.fixture(scope='function',
-                params=models.BASE_MODELS + models.PROXY_MODELS)
+                params=models.BASE_MODELS + models.PROXY_MODELS,
+                ids=idfn)
 def model(request):
     return _prepare_db_test(request)
 
 
- at pytest.fixture(scope='function', params=models.BASE_MODELS)
+ at pytest.fixture(scope='function', params=models.BASE_MODELS, ids=idfn)
 def model_without_proxy(request):
     return _prepare_db_test(request)
 
 
- at pytest.fixture(scope='function', params=models.UNICODE_MODELS)
+ at pytest.fixture(scope='function', params=models.UNICODE_MODELS, ids=idfn)
 def model_with_unicode(request):
     return _prepare_db_test(request)
 
 
- at pytest.fixture(scope='function', params=models.SORTED_MODELS)
+ at pytest.fixture(scope='function', params=models.SORTED_MODELS, ids=idfn)
 def sorted_model(request):
     return _prepare_db_test(request)
 
 
- at pytest.fixture(scope='function', params=models.RELATED_MODELS)
+ at pytest.fixture(scope='function', params=models.RELATED_MODELS, ids=idfn)
 def related_model(request):
     return _prepare_db_test(request)
 
 
- at pytest.fixture(scope='function', params=models.INHERITED_MODELS)
+ at pytest.fixture(scope='function', params=models.INHERITED_MODELS, ids=idfn)
 def inherited_model(request):
     return _prepare_db_test(request)
 
 
- at pytest.fixture(scope='function', params=models.MP_SHORTPATH_MODELS)
+ at pytest.fixture(scope='function', params=models.MP_SHORTPATH_MODELS, ids=idfn)
 def mpshort_model(request):
     return _prepare_db_test(request)
 
 
- at pytest.fixture(scope='function', params=[models.MP_TestNodeShortPath])
+ at pytest.fixture(scope='function', params=[models.MP_TestNodeShortPath], ids=idfn)
 def mpshortnotsorted_model(request):
     return _prepare_db_test(request)
 
 
- at pytest.fixture(scope='function', params=[models.MP_TestNodeAlphabet])
+ at pytest.fixture(scope='function', params=[models.MP_TestNodeAlphabet], ids=idfn)
 def mpalphabet_model(request):
     return _prepare_db_test(request)
 
 
- at pytest.fixture(scope='function', params=[models.MP_TestNodeSortedAutoNow])
+ at pytest.fixture(scope='function', params=[models.MP_TestNodeSortedAutoNow], ids=idfn)
 def mpsortedautonow_model(request):
     return _prepare_db_test(request)
 
@@ -1759,6 +1763,19 @@ class TestInheritedModels(TestTreeBase):
         assert node21.get_descendant_count() == 2
         assert node3.get_descendant_count() == 0
 
+    def test_cascading_deletion(self, inherited_model):
+        # Deleting a node by calling delete() on the inherited_model class
+        # should delete descendants, even if those descendants are not
+        # instances of inherited_model
+        base_model = inherited_model.__bases__[0]
+
+        node21 = inherited_model.objects.get(desc='21')
+        node21.delete()
+        node2 = base_model.objects.get(desc='2')
+        for desc in ['21', '211', '212']:
+            assert not base_model.objects.filter(desc=desc).exists()
+        assert [node.desc for node in node2.get_descendants()] == ['22']
+
 
 class TestMP_TreeAlphabet(TestTreeBase):
     @pytest.mark.skipif(

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



More information about the Python-modules-commits mailing list