Commit d02ed150 authored by Stephen Finucane's avatar Stephen Finucane Committed by Damien Lespiau
Browse files

py3: "Modernize" code base



Run code through the 'modernize' application to fix Python 3
compatibility while also retaining Python 2 backwards compatibility.

There are some key changes made to the autogenerated code:

* Don't wrap 'items()' in 'list' for for loops - it's not necessary
* Don't wrap 'keys()' in 'list' - just drop 'keys()'
* Use Django's version of six rather than the upstream one

Many of the issues found are based upon the changed definitions of the
map, keys and items functions, along with the removal of the iteritems
function and reduce keyword.

v2: Port to fdo's patchwork (Damien)
Signed-off-by: default avatarStephen Finucane <stephen.finucane@intel.com>
Signed-off-by: default avatarDamien Lespiau <damien.lespiau@intel.com>
parent b348108b
......@@ -28,6 +28,7 @@ from email import message_from_file
from email.header import Header, decode_header
from email.parser import HeaderParser
from email.utils import parsedate_tz, mktime_tz
from functools import reduce
import logging
import operator
import re
......@@ -40,6 +41,8 @@ from django.contrib.auth.models import User
from django.core.exceptions import MultipleObjectsReturned
from django.db.models import Q
from django.utils.log import AdminEmailHandler
from django.utils import six
from django.utils.six.moves import map
from patchwork import lock as lockmod
from patchwork.lock import release
......@@ -75,7 +78,7 @@ def clean_header(header):
return frag_str.decode(frag_encoding)
return frag_str.decode()
fragments = map(decode, decode_header(header))
fragments = list(map(decode, decode_header(header)))
return normalise_space(u' '.join(fragments))
......@@ -182,8 +185,8 @@ def mail_date(mail):
def mail_headers(mail):
return reduce(operator.__concat__,
['%s: %s\n' % (k, Header(v, header_name = k,
continuation_ws = '\t').encode())
for (k, v) in mail.items()])
continuation_ws = '\t').encode())
for (k, v) in list(mail.items())])
def find_pull_request(content):
......@@ -199,7 +202,7 @@ def find_pull_request(content):
def try_decode(payload, charset):
try:
payload = unicode(payload, charset)
payload = six.text_type(payload, charset)
except UnicodeDecodeError:
return None
return payload
......@@ -329,7 +332,7 @@ def find_content(project, mail):
payload = part.get_payload(decode=True)
subtype = part.get_content_subtype()
if not isinstance(payload, unicode):
if not isinstance(payload, six.text_type):
charset = part.get_content_charset()
# Check that we have a charset that we understand. Otherwise,
......@@ -817,7 +820,7 @@ def main(args):
def list_logging_levels():
"""Give a summary of all available logging levels."""
return sorted(VERBOSITY_LEVELS.keys(),
return sorted(list(VERBOSITY_LEVELS.keys()),
key=lambda x: VERBOSITY_LEVELS[x])
parser.add_argument('--verbosity', choices=list_logging_levels(),
......
......@@ -19,11 +19,11 @@
from __future__ import absolute_import
from urllib import quote
from django.contrib.auth.models import User
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.utils import six
from django.utils.six.moves.urllib.parse import quote
from patchwork.models import Person, State
......@@ -55,7 +55,7 @@ class Filter(object):
pass
def parse(self, dict):
if self.param not in dict.keys():
if self.param not in dict:
return
self._set_key(dict[self.param])
......@@ -278,7 +278,7 @@ class ArchiveFilter(Filter):
def _set_key(self, str):
self.archive_state = False
self.applied = True
for (k, v) in self.param_map.iteritems():
for (k, v) in self.param_map.items():
if str == v:
self.archive_state = k
if self.archive_state == None:
......@@ -411,7 +411,7 @@ filterclasses = [SubmitterFilter, \
class Filters:
def __init__(self, request):
self._filters = map(lambda c: c(self), filterclasses)
self._filters = [c(self) for c in filterclasses]
self.dict = request.GET
self.project = None
......@@ -441,29 +441,27 @@ class Filters:
def querystring(self, remove = None):
params = dict(self.params())
for (k, v) in self.dict.iteritems():
for (k, v) in self.dict.items():
if k not in params:
params[k] = v
if remove is not None:
if remove.param in params.keys():
if remove.param in list(params.keys()):
del params[remove.param]
pairs = params.iteritems()
def sanitise(s):
if not isinstance(s, basestring):
s = unicode(s)
if not isinstance(s, six.string_types):
s = six.text_type(s)
return quote(s.encode('utf-8'))
return '?' + '&'.join(['%s=%s' % (sanitise(k), sanitise(v))
for (k, v) in pairs])
for (k, v) in list(params.items())])
def querystring_without_filter(self, filter):
return self.querystring(filter)
def applied_filters(self):
return filter(lambda x: x.applied, self._filters)
return [x for x in self._filters if x.applied]
def available_filters(self):
return self._filters
......
......@@ -21,6 +21,7 @@ from __future__ import absolute_import
from django.conf import settings
from django.core import paginator
from django.utils.six.moves import range
DEFAULT_PATCHES_PER_PAGE = 100
......
......@@ -26,6 +26,8 @@ from collections import Counter
import hashlib
import re
from django.utils.six.moves import map
_hunk_re = re.compile('^\@\@ -\d+(?:,(\d+))? \+\d+(?:,(\d+))? \@\@')
_filename_re = re.compile('^(---|\+\+\+) (\S+)')
......@@ -113,7 +115,7 @@ def parse_patch(text):
return 1
return int(x)
lc = map(fn, match.groups())
lc = list(map(fn, match.groups()))
state = 4
patchbuf += buf + line
......@@ -217,7 +219,7 @@ def hash_patch(str):
if not x:
return 1
return int(x)
line_nos = map(fn, hunk_match.groups())
line_nos = list(map(fn, hunk_match.groups()))
line = '@@ -%d +%d @@' % tuple(line_nos)
elif line[0] in prefixes:
......
......@@ -39,7 +39,7 @@ class ListURLNode(template.defaulttags.URLNode):
def __init__(self, kwargs):
super(ListURLNode, self).__init__(None, [], {}, False)
self.params = {}
for (k, v) in kwargs.iteritems():
for (k, v) in kwargs.items():
if k in list_params:
self.params[k] = v
......@@ -68,14 +68,14 @@ class ListURLNode(template.defaulttags.URLNode):
except Exception:
pass
for (k, v) in self.params.iteritems():
for (k, v) in self.params.items():
params[smart_str(k, 'ascii')] = v.resolve(context)
if not params:
return str
return str + '?' + '&'.join(
['%s=%s' % (k, escape(v)) for (k, v) in params.iteritems()])
['%s=%s' % (k, escape(v)) for (k, v) in list(params.items())])
@register.tag
......
......@@ -24,6 +24,7 @@ import re
from django import template
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.utils.six.moves import map
register = template.Library()
......@@ -32,17 +33,17 @@ def _compile(t):
(r, str) = t
return (re.compile(r, re.M | re.I), str)
_patch_span_res = map(_compile, [
_patch_span_res = list(map(_compile, [
('^(Index:?|diff|\-\-\-|\+\+\+|\*\*\*) .*$', 'p_header'),
('^\+.*$', 'p_add'),
('^-.*$', 'p_del'),
('^!.*$', 'p_mod'),
])
]))
_patch_chunk_re = \
re.compile('^(@@ \-\d+(?:,\d+)? \+\d+(?:,\d+)? @@)(.*)$', re.M | re.I)
_comment_span_res = map(_compile, [
_comment_span_res = list(map(_compile, [
('^\s*Signed-off-by: .*$', 'signed-off-by'),
('^\s*Acked-by: .*$', 'acked-by'),
('^\s*Nacked-by: .*$', 'nacked-by'),
......@@ -50,7 +51,7 @@ _comment_span_res = map(_compile, [
('^\s*Reviewed-by: .*$', 'reviewed-by'),
('^\s*From: .*$', 'from'),
('^\s*&gt;.*$', 'quote'),
])
]))
_span = '<span class="%s">%s</span>'
......
......@@ -29,6 +29,7 @@ from django.utils.http import urlencode
from patchwork.models import Patch, Bundle, BundlePatch, Person
from patchwork.tests.utils import defaults, create_user, find_in_context
from django.utils.six.moves import range, zip
def bundle_url(bundle):
return '/bundle/%s/%s/' % (bundle.owner.username, bundle.name)
......@@ -573,11 +574,11 @@ class BundleInitialOrderTest(BundleTestBase):
bundle.delete()
def testBundleForwardOrder(self):
ids = map(lambda p: p.id, self.patches)
ids = [p.id for p in self.patches]
self._testOrder(ids, self.patches)
def testBundleReverseOrder(self):
ids = map(lambda p: p.id, self.patches)
ids = [p.id for p in self.patches]
ids.reverse()
self._testOrder(ids, self.patches)
......@@ -611,7 +612,7 @@ class BundleReorderTest(BundleTestBase):
# check if order field is still sequential:
order_numbers = [ bp.order for bp in bps ]
expected_order = range(1, len(neworder)+1) # [1 ... len(neworder)]
expected_order = list(range(1, len(neworder)+1)) # [1 ... len(neworder)]
self.failUnlessEqual(order_numbers, expected_order)
def testBundleReorderAll(self):
......
......@@ -28,6 +28,7 @@ import unittest
from django.core.urlresolvers import reverse
from django.test.client import Client
from django.test import TestCase
from django.utils.six.moves import zip
from patchwork.models import Person, Patch
from patchwork.tests.utils import defaults, create_user, find_in_context
......@@ -83,7 +84,7 @@ class PatchOrderTest(TestCase):
ids = self._extract_patch_ids(response)
self.assertTrue(bool(ids))
patches = [ Patch.objects.get(id = i) for i in ids ]
pairs = zip(patches, patches[1:])
pairs = list(zip(patches, patches[1:]))
[ test_fn(p1, p2) for (p1, p2) in pairs ]
def testDateOrder(self):
......
......@@ -24,6 +24,7 @@ import unittest
from django.test.client import Client
from django.test import TestCase
from django.utils.six.moves import map, range
from patchwork.models import EmailConfirmation, Person, Bundle
......@@ -33,7 +34,7 @@ class SubmitterCompletionTest(TestCase):
Person(name = "Test Name", email = "test1@example.com"),
Person(email = "test2@example.com"),
]
map(lambda p: p.save(), self.people)
list(map(lambda p: p.save(), self.people))
def testNameComplete(self):
response = self.client.get('/submitter/', {'q': 'name'})
......
......@@ -18,11 +18,11 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import unittest
import xmlrpclib
from django.conf import settings
from django.core.urlresolvers import reverse
from django.test import LiveServerTestCase
from django.utils.six.moves import xmlrpc_client
from patchwork.models import Person, Patch
from patchwork.tests.utils import defaults
......@@ -36,7 +36,7 @@ class XMLRPCTest(LiveServerTestCase):
def setUp(self):
self.url = (self.live_server_url +
reverse('patchwork.views.xmlrpc.xmlrpc'))
self.rpc = xmlrpclib.Server(self.url)
self.rpc = xmlrpc_client.Server(self.url)
def testGetRedirect(self):
response = self.client.patch(self.url)
......
......@@ -106,7 +106,7 @@ def read_patch(filename, encoding = None):
if encoding is not None:
f = codecs.open(file_path, encoding = encoding)
else:
f = file(file_path)
f = open(file_path)
return f.read()
......
......@@ -76,7 +76,7 @@ class Order(object):
str = str[1:]
reversed = True
if str not in self.order_map.keys():
if str not in self.order_map:
return
self.order = str
......
......@@ -108,7 +108,7 @@ def optinout(request, action, description):
conf_settings.DEFAULT_FROM_EMAIL, [email])
context['email'] = mail
context['email_sent'] = True
except Exception, ex:
except Exception as ex:
context['error'] = 'An error occurred during confirmation . ' + \
'Please try again later.'
context['admins'] = conf_settings.ADMINS
......
......@@ -64,7 +64,7 @@ def patch(request, patch_id):
bundle.append_patch(patch)
bundle.save()
context.add_message('Patch added to bundle "%s"' % bundle.name)
except Exception, ex:
except Exception as ex:
context.add_message("Couldn't add patch '%s' to bundle %s: %s" \
% (patch.name, bundle.name, ex.message))
......
......@@ -23,16 +23,21 @@
from __future__ import absolute_import
import base64
from DocXMLRPCServer import XMLRPCDocGenerator
from SimpleXMLRPCServer import SimpleXMLRPCDispatcher
# NOTE(stephenfin) six does not seem to support this
try:
from DocXMLRPCServer import XMLRPCDocGenerator
except ImportError:
from xmlrpc.server import XMLRPCDocGenerator
import sys
import xmlrpclib
from django.core import urlresolvers
from django.contrib.auth import authenticate
from django.http import (
HttpResponse, HttpResponseRedirect, HttpResponseServerError)
from django.views.decorators.csrf import csrf_exempt
from django.utils import six
from django.utils.six.moves import map, xmlrpc_client
from django.utils.six.moves.xmlrpc_server import SimpleXMLRPCDispatcher
from patchwork.models import Patch, Project, Person, State
from patchwork.views import patch_to_mbox
......@@ -52,7 +57,7 @@ class PatchworkXMLRPCDispatcher(SimpleXMLRPCDispatcher,
def _dumps(obj, *args, **kwargs):
kwargs['allow_none'] = self.allow_none
kwargs['encoding'] = self.encoding
return xmlrpclib.dumps(obj, *args, **kwargs)
return xmlrpc_client.dumps(obj, *args, **kwargs)
self.dumps = _dumps
......@@ -90,7 +95,7 @@ class PatchworkXMLRPCDispatcher(SimpleXMLRPCDispatcher,
return authenticate(username=username, password=password)
def _dispatch(self, request, method, params):
if method not in self.func_map.keys():
if method not in list(self.func_map.keys()):
raise Exception('method "%s" is not supported' % method)
auth_required, fn = self.func_map[method]
......@@ -106,18 +111,19 @@ class PatchworkXMLRPCDispatcher(SimpleXMLRPCDispatcher,
def _marshaled_dispatch(self, request):
try:
params, method = xmlrpclib.loads(request.body)
params, method = six.moves.xmlrpc_client.loads(request.body)
response = self._dispatch(request, method, params)
# wrap response in a singleton tuple
response = (response,)
response = self.dumps(response, methodresponse=1)
except xmlrpclib.Fault, fault:
except six.moves.xmlrpc_client.Fault as fault:
response = self.dumps(fault)
except:
# report exception back to server
response = self.dumps(
xmlrpclib.Fault(1, '%s:%s' % (sys.exc_type, sys.exc_value)),
six.moves.xmlrpc_client.Fault(1,
'%s:%s' % (sys.exc_info()[0], sys.exc_info()[1])),
)
return response
......@@ -225,7 +231,7 @@ def person_to_dict(obj):
'id': obj.id,
'email': obj.email,
'name': name,
'user': unicode(obj.user).encode('utf-8'),
'user': six.text_type(obj.user).encode('utf-8'),
}
......@@ -261,18 +267,18 @@ def patch_to_dict(obj):
"""
return {
'id': obj.id,
'date': unicode(obj.date).encode('utf-8'),
'date': six.text_type(obj.date).encode('utf-8'),
'filename': obj.filename(),
'msgid': obj.msgid,
'name': obj.name,
'project': unicode(obj.project).encode('utf-8'),
'project': six.text_type(obj.project).encode('utf-8'),
'project_id': obj.project_id,
'state': unicode(obj.state).encode('utf-8'),
'state': six.text_type(obj.state).encode('utf-8'),
'state_id': obj.state_id,
'archived': obj.archived,
'submitter': unicode(obj.submitter).encode('utf-8'),
'submitter': six.text_type(obj.submitter).encode('utf-8'),
'submitter_id': obj.submitter_id,
'delegate': unicode(obj.delegate).encode('utf-8'),
'delegate': six.text_type(obj.delegate).encode('utf-8'),
'delegate_id': max(obj.delegate_id, 0),
'commit_ref': max(obj.commit_ref, ''),
}
......@@ -376,7 +382,7 @@ def project_list(search_str=None, max_count=0):
elif max_count < 0:
return map(project_to_dict, projects)[max_count:]
else:
return map(project_to_dict, projects)
return list(map(project_to_dict, projects))
except Project.DoesNotExist:
return []
......@@ -430,7 +436,7 @@ def person_list(search_str=None, max_count=0):
elif max_count < 0:
return map(person_to_dict, people)[max_count:]
else:
return map(person_to_dict, people)
return list(map(person_to_dict, people))
except Person.DoesNotExist:
return []
......@@ -571,13 +577,13 @@ def patch_list(filt=None):
patches = Patch.objects.filter(**dfilter)
if max_count > 0:
return map(patch_to_dict, patches[:max_count])
return [patch_to_dict(p) for p in patches[:max_count]]
elif max_count < 0:
results = map(patch_to_dict, patches.reverse()[:-max_count])
results.reverse()
return results
res = [patch_to_dict(p) for p in patches.reverse()[:-max_count]]
res.reverse()
return res
else:
return map(patch_to_dict, patches)
return [patch_to_dict(p) for p in patches]
except Patch.DoesNotExist:
return []
......@@ -727,7 +733,7 @@ def patch_set(user, patch_id, params):
if not patch.is_editable(user):
raise Exception('No permissions to edit this patch')
for (k, v) in params.iteritems():
for (k, v) in params.items():
if k not in ok_params:
continue
......@@ -772,7 +778,7 @@ def state_list(search_str=None, max_count=0):
elif max_count < 0:
return map(state_to_dict, states)[max_count:]
else:
return map(state_to_dict, states)
return list(map(state_to_dict, states))
except State.DoesNotExist:
return []
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment