[Python-modules-commits] [django-session-security] 07/09: Test stabilization and Django upgrade

Jean-Michel Vourgère nirgal at moszumanska.debian.org
Sun Jan 17 04:55:43 UTC 2016


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

nirgal pushed a commit to tag 2.3.1
in repository django-session-security.

commit 629cb112d5d6a1c12133331fae55e5b3cba5e298
Author: jpic <jamespic at gmail.com>
Date:   Wed Dec 23 02:45:10 2015 +0100

    Test stabilization and Django upgrade
    
    This commit introduces django-sbo-selenium, which is AWESOME so far,
    apparently it should give use saucelabs support for free so we should be
    able to test on a variety of browser when this is set up on travis.
---
 .travis.yml                                        |  13 +-
 circle.yml                                         |   1 -
 .../fixtures/session_security_test_user.json       |  20 +++
 session_security/tests/project/__init__.py         |   0
 session_security/tests/project/settings.py         | 117 +++++++++++++++++
 .../tests/project}/static/jquery.js                |   0
 .../tests/project}/templates/404.html              |   0
 .../tests/project}/templates/500.html              |   0
 .../tests/project}/templates/admin/base_site.html  |   0
 .../tests/project}/templates/home.html             |   0
 .../tests/project}/urls.py                         |  15 ++-
 session_security/tests/project/wsgi.py             |  16 +++
 session_security/tests/test_base.py                |  68 +++-------
 session_security/tests/test_middleware.py          |   8 +-
 session_security/tests/test_script.py              | 143 ++++++---------------
 session_security/tests/test_views.py               |   6 +-
 session_security/urls.py                           |   4 +-
 test_project/test_project/settings.py              |   1 +
 tox.ini                                            |  31 ++---
 19 files changed, 254 insertions(+), 189 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 5739112..f1266b2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,23 +4,20 @@ python:
   - "2.7"
 env:
   matrix:
-  - TOXENV=py27-django16
   - TOXENV=py27-django17
   - TOXENV=py27-django18
   - TOXENV=py27-django19
-  - TOXENV=py34-django16
+  - TOXENV=py27-django110
   - TOXENV=py34-django17
   - TOXENV=py34-django18
   - TOXENV=py34-django19
-before_script:
-  - "export DISPLAY=:99.0"
-  - "sh -e /etc/init.d/xvfb start"
-  - sleep 3 # give xvfb some time to start
+  - TOXENV=py34-django110
 install:
-  - pip install tox --use-mirrors
+  - pip install -U pip
+  - pip install tox
   - pip freeze
 script:
-  - CI=1 tox
+  - tox
 notifications:
   irc:
     channels:
diff --git a/circle.yml b/circle.yml
deleted file mode 120000
index e623fa5..0000000
--- a/circle.yml
+++ /dev/null
@@ -1 +0,0 @@
-.travis.yml
\ No newline at end of file
diff --git a/session_security/fixtures/session_security_test_user.json b/session_security/fixtures/session_security_test_user.json
new file mode 100644
index 0000000..7d1d88c
--- /dev/null
+++ b/session_security/fixtures/session_security_test_user.json
@@ -0,0 +1,20 @@
+[
+{
+    "fields": {
+        "username": "test",
+        "first_name": "",
+        "last_name": "",
+        "is_active": true,
+        "is_superuser": true,
+        "is_staff": true,
+        "last_login": "2016-01-02T18:58:21.335Z",
+        "groups": [],
+        "user_permissions": [],
+        "password": "pbkdf2_sha256$20000$TQkBIr0aXufO$+gnQDKfj7Gr1S1USQLULGIH0dXZAvmwVAv8OgoREkEE=",
+        "email": "t at tt.tt",
+        "date_joined": "2016-01-02T18:58:14.790Z"
+    },
+    "model": "auth.user",
+    "pk": 1
+}
+]
diff --git a/session_security/tests/project/__init__.py b/session_security/tests/project/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/session_security/tests/project/settings.py b/session_security/tests/project/settings.py
new file mode 100644
index 0000000..def47de
--- /dev/null
+++ b/session_security/tests/project/settings.py
@@ -0,0 +1,117 @@
+"""
+Django settings for project project.
+
+Generated by 'django-admin startproject' using Django 1.8.3.dev20150604012123.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/dev/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/dev/ref/settings/
+"""
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+import os
+
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/dev/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '#vhyi-*846#q09+him)ogenb#j7^3(w5($c8c1@)sy781(!8fm'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = (
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'session_security',
+    'sbo_selenium',
+)
+
+MIDDLEWARE_CLASSES = (
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+    'session_security.middleware.SessionSecurityMiddleware',
+)
+
+ROOT_URLCONF = 'session_security.tests.project.urls'
+
+TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')]
+TEMPLATE_CONTEXT_PROCESSORS = [
+    'django.core.context_processors.request',
+    'django.core.context_processors.debug',
+    'django.contrib.auth.context_processors.auth',
+]
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': TEMPLATE_DIRS,
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+            ]
+        },
+    },
+]
+
+STATICFILES_DIRS = (
+    os.path.join(BASE_DIR, 'static'),
+)
+
+WSGI_APPLICATION = 'session_security.tests.project.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/dev/ref/settings/#databases
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3',
+        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+    }
+}
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/dev/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/dev/howto/static-files/
+
+STATIC_URL = '/static/'
+
+SESSION_SECURITY_EXPIRE_AFTER=10
+SESSION_SECURITY_WARN_AFTER=5
diff --git a/test_project/static/jquery.js b/session_security/tests/project/static/jquery.js
similarity index 100%
rename from test_project/static/jquery.js
rename to session_security/tests/project/static/jquery.js
diff --git a/test_project/templates/404.html b/session_security/tests/project/templates/404.html
similarity index 100%
rename from test_project/templates/404.html
rename to session_security/tests/project/templates/404.html
diff --git a/test_project/templates/500.html b/session_security/tests/project/templates/500.html
similarity index 100%
rename from test_project/templates/500.html
rename to session_security/tests/project/templates/500.html
diff --git a/test_project/templates/admin/base_site.html b/session_security/tests/project/templates/admin/base_site.html
similarity index 100%
rename from test_project/templates/admin/base_site.html
rename to session_security/tests/project/templates/admin/base_site.html
diff --git a/test_project/templates/home.html b/session_security/tests/project/templates/home.html
similarity index 100%
rename from test_project/templates/home.html
rename to session_security/tests/project/templates/home.html
diff --git a/test_project/test_project/urls.py b/session_security/tests/project/urls.py
similarity index 77%
rename from test_project/test_project/urls.py
rename to session_security/tests/project/urls.py
index 09d6e66..a89d543 100644
--- a/test_project/test_project/urls.py
+++ b/session_security/tests/project/urls.py
@@ -1,6 +1,11 @@
 import time
 
-from django.conf.urls import patterns, include, url
+from django.conf.urls import include, url
+
+try:
+    from django.conf.urls import patterns
+except ImportError:
+    patterns = None
 
 # Uncomment the next two lines to enable the admin:
 from django.contrib import admin
@@ -15,10 +20,14 @@ class SleepView(generic.TemplateView):
         time.sleep(int(request.GET.get('seconds', 0)))
         return super(SleepView, self).get(request, *args, **kwargs)
 
-urlpatterns = patterns('',
+
+urlpatterns = [
     url(r'^$', generic.TemplateView.as_view(template_name='home.html')),
     url(r'^sleep/$', login_required(
         SleepView.as_view(template_name='home.html')), name='sleep'),
     url(r'^admin/', include(admin.site.urls)),
     url(r'session_security/', include('session_security.urls')),
-)
+]
+
+if patterns:
+    urlpatterns = patterns('', *urlpatterns)
diff --git a/session_security/tests/project/wsgi.py b/session_security/tests/project/wsgi.py
new file mode 100644
index 0000000..6cf673d
--- /dev/null
+++ b/session_security/tests/project/wsgi.py
@@ -0,0 +1,16 @@
+"""
+WSGI config for project project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
+
+application = get_wsgi_application()
diff --git a/session_security/tests/test_base.py b/session_security/tests/test_base.py
index 1ffb9e5..19027b7 100644
--- a/session_security/tests/test_base.py
+++ b/session_security/tests/test_base.py
@@ -1,34 +1,23 @@
 import os
 import time
+import atexit
 
 from django.contrib.auth.models import User
 
-try:
-    from django.contrib.staticfiles.testing import StaticLiveServerTestCase as \
-        LiveServerTestCase
-except ImportError:
-    from django.test import LiveServerTestCase
+from sbo_selenium import SeleniumTestCase
+
 from selenium.webdriver.common.keys import Keys
 from selenium.webdriver.common.action_chains import ActionChains
+from selenium.webdriver.phantomjs.webdriver import WebDriver
+from selenium.webdriver import Remote
+from django.contrib.staticfiles.testing import StaticLiveServerTestCase
 
-if os.environ.get('CI', False):
-    from selenium.webdriver.phantomjs.webdriver import WebDriver
-else:
-    from selenium.webdriver.chrome.webdriver import WebDriver
 from selenium.common.exceptions import NoSuchElementException
 
 from session_security.settings import WARN_AFTER, EXPIRE_AFTER
 
 
-def get_or_create_test_admin():
-    u, c = User.objects.get_or_create(username='test')
-
-    if c:
-        u.is_staff = True
-        u.set_password('test')
-        u.save()
-
-    return u
+WAIT_TIME = 5 if not os.environ.get('CI', False) else 30
 
 
 class SettingsMixin(object):
@@ -36,42 +25,25 @@ class SettingsMixin(object):
         # Give some time for selenium lag
         self.min_warn_after = WARN_AFTER
         self.max_warn_after = EXPIRE_AFTER * 0.9
+        self.min_expire_after = EXPIRE_AFTER
         self.max_expire_after = EXPIRE_AFTER * 1.5
+        super(SettingsMixin, self).setUp()
 
 
-class BaseLiveServerTestCase(SettingsMixin, LiveServerTestCase):
-    def setUp(self):
-        super(BaseLiveServerTestCase, self).setUp()
-        get_or_create_test_admin()
-        self.browser = WebDriver()
-        self.do_admin_login('test', 'test')
-
-    def tearDown(self):
-        self.browser.quit()
+class BaseLiveServerTestCase(SettingsMixin, StaticLiveServerTestCase,
+                             SeleniumTestCase):
 
-    def do_admin_login(self, username, password):
-        self.browser.get('%s%s' % (self.live_server_url, '/admin/'))
-        username_input = self.browser.find_element_by_name("username")
-        username_input.send_keys(username)
-        password_input = self.browser.find_element_by_name("password")
-        password_input.send_keys(password)
-        self.browser.find_element_by_xpath('//input[@value="Log in"]').click()
+    fixtures = ['session_security_test_user']
 
-    def new_window(self, name='other'):
-        self.browser.execute_script('window.open("/admin/", "'+ name +'")')
-        self.browser.switch_to_window(self.browser.window_handles[1])
-        while self.warning_element() is False:
-            time.sleep(0.1)
-        self.browser.switch_to_window(self.browser.window_handles[0])
+    def setUp(self):
+        super(BaseLiveServerTestCase, self).setUp()
+        self.get('/admin/')
+        self.sel.find_element_by_name('username').send_keys('test')
+        self.sel.find_element_by_name('password').send_keys('test')
+        self.sel.find_element_by_xpath('//input[@value="Log in"]').click()
+        self.sel.execute_script('window.open("/admin/", "other")')
 
     def press_space(self):
-        a = ActionChains(self.browser)
+        a = ActionChains(self.sel)
         a.key_down(Keys.SPACE)
         a.perform()
-
-    def wait_for_pages_loaded(self):
-        for win in self.browser.window_handles:
-            self.browser.switch_to_window(win)
-
-            while self.browser.execute_script('window.sessionSecurity === undefined'):
-                time.sleep(0.1)
diff --git a/session_security/tests/test_middleware.py b/session_security/tests/test_middleware.py
index 5263019..fe0ba7a 100644
--- a/session_security/tests/test_middleware.py
+++ b/session_security/tests/test_middleware.py
@@ -2,16 +2,18 @@ import time
 import unittest
 
 from django.test.client import Client
+from django import test
 from session_security.utils import set_last_activity
 from datetime import datetime, timedelta
 
-from .test_base import get_or_create_test_admin, SettingsMixin
+from .test_base import SettingsMixin
 
 
-class MiddlewareTestCase(SettingsMixin, unittest.TestCase):
+class MiddlewareTestCase(SettingsMixin, test.TestCase):
+    fixtures = ['session_security_test_user']
+
     def setUp(self):
         super(MiddlewareTestCase, self).setUp()
-        get_or_create_test_admin()
         self.client = Client()
 
     def test_auto_logout(self):
diff --git a/session_security/tests/test_script.py b/session_security/tests/test_script.py
index ebfa4be..dacda88 100644
--- a/session_security/tests/test_script.py
+++ b/session_security/tests/test_script.py
@@ -1,126 +1,57 @@
-from datetime import datetime
+import datetime
 import time
 
 from selenium.webdriver.common.keys import Keys
 from selenium.webdriver.common.action_chains import ActionChains
 from selenium.webdriver.firefox.webdriver import WebDriver
 from selenium.common.exceptions import NoSuchElementException
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.support import expected_conditions
+from selenium.webdriver.common.by import By
 
-from .test_base import BaseLiveServerTestCase
+from .test_base import BaseLiveServerTestCase, WAIT_TIME
 
-class ScriptTestCase(BaseLiveServerTestCase):
-    def warning_element(self):
-        try:
-            return self.browser.find_elements_by_css_selector(
-                '#session_security_warning')[0]
-        except IndexError:
-            return False
-
-    def deadline_passed(self, now, deadline):
-        return (datetime.now() - now).seconds > deadline
-
-    def assertWarningShows(self, max_seconds):
-        now = datetime.now()
-
-        for win in self.browser.window_handles:
-            self.browser.switch_to_window(win)
-
-            while self.warning_element() is False:
-                time.sleep(0.1)
-
-                if self.deadline_passed(now, max_seconds):
-                    self.fail('Warning did not make it into DOM')
-
-        for win in self.browser.window_handles:
-            self.browser.switch_to_window(win)
-
-            while self.warning_element().is_displayed() is False:
-                time.sleep(0.1)
-
-                if self.deadline_passed(now, max_seconds):
-                    self.fail('Warning did not make it into DOM')
-
-    def assertWarningHides(self, max_seconds):
-        now = datetime.now()
 
-        for win in self.browser.window_handles:
-            self.browser.switch_to_window(win)
-
-            while self.warning_element().is_displayed() is not False:
-                time.sleep(0.1)
-
-                if self.deadline_passed(now, max_seconds):
-                    self.fail('Warning did not hide')
-
-    def assertExpires(self, max_seconds):
-        now = datetime.now()
-
-        for win in self.browser.window_handles:
-            self.browser.switch_to_window(win)
-
-            while self.warning_element() is not False:
-                time.sleep(0.1)
-
-                if self.deadline_passed(now, max_seconds):
-                    self.fail('Warning did not make it out of DOM')
+class ScriptTestCase(BaseLiveServerTestCase):
+    def test_warning_shows_and_session_expires(self):
+        start = datetime.datetime.now()
 
-    def assertWarningShown(self):
-        for win in self.browser.window_handles:
-            self.browser.switch_to_window(win)
-            self.assertTrue(self.warning_element().is_displayed())
+        for win in self.sel.window_handles:
+            self.sel.switch_to_window(win)
+            self.wait_until_visible('#session_security_warning')
+            self.assert_visible('#session_security_warning')
 
-    def assertWarningHidden(self):
-        for win in self.browser.window_handles:
-            self.browser.switch_to_window(win)
-            self.assertFalse(self.warning_element().is_displayed())
+        end = datetime.datetime.now()
+        delta = end - start
 
-    def assertWarningNotInPage(self):
-        for win in self.browser.window_handles:
-            self.browser.switch_to_window(win)
-            self.assertTrue(self.warning_element() is False)
+        self.assertGreaterEqual(delta.seconds, self.min_warn_after)
+        self.assertLessEqual(delta.seconds, self.max_warn_after)
 
+        for win in self.sel.window_handles:
+            self.sel.switch_to_window(win)
+            self.wait_until_visible('#id_password')
 
-    def test_single_window_inactivity(self):
-        self.wait_for_pages_loaded()
-        self.assertWarningHidden()
-        self.assertWarningShows(self.max_warn_after)
-        self.assertExpires(self.max_expire_after)
+        delta = datetime.datetime.now() - start
+        self.assertGreaterEqual(delta.seconds, self.min_expire_after)
+        self.assertLessEqual(delta.seconds, self.max_expire_after)
 
-    def test_single_dont_show_warning(self):
-        self.wait_for_pages_loaded()
-        self.assertWarningHidden()
-        time.sleep(self.min_warn_after * 0.5)
+    def test_activity_hides_warning(self):
+        self.wait_until_visible('#session_security_warning')
         self.press_space()
-        self.assertWarningHidden()
-        time.sleep(self.min_warn_after * 0.5)
-        self.assertWarningHidden()
 
-    def test_single_hide_warning(self):
-        self.assertWarningShows(self.max_warn_after)
-        self.press_space()
-        self.assertWarningHides(self.min_warn_after * 0.8)
+        for win in self.sel.window_handles:
+            self.sel.switch_to_window(win)
+            self.wait_until_hidden('#session_security_warning')
+            self.assert_not_visible('#session_security_warning')
 
-    def test_double_window_inactivity(self):
-        self.new_window()
-        #self.wait_for_pages_loaded()
-        self.assertWarningHidden()
-        self.assertWarningShows(self.max_warn_after)
-        self.assertExpires(self.max_expire_after)
-
-    def test_double_dont_show_warning(self):
-        self.new_window()
-        self.wait_for_pages_loaded()
-        self.assertWarningHidden()
-        time.sleep(self.min_warn_after * 0.5)
+    def test_activity_prevents_warning(self):
+        time.sleep(self.min_warn_after * .7)
         self.press_space()
-        self.assertWarningHidden()
-        time.sleep(self.min_warn_after * 0.5)
-        self.assertWarningHidden()
 
-    def test_double_hide_warning(self):
-        self.new_window()
-        self.assertWarningShows(self.max_warn_after)
-        # Not fixing a race condition here ^^
-        time.sleep(1)
-        self.press_space()
-        self.assertWarningHides(self.min_warn_after * 0.9)
+        start = datetime.datetime.now()
+        for win in self.sel.window_handles:
+            self.sel.switch_to_window(win)
+            self.wait_until_visible('#session_security_warning')
+            self.assert_visible('#session_security_warning')
+        delta = datetime.datetime.now() - start
+        self.assertGreaterEqual(delta.seconds, self.min_warn_after)
diff --git a/session_security/tests/test_views.py b/session_security/tests/test_views.py
index 3b85bb8..c451551 100644
--- a/session_security/tests/test_views.py
+++ b/session_security/tests/test_views.py
@@ -8,18 +8,18 @@ import unittest
 
 from django.test.utils import override_settings
 from django.test.client import Client
+from django import test
 
 from unittest_data_provider import data_provider
 
 from session_security.utils import set_last_activity
 from session_security import settings
 
-from .test_base import get_or_create_test_admin
 
+class ViewsTestCase(test.TestCase):
+    fixtures = ['session_security_test_user']
 
-class ViewsTestCase(unittest.TestCase):
     def setUp(self):
-        get_or_create_test_admin()
         self.client = Client()
 
     def test_anonymous(self):
diff --git a/session_security/urls.py b/session_security/urls.py
index ee202c9..110fd66 100644
--- a/session_security/urls.py
+++ b/session_security/urls.py
@@ -15,9 +15,9 @@ ie::
 
 """
 try:
-    from django.conf.urls import url, patterns
+    from django.conf.urls import url
 except ImportError:
-    from django.conf.urls.defaults import url, patterns
+    from django.conf.urls.defaults import url
 
 from .views import PingView
 
diff --git a/test_project/test_project/settings.py b/test_project/test_project/settings.py
index 866edd6..f1843f0 100644
--- a/test_project/test_project/settings.py
+++ b/test_project/test_project/settings.py
@@ -145,6 +145,7 @@ INSTALLED_APPS = (
     # Uncomment the next line to enable the admin:
     'django.contrib.admin',
     'session_security',
+    'sbo_selenium',
     # Uncomment the next line to enable admin documentation:
     # 'django.contrib.admindocs',
 )
diff --git a/tox.ini b/tox.ini
index f8557bc..c6f47a4 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,26 +1,27 @@
 [tox]
-envlist = py{27,34}-django{16,17,18,19}
+envlist = py{27,34}-django{17,18,19,110}
 
 [testenv]
 usedevelop = true
-changedir = test_project
-
 commands =
-    ./manage.py test {posargs:session_security}
-
+    coverage run {envbindir}/django-admin selenium --browser=phantomjs session_security
 deps =
-    django16: Django>=1.6,<1.7
-    django17: Django>=1.7,<1.8
-    django18: Django>=1.8,<1.9
-    django19: Django>=1.9a1
     six
     unittest-data-provider
     selenium
-
-whitelist_externals =
-
+    https://github.com/jpic/sbo-selenium/archive/django110.tar.gz
+    coverage
+    django17: Django>=1.7,<1.8
+    django18: Django>=1.8,<1.9
+    django19: Django>=1.9,<1.10
+    django110: https://github.com/django/django/archive/master.tar.gz
 setenv =
-    PYTHONPATH=test_project
-    DJANGO_SETTINGS_MODULE=test_project.settings
+    PIP_ALLOW_EXTERNAL=true
+    DJANGO_SETTINGS_MODULE=session_security.tests.project.settings
+passenv = CI DISPLAY DBDIFF_* TEST_* TOX_* SAUCE_*
 
-passenv = CI DISPLAY
+[testenv:checkqa]
+basepython = python2.7
+commands = pep8 --ignore E128 --exclude project session_security
+deps =
+    pep8

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



More information about the Python-modules-commits mailing list