diff --git a/monitoring/alarmdefs/views.py b/monitoring/alarmdefs/views.py
index 5dcf6cd0..49d4ebba 100644
--- a/monitoring/alarmdefs/views.py
+++ b/monitoring/alarmdefs/views.py
@@ -19,6 +19,7 @@ from django.core.paginator import Paginator, EmptyPage
from django.core.urlresolvers import reverse_lazy, reverse # noqa
from django.utils.translation import ugettext as _ # noqa
from django.views.generic import TemplateView # noqa
+import six
from horizon import exceptions
from horizon import forms
@@ -154,7 +155,7 @@ class AlarmDetailView(TemplateView):
except exc.HttpError:
msg = _("Notification %s has already been deleted.") % id
notifications.append({"id": id,
- "name": unicode(msg),
+ "name": six.text_type(msg),
"type": "",
"address": ""})
diff --git a/monitoring/alarms/forms.py b/monitoring/alarms/forms.py
index 638afdde..06083f04 100644
--- a/monitoring/alarms/forms.py
+++ b/monitoring/alarms/forms.py
@@ -19,6 +19,7 @@ from django import forms as django_forms
from django.template.loader import get_template
from django.utils import html
from django.utils.translation import ugettext_lazy as _ # noqa
+import six
from horizon import exceptions
from horizon import forms
@@ -116,7 +117,7 @@ class NotificationCreateWidget(forms.Select):
output = '
'
output += '%s |
' % \
- unicode(_("Name"))
+ six.text_type(_("Name"))
if value:
idx = 1
for notification in value:
@@ -143,7 +144,7 @@ class NotificationCreateWidget(forms.Select):
output += 'X | '
output += ''
output += '
'
- label = unicode(_("+ Add more"))
+ label = six.text_type(_("+ Add more"))
output += '%s' % (label)
return html.format_html(output)
@@ -221,10 +222,10 @@ class BaseAlarmForm(forms.SelfHandlingForm):
if notification_choices:
if len(notification_choices) > 1:
notification_choices.insert(
- 0, ("", unicode(_("Select Notification"))))
+ 0, ("", six.text_type(_("Select Notification"))))
else:
notification_choices.insert(
- 0, ("", unicode(_("No notifications available."))))
+ 0, ("", six.text_type(_("No notifications available."))))
self.fields['notifications'].choices = notification_choices
diff --git a/monitoring/alarms/tables.py b/monitoring/alarms/tables.py
index 1a7eb5ed..f33c7868 100644
--- a/monitoring/alarms/tables.py
+++ b/monitoring/alarms/tables.py
@@ -166,7 +166,7 @@ class GraphMetric(tables.LinkAction):
metric = datum['metrics'][0]['name']
dimensions = datum['metrics'][0].get('dimensions', {})
query = "?metric=%s" % metric
- for key, value in dimensions.iteritems():
+ for key, value in dimensions.items():
query += "&dim_%s=%s" % (key, value)
except AttributeError:
# Catches case where Grafana 2 is not enabled.
diff --git a/monitoring/alarms/views.py b/monitoring/alarms/views.py
index c932cfe3..2c1fe46e 100644
--- a/monitoring/alarms/views.py
+++ b/monitoring/alarms/views.py
@@ -25,6 +25,7 @@ from django.utils.dateparse import parse_datetime
from django.utils.translation import ugettext as _ # noqa
from django.utils.translation import ugettext_lazy
from django.views.generic import View # noqa
+import six
from horizon import exceptions
from horizon import forms
@@ -100,12 +101,12 @@ def generate_status(request):
service_alarms = alarms_by_service.setdefault(service, [])
service_alarms.append(a)
for row in SERVICES:
- row['name'] = unicode(row['name'])
+ row['name'] = six.text_type(row['name'])
for service in row['services']:
service_alarms = alarms_by_service.get(service['name'], [])
service['class'] = get_status(service_alarms)
service['icon'] = get_icon(service['class'])
- service['display'] = unicode(service['display'])
+ service['display'] = six.text_type(service['display'])
return SERVICES
diff --git a/monitoring/overview/tests.py b/monitoring/overview/tests.py
index f8375cc2..33287b54 100644
--- a/monitoring/overview/tests.py
+++ b/monitoring/overview/tests.py
@@ -43,7 +43,7 @@ class KibanaProxyViewTest(helpers.TestCase):
def test_get_relative_url_with_unicode(self):
"""Tests if it properly converts multibyte characters."""
- import urlparse
+ from six.moves.urllib import parse as urlparse
self.view.request = self.request_factory.get(
'/', data={'a': 1, 'b': 2}
diff --git a/monitoring/overview/views.py b/monitoring/overview/views.py
index f2c3fc52..e1ac80b4 100644
--- a/monitoring/overview/views.py
+++ b/monitoring/overview/views.py
@@ -16,8 +16,6 @@ import base64
import copy
import json
import logging
-import urllib
-import urllib2
from django import http
from django.contrib import messages
@@ -29,6 +27,8 @@ from django.views.decorators.csrf import csrf_exempt
from django.views.generic import TemplateView # noqa
from openstack_auth import utils as auth_utils
from openstack_dashboard import policy
+import six
+from six.moves import urllib
from horizon import exceptions
@@ -79,8 +79,8 @@ def get_dashboard_links(request):
non_project_keys = {'fileName', 'title'}
try:
for project_link in settings.DASHBOARDS:
- key = project_link.keys()[0]
- value = project_link.values()[0]
+ key = list(project_link)[0]
+ value = list(project_link.values())[0]
if key in non_project_keys:
#
# we're not indexed by project, just return
@@ -129,8 +129,8 @@ def get_monitoring_services(request):
non_project_keys = {'name', 'groupBy'}
try:
for group in settings.MONITORING_SERVICES:
- key = group.keys()[0]
- value = group.values()[0]
+ key = list(group.keys())[0]
+ value = list(group.values())[0]
if key in non_project_keys:
#
# we're not indexed by project, just return
@@ -194,7 +194,7 @@ def generate_status(request):
service_alarms.append(a)
monitoring_services = copy.deepcopy(get_monitoring_services(request))
for row in monitoring_services:
- row['name'] = unicode(row['name'])
+ row['name'] = six.text_type(row['name'])
if 'groupBy' in row:
alarms_by_group = {}
for a in alarms:
@@ -220,7 +220,7 @@ def generate_status(request):
service_alarms = alarms_by_service.get(service['name'], [])
service['class'] = get_status(service_alarms)
service['icon'] = get_icon(service['class'])
- service['display'] = unicode(service['display'])
+ service['display'] = six.text_type(service['display'])
return monitoring_services
@@ -271,7 +271,7 @@ class MonascaProxyView(TemplateView):
if len(dimension_name_value) == 2:
name = dimension_name_value[0].encode('utf8')
value = dimension_name_value[1].encode('utf8')
- dim_dict[name] = urllib.unquote(value)
+ dim_dict[name] = urllib.parse.unquote(value)
else:
raise Exception('Dimensions are malformed')
@@ -329,10 +329,10 @@ class StatusView(TemplateView):
content_type='application/json')
-class _HttpMethodRequest(urllib2.Request):
+class _HttpMethodRequest(urllib.request.Request):
def __init__(self, method, url, **kwargs):
- urllib2.Request.__init__(self, url, **kwargs)
+ urllib.request.Request.__init__(self, url, **kwargs)
self.method = method
def get_method(self):
@@ -359,15 +359,15 @@ class KibanaProxyView(generic.View):
method, proxy_request_url, data=data, headers=headers
)
try:
- response = urllib2.urlopen(proxy_request)
+ response = urllib.request.urlopen(proxy_request)
- except urllib2.HTTPError as e:
+ except urllib.error.HTTPError as e:
return http.HttpResponse(
e.read(),
status=e.code,
content_type=e.hdrs['content-type']
)
- except urllib2.URLError as e:
+ except urllib.error.URLError as e:
return http.HttpResponse(e.reason, 404)
else:
@@ -406,7 +406,7 @@ class KibanaProxyView(generic.View):
return self.read(request.method, url, request.body, headers)
def get_relative_url(self, url):
- url = urllib.quote(url.encode('utf-8'))
+ url = urllib.parse.quote(url.encode('utf-8'))
params_str = self.request.GET.urlencode()
if params_str:
diff --git a/requirements.txt b/requirements.txt
index cdd13a9f..c0916c8a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -5,3 +5,4 @@ oslo.log>=3.36.0 # Apache-2.0
python-monascaclient>=1.7.0 # Apache-2.0
Django<2.0,>=1.8 # BSD
horizon>=13.0.0 # Apache-2.0
+six>=1.10.0 # MIT
diff --git a/tools/install_venv.py b/tools/install_venv.py
index 67e3a1b9..547a4470 100644
--- a/tools/install_venv.py
+++ b/tools/install_venv.py
@@ -22,6 +22,8 @@
Installation script for the OpenStack Dashboard development virtualenv.
"""
+from __future__ import print_function
+
import os
import subprocess
import sys
@@ -69,12 +71,12 @@ HAS_VIRTUALENV = bool(run_command(['which', 'virtualenv'],
def check_dependencies():
"""Make sure virtualenv is in the path."""
- print 'Checking dependencies...'
+ print('Checking dependencies...')
if not HAS_VIRTUALENV:
- print 'Virtual environment not found.'
+ print('Virtual environment not found.')
# Try installing it via easy_install...
if HAS_EASY_INSTALL:
- print 'Installing virtualenv via easy_install...',
+ print('Installing virtualenv via easy_install...', end=' ')
run_command(['easy_install', 'virtualenv'],
die_message='easy_install failed to install virtualenv'
'\ndevelopment requires virtualenv, please'
@@ -84,28 +86,28 @@ def check_dependencies():
' requires virtualenv, please install it using your'
' favorite package management tool and ensure'
' virtualenv is in your path')
- print 'virtualenv installation done.'
+ print('virtualenv installation done.')
else:
die('easy_install not found.\n\nInstall easy_install'
' (python-setuptools in ubuntu) or virtualenv by hand,'
' then rerun.')
- print 'dependency check done.'
+ print('dependency check done.')
def create_virtualenv(venv=VENV):
"""Creates the virtual environment and installs PIP only into the
virtual environment
"""
- print 'Creating venv...',
+ print('Creating venv...', end=' ')
run_command(['virtualenv', '-q', '--no-site-packages', VENV])
- print 'done.'
- print 'Installing pip in virtualenv...',
+ print('done.')
+ print('Installing pip in virtualenv...', end=' ')
if not run_command([WITH_VENV, 'easy_install', 'pip']).strip():
die("Failed to install pip.")
- print 'done.'
- print 'Installing distribute in virtualenv...'
+ print('done.')
+ print('Installing distribute in virtualenv...')
pip_install('distribute>=0.6.24')
- print 'done.'
+ print('done.')
def pip_install(*args):
@@ -114,8 +116,8 @@ def pip_install(*args):
def install_dependencies(venv=VENV):
- print "Installing dependencies..."
- print "(This may take several minutes, don't panic)"
+ print("Installing dependencies...")
+ print("(This may take several minutes, don't panic)")
pip_install('-r', TEST_REQUIRES)
pip_install('-r', PIP_REQUIRES)
@@ -127,7 +129,7 @@ def install_dependencies(venv=VENV):
def install_horizon():
- print 'Installing horizon module in development mode...'
+ print('Installing horizon module in development mode...')
run_command([WITH_VENV, 'python', 'setup.py', 'develop'], cwd=ROOT)
@@ -140,7 +142,7 @@ can run:
$ source .venv/bin/activate
"""
- print summary
+ print(summary)
def main():
diff --git a/tox.ini b/tox.ini
index ef0100ba..19dc9bb6 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py27,pep8
+envlist = py27,pep8,py35
minversion = 2.6
skipsdist = True