Message ID | 20230607055754.51065-1-heinrich.schuchardt@canonical.com |
---|---|
State | Deferred |
Delegated to: | Tom Rini |
Headers | show |
Series | [gitdm,1/1] Convert to Python 3 | expand |
> This is the result of running 2to3 and manually converting the comparison > functions to lambda expressions. > > Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> Hello Tom, which is the branch that you use for the gitdm U-Boot stats? Is it master or u-boot? If it is u-boot, please, update gitlab to make u-boot the main branch. The current patch applies to the master branch. Best regards Heinrich > --- > ConfigFile.py | 4 +- > csvdump.py | 4 +- > database.py | 22 +++++------ > gitdm | 27 ++++++------- > gitlog.py | 8 ++-- > logparser.py | 6 +-- > reports.py | 106 +++++++++++++++----------------------------------- > utils.py | 4 +- > 8 files changed, 70 insertions(+), 111 deletions(-) > > diff --git a/ConfigFile.py b/ConfigFile.py > index 3a1e208..e58c601 100644 > --- a/ConfigFile.py > +++ b/ConfigFile.py > @@ -147,10 +147,10 @@ def ReadFileType (filename): > m = regex_file_type.match (line) > if not m or len (m.groups ()) != 2: > ConfigFile.croak ('Funky file type line "%s"' % (line)) > - if not patterns.has_key (m.group (1)): > + if m.group (1) not in patterns: > patterns[m.group (1)] = [] > if m.group (1) not in order: > - print '%s not found, appended to the last order' % m.group (1) > + print('%s not found, appended to the last order' % m.group (1)) > order.append (m.group (1)) > > patterns[m.group (1)].append (re.compile (m.group (2), re.IGNORECASE)) > diff --git a/csvdump.py b/csvdump.py > index 9d1a65e..55e38a0 100644 > --- a/csvdump.py > +++ b/csvdump.py > @@ -50,7 +50,7 @@ def store_patch(patch): > ChangeSets.append([patch.commit, str(patch.date), > patch.email, domain, author, employer, > patch.added, patch.removed]) > - for (filetype, (added, removed)) in patch.filetypes.iteritems(): > + for (filetype, (added, removed)) in patch.filetypes.items(): > FileTypes.append([patch.commit, filetype, added, removed]) > > > @@ -82,7 +82,7 @@ def OutputCSV (file): > writer = csv.writer (file, quoting=csv.QUOTE_NONNUMERIC) > writer.writerow (['Name', 'Email', 'Affliation', 'Date', > 'Added', 'Removed', 'Changesets']) > - for date, stat in PeriodCommitHash.items(): > + for date, stat in list(PeriodCommitHash.items()): > # sanitise names " is common and \" sometimes too > empl_name = stat.employer.name.replace ('"', '.').replace ('\\', '.') > author_name = stat.name.replace ('"', '.').replace ('\\', '.') > diff --git a/database.py b/database.py > index bf13227..b267ed5 100644 > --- a/database.py > +++ b/database.py > @@ -40,7 +40,7 @@ class Hacker: > for edate, empl in self.employer[i]: > if edate > date: > return empl > - print 'OOPS. ', self.name, self.employer, self.email, email, date > + print('OOPS. ', self.name, self.employer, self.email, email, date) > return None # Should not happen > > def addpatch (self, patch): > @@ -124,11 +124,11 @@ def LookupStoreHacker(name, email, mapunknown = True): > > > def AllHackers (): > - return HackersByID.values () > + return list(HackersByID.values ()) > > def DumpDB (): > out = open ('database.dump', 'w') > - names = HackersByName.keys () > + names = list(HackersByName.keys ()) > names.sort () > for name in names: > h = HackersByName[name] > @@ -149,7 +149,7 @@ def DumpDB (): > # push it backward through the changes we've already seen. > # > def ApplyFirstTag (tag): > - for n in HackersByName.keys (): > + for n in list(HackersByName.keys ()): > if HackersByName[n].versions: > HackersByName[n].versions = [tag] > > @@ -185,7 +185,7 @@ def GetEmployer (name): > return e > > def AllEmployers (): > - return Employers.values () > + return list(Employers.values ()) > > # > # Certain obnoxious developers, who will remain nameless (because we > @@ -215,8 +215,8 @@ class VirtualEmployer (Employer): > self.__init__ (name) # Reset counts just in case > > def store (self): > - if Employers.has_key (self.name): > - print Employers[self.name] > + if self.name in Employers: > + print(Employers[self.name]) > sys.stderr.write ('WARNING: Virtual empl %s overwrites another\n' > % (self.name)) > if len (self.splits) == 0: > @@ -235,7 +235,7 @@ class FileType: > order = order or self.order > > for file_type in order: > - if patterns.has_key (file_type): > + if file_type in patterns: > for patt in patterns[file_type]: > if patt.search (filename): > return file_type > @@ -261,7 +261,7 @@ def MixVirtuals (): > EmailAliases = { } > > def AddEmailAlias (variant, canonical): > - if EmailAliases.has_key (variant): > + if variant in EmailAliases: > sys.stderr.write ('Duplicate email alias for %s\n' % (variant)) > EmailAliases[variant] = canonical > > @@ -288,7 +288,7 @@ def AddEmailEmployerMapping (email, employer, end = nextyear): > for i in range (0, len(l)): > date, xempl = l[i] > if date == end: # probably both nextyear > - print 'WARNING: duplicate email/empl for %s' % (email) > + print('WARNING: duplicate email/empl for %s' % (email)) > if date > end: > l.insert (i, (end, empl)) > return > @@ -305,7 +305,7 @@ def MapToEmployer (email, unknown = 0): > pass > namedom = email.split ('@') > if len (namedom) < 2: > - print 'Oops...funky email %s' % email > + print('Oops...funky email %s' % email) > return [(nextyear, GetEmployer ('Funky'))] > s = namedom[1].split ('.') > for dots in range (len (s) - 2, -1, -1): > diff --git a/gitdm b/gitdm > index 61318ad..f426cc7 100755 > --- a/gitdm > +++ b/gitdm > @@ -1,4 +1,4 @@ > -#!/usr/bin/pypy > +#!/usr/bin/python3 > #-*- coding:utf-8 -*- > # > > @@ -15,7 +15,8 @@ > > import database, csvdump, ConfigFile, reports > import getopt, datetime > -import os, re, sys, rfc822, string, os.path > +from email.utils import parsedate_tz > +import os, re, sys, string, os.path > import logparser > from patterns import patterns > > @@ -108,7 +109,7 @@ def ParseOpts(): > elif opt[0] == '-p': > CSVPrefix = opt[1] > elif opt[0] == '-r': > - print 'Filter on "%s"' % (opt[1]) > + print('Filter on "%s"' % (opt[1])) > FileFilter = re.compile(opt[1]) > elif opt[0] == '-s': > AuthorSOBs = 0 > @@ -120,7 +121,7 @@ def ParseOpts(): > ReportUnknowns = True > elif opt[0] == '-x': > CSVFile = open(opt[1], 'w') > - print "open output file " + opt[1] + "\n" > + print("open output file " + opt[1] + "\n") > elif opt [0] == '-w': > Aggregate = 'week' > elif opt [0] == '-y': > @@ -172,7 +173,7 @@ DateMap = { } > > def AddDateLines(date, lines): > if lines > 1000000: > - print 'Skip big patch (%d)' % lines > + print('Skip big patch (%d)' % lines) > return > try: > DateMap[date] += lines > @@ -180,7 +181,7 @@ def AddDateLines(date, lines): > DateMap[date] = lines > > def PrintDateStats(): > - dates = DateMap.keys() > + dates = list(DateMap.keys()) > dates.sort() > total = 0 > datef = open('datelc.csv', 'w') > @@ -195,7 +196,7 @@ def PrintDateStats(): > # Let's slowly try to move some smarts into this class. > # > class patch: > - (ADDED, REMOVED) = range(2) > + (ADDED, REMOVED) = list(range(2)) > > def __init__(self, commit): > self.commit = commit > @@ -219,7 +220,7 @@ class patch: > self.reports.append(reporter) > > def addfiletype(self, filetype, added, removed): > - if self.filetypes.has_key(filetype): > + if filetype in self.filetypes: > self.filetypes[filetype][self.ADDED] += added > self.filetypes[filetype][self.REMOVED] += removed > else: > @@ -330,7 +331,7 @@ def grabpatch(logpatch): > # > m = patterns['date'].match(Line) > if m: > - dt = rfc822.parsedate(m.group(2)) > + dt = parsedate_tz(m.group(2)) > p.date = datetime.date(dt[0], dt[1], dt[2]) > if p.date > Today: > sys.stderr.write('Funky date: %s\n' % p.date) > @@ -389,7 +390,7 @@ def GripeAboutAuthorName(name): > if name in GripedAuthorNames: > return > GripedAuthorNames.append(name) > - print '%s is an author name, probably not what you want' % (name) > + print('%s is an author name, probably not what you want' % (name)) > > def ApplyFileFilter(line, ignore): > # > @@ -462,14 +463,14 @@ TotalChanged = TotalAdded = TotalRemoved = 0 > # > # Snarf changesets. > # > -print >> sys.stderr, 'Grabbing changesets...\r', > +print('Grabbing changesets...\r', end=' ', file=sys.stderr) > > patches = logparser.LogPatchSplitter(sys.stdin) > printcount = CSCount = 0 > > for logpatch in patches: > if (printcount % 50) == 0: > - print >> sys.stderr, 'Grabbing changesets...%d\r' % printcount, > + print('Grabbing changesets...%d\r' % printcount, end=' ', file=sys.stderr) > printcount += 1 > > # We want to ignore commits on svn tags since in Subversion > @@ -528,7 +529,7 @@ for logpatch in patches: > CSCount += 1 > csvdump.AccumulatePatch(p, Aggregate) > csvdump.store_patch(p) > -print >> sys.stderr, 'Grabbing changesets...done ' > +print('Grabbing changesets...done ', file=sys.stderr) > > if DumpDB: > database.DumpDB() > diff --git a/gitlog.py b/gitlog.py > index 71efee1..4b1c5d6 100644 > --- a/gitlog.py > +++ b/gitlog.py > @@ -61,7 +61,7 @@ S_DONE = 5 > def get_header(patch, line, input): > if line == '': > if patch.author == '': > - print 'Funky auth line in', patch.commit > + print('Funky auth line in', patch.commit) > patch.author = database.LookupStoreHacker('Unknown', > 'unknown@hacker.net') > return S_DESC > @@ -78,7 +78,7 @@ def get_header(patch, line, input): > > def get_desc(patch, line, input): > if not line: > - print 'Missing desc in', patch.commit > + print('Missing desc in', patch.commit) > return S_CHANGELOG > patch.desc = line > line = getline(input) > @@ -188,7 +188,7 @@ def grabpatch(input): > return None > m = patterns['commit'].match(line) > if not m: > - print 'noncommit', line > + print('noncommit', line) > return None > p = patch(m.group(1)) > state = S_HEADER > @@ -199,7 +199,7 @@ def grabpatch(input): > line = getline(input) > if line is None: > if state != S_NUMSTAT: > - print 'Ran out of patch', state > + print('Ran out of patch', state) > return None > return p > state = grabbers[state](p, line, input) > diff --git a/logparser.py b/logparser.py > index b375034..88293c5 100644 > --- a/logparser.py > +++ b/logparser.py > @@ -41,7 +41,7 @@ class LogPatchSplitter: > def __iter__(self): > return self > > - def next(self): > + def __next__(self): > patch = self.__grab_patch__() > if not patch: > raise StopIteration > @@ -85,6 +85,6 @@ if __name__ == '__main__': > patches = LogPatchSplitter(sys.stdin) > > for patch in patches: > - print '---------- NEW PATCH ----------' > + print('---------- NEW PATCH ----------') > for line in patch: > - print line, > + print(line, end=' ') > diff --git a/reports.py b/reports.py > index d7a96bc..3e03e69 100644 > --- a/reports.py > +++ b/reports.py > @@ -69,11 +69,8 @@ def EndReport(): > # > # Comparison and report generation functions. > # > -def ComparePCount(h1, h2): > - return len(h2.patches) - len(h1.patches) > - > def ReportByPCount(hlist, cscount): > - hlist.sort(ComparePCount) > + hlist.sort(key=lambda h: -len(h.patches)) > count = 0 > BeginReport('Developers with the most changesets') > for h in hlist: > @@ -87,11 +84,8 @@ def ReportByPCount(hlist, cscount): > break > EndReport() > > -def CompareLChanged(h1, h2): > - return h2.changed - h1.changed > - > def ReportByLChanged(hlist, totalchanged): > - hlist.sort(CompareLChanged) > + hlist.sort(key=lambda h: -h.changed) > count = 0 > BeginReport('Developers with the most changed lines') > for h in hlist: > @@ -103,11 +97,8 @@ def ReportByLChanged(hlist, totalchanged): > break > EndReport() > > -def CompareLRemoved(h1, h2): > - return (h2.removed - h2.added) - (h1.removed - h1.added) > - > def ReportByLRemoved(hlist, totalremoved): > - hlist.sort(CompareLRemoved) > + hlist.sort(key=lambda h: h.added - h.removed) > count = 0 > BeginReport('Developers with the most lines removed') > for h in hlist: > @@ -121,11 +112,8 @@ def ReportByLRemoved(hlist, totalremoved): > break > EndReport() > > -def CompareEPCount(e1, e2): > - return e2.count - e1.count > - > def ReportByPCEmpl(elist, cscount): > - elist.sort(CompareEPCount) > + elist.sort(key=lambda e: -e.count) > count = 0 > BeginReport('Top changeset contributors by employer') > for e in elist: > @@ -137,11 +125,8 @@ def ReportByPCEmpl(elist, cscount): > EndReport() > > > -def CompareELChanged(e1, e2): > - return e2.changed - e1.changed > - > def ReportByELChanged(elist, totalchanged): > - elist.sort(CompareELChanged) > + elist.sort(key=lambda e: -e.changed) > count = 0 > BeginReport('Top lines changed by employer') > for e in elist: > @@ -154,11 +139,8 @@ def ReportByELChanged(elist, totalchanged): > > > > -def CompareSOBs(h1, h2): > - return len(h2.signoffs) - len(h1.signoffs) > - > def ReportBySOBs(hlist): > - hlist.sort(CompareSOBs) > + hlist.sort(key = lambda h: -len(h.signoffs)) > totalsobs = 0 > for h in hlist: > totalsobs += len(h.signoffs) > @@ -176,11 +158,8 @@ def ReportBySOBs(hlist): > # > # Reviewer reporting. > # > -def CompareRevs(h1, h2): > - return len(h2.reviews) - len(h1.reviews) > - > def ReportByRevs(hlist): > - hlist.sort(CompareRevs) > + hlist.sort(key=lambda h: -len(h.reviews)) > totalrevs = 0 > for h in hlist: > totalrevs += len(h.reviews) > @@ -198,11 +177,8 @@ def ReportByRevs(hlist): > # > # tester reporting. > # > -def CompareTests(h1, h2): > - return len(h2.tested) - len(h1.tested) > - > def ReportByTests(hlist): > - hlist.sort(CompareTests) > + hlist.sort(key=lambda h: -len(h.tested)) > totaltests = 0 > for h in hlist: > totaltests += len(h.tested) > @@ -217,11 +193,8 @@ def ReportByTests(hlist): > break > EndReport() > > -def CompareTestCred(h1, h2): > - return h2.testcred - h1.testcred > - > def ReportByTestCreds(hlist): > - hlist.sort(CompareTestCred) > + hlist.sort(key=lambda h: -h.testcred) > totaltests = 0 > for h in hlist: > totaltests += h.testcred > @@ -240,11 +213,8 @@ def ReportByTestCreds(hlist): > # > # Reporter reporting. > # > -def CompareReports(h1, h2): > - return len(h2.reports) - len(h1.reports) > - > def ReportByReports(hlist): > - hlist.sort(CompareReports) > + hlist.sort(key=lambda h: -len(h.reports)) > totalreps = 0 > for h in hlist: > totalreps += len(h.reports) > @@ -259,11 +229,8 @@ def ReportByReports(hlist): > break > EndReport() > > -def CompareRepCred(h1, h2): > - return h2.repcred - h1.repcred > - > def ReportByRepCreds(hlist): > - hlist.sort(CompareRepCred) > + hlist.sort(key=lambda h: -h.repcred) > totalreps = 0 > for h in hlist: > totalreps += h.repcred > @@ -280,14 +247,11 @@ def ReportByRepCreds(hlist): > # > # Versions. > # > -def CompareVersionCounts(h1, h2): > - if h1.versions and h2.versions: > - return len(h2.versions) - len(h1.versions) > - if h2.versions: > - return 1 > - if h1.versions: > - return -1 > - return 0 > +def VersionCount(h): > + if h.versions: > + return len(h.versions) > + else: > + return 0 > > def MissedVersions(hv, allv): > missed = [v for v in allv if v not in hv] > @@ -295,7 +259,7 @@ def MissedVersions(hv, allv): > return ' '.join(missed) > > def ReportVersions(hlist): > - hlist.sort(CompareVersionCounts) > + hlist.sort(key=lambda h: -VersionCount(h)) > BeginReport('Developers represented in the most kernel versions') > count = 0 > allversions = hlist[0].versions > @@ -307,11 +271,8 @@ def ReportVersions(hlist): > EndReport() > > > -def CompareESOBs(e1, e2): > - return e2.sobs - e1.sobs > - > def ReportByESOBs(elist): > - elist.sort(CompareESOBs) > + elist.sort(key=lambda e: -e.sobs) > totalsobs = 0 > for e in elist: > totalsobs += e.sobs > @@ -325,11 +286,8 @@ def ReportByESOBs(elist): > break > EndReport() > > -def CompareHackers(e1, e2): > - return len(e2.hackers) - len(e1.hackers) > - > def ReportByEHackers(elist): > - elist.sort(CompareHackers) > + elist.sort(key=lambda e: -len(e.hackers)) > totalhackers = 0 > for e in elist: > totalhackers += len(e.hackers) > @@ -375,7 +333,7 @@ def ReportUnknowns(hlist, cscount): > # mapping to (Unknown) is happening or not. > # > ulist = [ h for h in hlist if IsUnknown(h) ] > - ulist.sort(ComparePCount) > + ulist.sort(lambda h: len(h.patches)) > count = 0 > BeginReport('Developers with unknown affiliation') > for h in ulist: > @@ -398,46 +356,46 @@ def ReportByFileType(hacker_list): > by_hacker = {} > for patch in h.patches: > # Get a summary by hacker > - for (filetype, (added, removed)) in patch.filetypes.iteritems(): > - if by_hacker.has_key(filetype): > + for (filetype, (added, removed)) in patch.filetypes.items(): > + if filetype in by_hacker: > by_hacker[filetype][patch.ADDED] += added > by_hacker[filetype][patch.REMOVED] += removed > else: > by_hacker[filetype] = [added, removed] > > # Update the totals > - if total.has_key(filetype): > + if filetype in total: > total[filetype][patch.ADDED] += added > total[filetype][patch.REMOVED] += removed > else: > total[filetype] = [added, removed, []] > > # Print a summary by hacker > - print h.name > - for filetype, counters in by_hacker.iteritems(): > - print '\t', filetype, counters > + print(h.name) > + for filetype, counters in by_hacker.items(): > + print('\t', filetype, counters) > h_added = by_hacker[filetype][patch.ADDED] > h_removed = by_hacker[filetype][patch.REMOVED] > total[filetype][2].append([h.name, h_added, h_removed]) > > # Print the global summary > BeginReport('Contributions by type and developers') > - for filetype, (added, removed, hackers) in total.iteritems(): > - print filetype, added, removed > + for filetype, (added, removed, hackers) in total.items(): > + print(filetype, added, removed) > for h, h_added, h_removed in hackers: > - print '\t%s: [%d, %d]' % (h, h_added, h_removed) > + print('\t%s: [%d, %d]' % (h, h_added, h_removed)) > > # Print the very global summary > BeginReport('General contributions by type') > - for filetype, (added, removed, hackers) in total.iteritems(): > - print filetype, added, removed > + for filetype, (added, removed, hackers) in total.items(): > + print(filetype, added, removed) > > # > # The file access report is a special beast. > # > def FileAccessReport(name, accesses, total): > outf = open(name, 'w') > - files = accesses.keys() > + files = list(accesses.keys()) > files.sort() > for file in files: > a = accesses[file] > diff --git a/utils.py b/utils.py > index 2b3be5d..9f17911 100644 > --- a/utils.py > +++ b/utils.py > @@ -21,7 +21,7 @@ class accumulator: > return default > > def append(self, key, item, unique = False): > - if unique and self._data.has_key(key) and \ > + if unique and key in self._data and \ > item in self._data[key]: > return > try: > @@ -30,7 +30,7 @@ class accumulator: > self._data[key] = [item] > > def keys(self): > - return self._data.keys() > + return list(self._data.keys()) > > def __getitem__(self, key): > return self._data[key]
On Wed, Jun 07, 2023 at 07:57:54AM +0200, Heinrich Schuchardt wrote: > This is the result of running 2to3 and manually converting the comparison > functions to lambda expressions. > > Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> > --- > ConfigFile.py | 4 +- > csvdump.py | 4 +- > database.py | 22 +++++------ > gitdm | 27 ++++++------- > gitlog.py | 8 ++-- > logparser.py | 6 +-- > reports.py | 106 +++++++++++++++----------------------------------- > utils.py | 4 +- > 8 files changed, 70 insertions(+), 111 deletions(-) > Is this really versus our current tree? It's already running in python3. If there's specific "this is better python" changes, we should send them to Jon first and sync back.
diff --git a/ConfigFile.py b/ConfigFile.py index 3a1e208..e58c601 100644 --- a/ConfigFile.py +++ b/ConfigFile.py @@ -147,10 +147,10 @@ def ReadFileType (filename): m = regex_file_type.match (line) if not m or len (m.groups ()) != 2: ConfigFile.croak ('Funky file type line "%s"' % (line)) - if not patterns.has_key (m.group (1)): + if m.group (1) not in patterns: patterns[m.group (1)] = [] if m.group (1) not in order: - print '%s not found, appended to the last order' % m.group (1) + print('%s not found, appended to the last order' % m.group (1)) order.append (m.group (1)) patterns[m.group (1)].append (re.compile (m.group (2), re.IGNORECASE)) diff --git a/csvdump.py b/csvdump.py index 9d1a65e..55e38a0 100644 --- a/csvdump.py +++ b/csvdump.py @@ -50,7 +50,7 @@ def store_patch(patch): ChangeSets.append([patch.commit, str(patch.date), patch.email, domain, author, employer, patch.added, patch.removed]) - for (filetype, (added, removed)) in patch.filetypes.iteritems(): + for (filetype, (added, removed)) in patch.filetypes.items(): FileTypes.append([patch.commit, filetype, added, removed]) @@ -82,7 +82,7 @@ def OutputCSV (file): writer = csv.writer (file, quoting=csv.QUOTE_NONNUMERIC) writer.writerow (['Name', 'Email', 'Affliation', 'Date', 'Added', 'Removed', 'Changesets']) - for date, stat in PeriodCommitHash.items(): + for date, stat in list(PeriodCommitHash.items()): # sanitise names " is common and \" sometimes too empl_name = stat.employer.name.replace ('"', '.').replace ('\\', '.') author_name = stat.name.replace ('"', '.').replace ('\\', '.') diff --git a/database.py b/database.py index bf13227..b267ed5 100644 --- a/database.py +++ b/database.py @@ -40,7 +40,7 @@ class Hacker: for edate, empl in self.employer[i]: if edate > date: return empl - print 'OOPS. ', self.name, self.employer, self.email, email, date + print('OOPS. ', self.name, self.employer, self.email, email, date) return None # Should not happen def addpatch (self, patch): @@ -124,11 +124,11 @@ def LookupStoreHacker(name, email, mapunknown = True): def AllHackers (): - return HackersByID.values () + return list(HackersByID.values ()) def DumpDB (): out = open ('database.dump', 'w') - names = HackersByName.keys () + names = list(HackersByName.keys ()) names.sort () for name in names: h = HackersByName[name] @@ -149,7 +149,7 @@ def DumpDB (): # push it backward through the changes we've already seen. # def ApplyFirstTag (tag): - for n in HackersByName.keys (): + for n in list(HackersByName.keys ()): if HackersByName[n].versions: HackersByName[n].versions = [tag] @@ -185,7 +185,7 @@ def GetEmployer (name): return e def AllEmployers (): - return Employers.values () + return list(Employers.values ()) # # Certain obnoxious developers, who will remain nameless (because we @@ -215,8 +215,8 @@ class VirtualEmployer (Employer): self.__init__ (name) # Reset counts just in case def store (self): - if Employers.has_key (self.name): - print Employers[self.name] + if self.name in Employers: + print(Employers[self.name]) sys.stderr.write ('WARNING: Virtual empl %s overwrites another\n' % (self.name)) if len (self.splits) == 0: @@ -235,7 +235,7 @@ class FileType: order = order or self.order for file_type in order: - if patterns.has_key (file_type): + if file_type in patterns: for patt in patterns[file_type]: if patt.search (filename): return file_type @@ -261,7 +261,7 @@ def MixVirtuals (): EmailAliases = { } def AddEmailAlias (variant, canonical): - if EmailAliases.has_key (variant): + if variant in EmailAliases: sys.stderr.write ('Duplicate email alias for %s\n' % (variant)) EmailAliases[variant] = canonical @@ -288,7 +288,7 @@ def AddEmailEmployerMapping (email, employer, end = nextyear): for i in range (0, len(l)): date, xempl = l[i] if date == end: # probably both nextyear - print 'WARNING: duplicate email/empl for %s' % (email) + print('WARNING: duplicate email/empl for %s' % (email)) if date > end: l.insert (i, (end, empl)) return @@ -305,7 +305,7 @@ def MapToEmployer (email, unknown = 0): pass namedom = email.split ('@') if len (namedom) < 2: - print 'Oops...funky email %s' % email + print('Oops...funky email %s' % email) return [(nextyear, GetEmployer ('Funky'))] s = namedom[1].split ('.') for dots in range (len (s) - 2, -1, -1): diff --git a/gitdm b/gitdm index 61318ad..f426cc7 100755 --- a/gitdm +++ b/gitdm @@ -1,4 +1,4 @@ -#!/usr/bin/pypy +#!/usr/bin/python3 #-*- coding:utf-8 -*- # @@ -15,7 +15,8 @@ import database, csvdump, ConfigFile, reports import getopt, datetime -import os, re, sys, rfc822, string, os.path +from email.utils import parsedate_tz +import os, re, sys, string, os.path import logparser from patterns import patterns @@ -108,7 +109,7 @@ def ParseOpts(): elif opt[0] == '-p': CSVPrefix = opt[1] elif opt[0] == '-r': - print 'Filter on "%s"' % (opt[1]) + print('Filter on "%s"' % (opt[1])) FileFilter = re.compile(opt[1]) elif opt[0] == '-s': AuthorSOBs = 0 @@ -120,7 +121,7 @@ def ParseOpts(): ReportUnknowns = True elif opt[0] == '-x': CSVFile = open(opt[1], 'w') - print "open output file " + opt[1] + "\n" + print("open output file " + opt[1] + "\n") elif opt [0] == '-w': Aggregate = 'week' elif opt [0] == '-y': @@ -172,7 +173,7 @@ DateMap = { } def AddDateLines(date, lines): if lines > 1000000: - print 'Skip big patch (%d)' % lines + print('Skip big patch (%d)' % lines) return try: DateMap[date] += lines @@ -180,7 +181,7 @@ def AddDateLines(date, lines): DateMap[date] = lines def PrintDateStats(): - dates = DateMap.keys() + dates = list(DateMap.keys()) dates.sort() total = 0 datef = open('datelc.csv', 'w') @@ -195,7 +196,7 @@ def PrintDateStats(): # Let's slowly try to move some smarts into this class. # class patch: - (ADDED, REMOVED) = range(2) + (ADDED, REMOVED) = list(range(2)) def __init__(self, commit): self.commit = commit @@ -219,7 +220,7 @@ class patch: self.reports.append(reporter) def addfiletype(self, filetype, added, removed): - if self.filetypes.has_key(filetype): + if filetype in self.filetypes: self.filetypes[filetype][self.ADDED] += added self.filetypes[filetype][self.REMOVED] += removed else: @@ -330,7 +331,7 @@ def grabpatch(logpatch): # m = patterns['date'].match(Line) if m: - dt = rfc822.parsedate(m.group(2)) + dt = parsedate_tz(m.group(2)) p.date = datetime.date(dt[0], dt[1], dt[2]) if p.date > Today: sys.stderr.write('Funky date: %s\n' % p.date) @@ -389,7 +390,7 @@ def GripeAboutAuthorName(name): if name in GripedAuthorNames: return GripedAuthorNames.append(name) - print '%s is an author name, probably not what you want' % (name) + print('%s is an author name, probably not what you want' % (name)) def ApplyFileFilter(line, ignore): # @@ -462,14 +463,14 @@ TotalChanged = TotalAdded = TotalRemoved = 0 # # Snarf changesets. # -print >> sys.stderr, 'Grabbing changesets...\r', +print('Grabbing changesets...\r', end=' ', file=sys.stderr) patches = logparser.LogPatchSplitter(sys.stdin) printcount = CSCount = 0 for logpatch in patches: if (printcount % 50) == 0: - print >> sys.stderr, 'Grabbing changesets...%d\r' % printcount, + print('Grabbing changesets...%d\r' % printcount, end=' ', file=sys.stderr) printcount += 1 # We want to ignore commits on svn tags since in Subversion @@ -528,7 +529,7 @@ for logpatch in patches: CSCount += 1 csvdump.AccumulatePatch(p, Aggregate) csvdump.store_patch(p) -print >> sys.stderr, 'Grabbing changesets...done ' +print('Grabbing changesets...done ', file=sys.stderr) if DumpDB: database.DumpDB() diff --git a/gitlog.py b/gitlog.py index 71efee1..4b1c5d6 100644 --- a/gitlog.py +++ b/gitlog.py @@ -61,7 +61,7 @@ S_DONE = 5 def get_header(patch, line, input): if line == '': if patch.author == '': - print 'Funky auth line in', patch.commit + print('Funky auth line in', patch.commit) patch.author = database.LookupStoreHacker('Unknown', 'unknown@hacker.net') return S_DESC @@ -78,7 +78,7 @@ def get_header(patch, line, input): def get_desc(patch, line, input): if not line: - print 'Missing desc in', patch.commit + print('Missing desc in', patch.commit) return S_CHANGELOG patch.desc = line line = getline(input) @@ -188,7 +188,7 @@ def grabpatch(input): return None m = patterns['commit'].match(line) if not m: - print 'noncommit', line + print('noncommit', line) return None p = patch(m.group(1)) state = S_HEADER @@ -199,7 +199,7 @@ def grabpatch(input): line = getline(input) if line is None: if state != S_NUMSTAT: - print 'Ran out of patch', state + print('Ran out of patch', state) return None return p state = grabbers[state](p, line, input) diff --git a/logparser.py b/logparser.py index b375034..88293c5 100644 --- a/logparser.py +++ b/logparser.py @@ -41,7 +41,7 @@ class LogPatchSplitter: def __iter__(self): return self - def next(self): + def __next__(self): patch = self.__grab_patch__() if not patch: raise StopIteration @@ -85,6 +85,6 @@ if __name__ == '__main__': patches = LogPatchSplitter(sys.stdin) for patch in patches: - print '---------- NEW PATCH ----------' + print('---------- NEW PATCH ----------') for line in patch: - print line, + print(line, end=' ') diff --git a/reports.py b/reports.py index d7a96bc..3e03e69 100644 --- a/reports.py +++ b/reports.py @@ -69,11 +69,8 @@ def EndReport(): # # Comparison and report generation functions. # -def ComparePCount(h1, h2): - return len(h2.patches) - len(h1.patches) - def ReportByPCount(hlist, cscount): - hlist.sort(ComparePCount) + hlist.sort(key=lambda h: -len(h.patches)) count = 0 BeginReport('Developers with the most changesets') for h in hlist: @@ -87,11 +84,8 @@ def ReportByPCount(hlist, cscount): break EndReport() -def CompareLChanged(h1, h2): - return h2.changed - h1.changed - def ReportByLChanged(hlist, totalchanged): - hlist.sort(CompareLChanged) + hlist.sort(key=lambda h: -h.changed) count = 0 BeginReport('Developers with the most changed lines') for h in hlist: @@ -103,11 +97,8 @@ def ReportByLChanged(hlist, totalchanged): break EndReport() -def CompareLRemoved(h1, h2): - return (h2.removed - h2.added) - (h1.removed - h1.added) - def ReportByLRemoved(hlist, totalremoved): - hlist.sort(CompareLRemoved) + hlist.sort(key=lambda h: h.added - h.removed) count = 0 BeginReport('Developers with the most lines removed') for h in hlist: @@ -121,11 +112,8 @@ def ReportByLRemoved(hlist, totalremoved): break EndReport() -def CompareEPCount(e1, e2): - return e2.count - e1.count - def ReportByPCEmpl(elist, cscount): - elist.sort(CompareEPCount) + elist.sort(key=lambda e: -e.count) count = 0 BeginReport('Top changeset contributors by employer') for e in elist: @@ -137,11 +125,8 @@ def ReportByPCEmpl(elist, cscount): EndReport() -def CompareELChanged(e1, e2): - return e2.changed - e1.changed - def ReportByELChanged(elist, totalchanged): - elist.sort(CompareELChanged) + elist.sort(key=lambda e: -e.changed) count = 0 BeginReport('Top lines changed by employer') for e in elist: @@ -154,11 +139,8 @@ def ReportByELChanged(elist, totalchanged): -def CompareSOBs(h1, h2): - return len(h2.signoffs) - len(h1.signoffs) - def ReportBySOBs(hlist): - hlist.sort(CompareSOBs) + hlist.sort(key = lambda h: -len(h.signoffs)) totalsobs = 0 for h in hlist: totalsobs += len(h.signoffs) @@ -176,11 +158,8 @@ def ReportBySOBs(hlist): # # Reviewer reporting. # -def CompareRevs(h1, h2): - return len(h2.reviews) - len(h1.reviews) - def ReportByRevs(hlist): - hlist.sort(CompareRevs) + hlist.sort(key=lambda h: -len(h.reviews)) totalrevs = 0 for h in hlist: totalrevs += len(h.reviews) @@ -198,11 +177,8 @@ def ReportByRevs(hlist): # # tester reporting. # -def CompareTests(h1, h2): - return len(h2.tested) - len(h1.tested) - def ReportByTests(hlist): - hlist.sort(CompareTests) + hlist.sort(key=lambda h: -len(h.tested)) totaltests = 0 for h in hlist: totaltests += len(h.tested) @@ -217,11 +193,8 @@ def ReportByTests(hlist): break EndReport() -def CompareTestCred(h1, h2): - return h2.testcred - h1.testcred - def ReportByTestCreds(hlist): - hlist.sort(CompareTestCred) + hlist.sort(key=lambda h: -h.testcred) totaltests = 0 for h in hlist: totaltests += h.testcred @@ -240,11 +213,8 @@ def ReportByTestCreds(hlist): # # Reporter reporting. # -def CompareReports(h1, h2): - return len(h2.reports) - len(h1.reports) - def ReportByReports(hlist): - hlist.sort(CompareReports) + hlist.sort(key=lambda h: -len(h.reports)) totalreps = 0 for h in hlist: totalreps += len(h.reports) @@ -259,11 +229,8 @@ def ReportByReports(hlist): break EndReport() -def CompareRepCred(h1, h2): - return h2.repcred - h1.repcred - def ReportByRepCreds(hlist): - hlist.sort(CompareRepCred) + hlist.sort(key=lambda h: -h.repcred) totalreps = 0 for h in hlist: totalreps += h.repcred @@ -280,14 +247,11 @@ def ReportByRepCreds(hlist): # # Versions. # -def CompareVersionCounts(h1, h2): - if h1.versions and h2.versions: - return len(h2.versions) - len(h1.versions) - if h2.versions: - return 1 - if h1.versions: - return -1 - return 0 +def VersionCount(h): + if h.versions: + return len(h.versions) + else: + return 0 def MissedVersions(hv, allv): missed = [v for v in allv if v not in hv] @@ -295,7 +259,7 @@ def MissedVersions(hv, allv): return ' '.join(missed) def ReportVersions(hlist): - hlist.sort(CompareVersionCounts) + hlist.sort(key=lambda h: -VersionCount(h)) BeginReport('Developers represented in the most kernel versions') count = 0 allversions = hlist[0].versions @@ -307,11 +271,8 @@ def ReportVersions(hlist): EndReport() -def CompareESOBs(e1, e2): - return e2.sobs - e1.sobs - def ReportByESOBs(elist): - elist.sort(CompareESOBs) + elist.sort(key=lambda e: -e.sobs) totalsobs = 0 for e in elist: totalsobs += e.sobs @@ -325,11 +286,8 @@ def ReportByESOBs(elist): break EndReport() -def CompareHackers(e1, e2): - return len(e2.hackers) - len(e1.hackers) - def ReportByEHackers(elist): - elist.sort(CompareHackers) + elist.sort(key=lambda e: -len(e.hackers)) totalhackers = 0 for e in elist: totalhackers += len(e.hackers) @@ -375,7 +333,7 @@ def ReportUnknowns(hlist, cscount): # mapping to (Unknown) is happening or not. # ulist = [ h for h in hlist if IsUnknown(h) ] - ulist.sort(ComparePCount) + ulist.sort(lambda h: len(h.patches)) count = 0 BeginReport('Developers with unknown affiliation') for h in ulist: @@ -398,46 +356,46 @@ def ReportByFileType(hacker_list): by_hacker = {} for patch in h.patches: # Get a summary by hacker - for (filetype, (added, removed)) in patch.filetypes.iteritems(): - if by_hacker.has_key(filetype): + for (filetype, (added, removed)) in patch.filetypes.items(): + if filetype in by_hacker: by_hacker[filetype][patch.ADDED] += added by_hacker[filetype][patch.REMOVED] += removed else: by_hacker[filetype] = [added, removed] # Update the totals - if total.has_key(filetype): + if filetype in total: total[filetype][patch.ADDED] += added total[filetype][patch.REMOVED] += removed else: total[filetype] = [added, removed, []] # Print a summary by hacker - print h.name - for filetype, counters in by_hacker.iteritems(): - print '\t', filetype, counters + print(h.name) + for filetype, counters in by_hacker.items(): + print('\t', filetype, counters) h_added = by_hacker[filetype][patch.ADDED] h_removed = by_hacker[filetype][patch.REMOVED] total[filetype][2].append([h.name, h_added, h_removed]) # Print the global summary BeginReport('Contributions by type and developers') - for filetype, (added, removed, hackers) in total.iteritems(): - print filetype, added, removed + for filetype, (added, removed, hackers) in total.items(): + print(filetype, added, removed) for h, h_added, h_removed in hackers: - print '\t%s: [%d, %d]' % (h, h_added, h_removed) + print('\t%s: [%d, %d]' % (h, h_added, h_removed)) # Print the very global summary BeginReport('General contributions by type') - for filetype, (added, removed, hackers) in total.iteritems(): - print filetype, added, removed + for filetype, (added, removed, hackers) in total.items(): + print(filetype, added, removed) # # The file access report is a special beast. # def FileAccessReport(name, accesses, total): outf = open(name, 'w') - files = accesses.keys() + files = list(accesses.keys()) files.sort() for file in files: a = accesses[file] diff --git a/utils.py b/utils.py index 2b3be5d..9f17911 100644 --- a/utils.py +++ b/utils.py @@ -21,7 +21,7 @@ class accumulator: return default def append(self, key, item, unique = False): - if unique and self._data.has_key(key) and \ + if unique and key in self._data and \ item in self._data[key]: return try: @@ -30,7 +30,7 @@ class accumulator: self._data[key] = [item] def keys(self): - return self._data.keys() + return list(self._data.keys()) def __getitem__(self, key): return self._data[key]
This is the result of running 2to3 and manually converting the comparison functions to lambda expressions. Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> --- ConfigFile.py | 4 +- csvdump.py | 4 +- database.py | 22 +++++------ gitdm | 27 ++++++------- gitlog.py | 8 ++-- logparser.py | 6 +-- reports.py | 106 +++++++++++++++----------------------------------- utils.py | 4 +- 8 files changed, 70 insertions(+), 111 deletions(-)