launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #24926
[Merge] ~cjwatson/launchpad:py3-profile into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:py3-profile into launchpad:master.
Commit message:
Port lp.services.profile to Python 3
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/386528
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3-profile into launchpad:master.
diff --git a/lib/lp/services/profile/mem.py b/lib/lp/services/profile/mem.py
index 73ea820..42deda6 100644
--- a/lib/lp/services/profile/mem.py
+++ b/lib/lp/services/profile/mem.py
@@ -16,6 +16,8 @@ and improve APIs as needed.
"""
+from __future__ import absolute_import, print_function
+
__metatype__ = type
__all__ = [
'classesWithMostRefs',
@@ -94,15 +96,15 @@ def dump_garbage():
"""
# force collection
- print "\nGARBAGE:"
+ print("\nGARBAGE:")
gc.collect()
- print "\nGARBAGE OBJECTS:"
+ print("\nGARBAGE OBJECTS:")
for x in gc.garbage:
s = str(x)
if len(s) > 80:
s = s[:80]
- print type(x), "\n ", s
+ print(type(x), "\n ", s)
# This is spiv's reference count code, under 'MIT Licence if I'm pressed'.
@@ -183,7 +185,7 @@ def deltaCounts(counts1, counts2, n=30):
def printCounts(counts, file=None):
for c, obj in counts:
if file is None:
- print c, obj
+ print(c, obj)
else:
file.write("%s %s\n" % (c, obj))
diff --git a/lib/lp/services/profile/profile.py b/lib/lp/services/profile/profile.py
index 400f96e..e38de21 100644
--- a/lib/lp/services/profile/profile.py
+++ b/lib/lp/services/profile/profile.py
@@ -18,11 +18,11 @@ import heapq
import os
import pstats
import re
-import StringIO
import sys
import threading
from breezy import lsprof
+import six
import oops_datedir_repo.serializer_rfc822
from zope.component import (
adapter,
@@ -339,13 +339,14 @@ def end_request(event):
if is_html and 'show' in actions:
# Generate rfc822 OOPS result (might be nice to have an html
# serializer..).
- template_context['oops'] = ''.join(
- oops_datedir_repo.serializer_rfc822.to_chunks(oops_report))
+ template_context['oops'] = b''.join(
+ oops_datedir_repo.serializer_rfc822.to_chunks(
+ oops_report)).decode('UTF-8', 'replace')
# Generate profile summaries.
prof_stats.strip_dirs()
for name in ('time', 'cumulative', 'calls'):
prof_stats.sort(name)
- f = StringIO.StringIO()
+ f = six.StringIO()
prof_stats.pprint(file=f)
template_context[name] = f.getvalue()
template_context['profile_count'] = prof_stats.count
@@ -457,9 +458,8 @@ def end_request(event):
rank=step['python_rank'],
cls=step['python_class']))
# Identify the repeated Python calls that generated SQL.
- triggers = triggers.items()
- triggers.sort(key=lambda x: len(x[1]))
- triggers.reverse()
+ triggers = sorted(
+ triggers.items(), key=lambda x: len(x[1]), reverse=True)
top_triggers = []
for (key, ixs) in triggers:
if len(ixs) == 1:
@@ -491,11 +491,12 @@ def end_request(event):
except Exception:
error = ''.join(format_exception(*sys.exc_info(), as_html=True))
added_html = (
- '<div class="profiling_info">' + error + '</div>')
+ '<div class="profiling_info">' + error +
+ '</div>').encode(encoding)
existing_html = request.response.consumeBody()
e_start, e_close_body, e_end = existing_html.rpartition(
- '</body>')
- new_html = ''.join(
+ b'</body>')
+ new_html = b''.join(
(e_start, added_html, e_close_body, e_end))
request.response.setResult(new_html)
diff --git a/lib/lp/services/profile/profiling.txt b/lib/lp/services/profile/profiling.txt
index 844698b..7ba0ac7 100644
--- a/lib/lp/services/profile/profiling.txt
+++ b/lib/lp/services/profile/profiling.txt
@@ -72,7 +72,7 @@ When the environment isn't set, no profile is created.
>>> del os.environ['PROFILE_PAGETESTS_REQUESTS']
>>> PageTestLayer.setUp()
- >>> print PageTestLayer.profiler
+ >>> print(PageTestLayer.profiler)
None
And no stats file is written when the layer is torn down.
@@ -123,7 +123,7 @@ The feature has two modes.
smoke test. The unit tests verify further functionality.
>>> response = http('GET /++profile++ HTTP/1.0')
- >>> '<h1>Profiling Information</h1>' in response.getBody()
+ >>> b'<h1>Profiling Information</h1>' in response.getBody()
True
- It can be configured to profile all requests, indiscriminately. To turn
@@ -199,11 +199,11 @@ log file.
... (timestamp, page_id, oops_id, duration,
... start_vss, start_rss, end_vss, end_rss) = (
... memory_profile_fh.readline().split())
- >>> print timestamp
+ >>> print(timestamp)
20...
- >>> print oops_id
+ >>> print(oops_id)
-
- >>> print page_id
+ >>> print(page_id)
RootObject:index.html
.. ReST comment: this is clean up for the work done above.
diff --git a/lib/lp/services/profile/tests.py b/lib/lp/services/profile/tests.py
index 5bfcd81..b299a83 100644
--- a/lib/lp/services/profile/tests.py
+++ b/lib/lp/services/profile/tests.py
@@ -394,7 +394,7 @@ class BaseRequestEndHandlerTest(BaseTest):
def getAddedResponse(self, request,
start=EXAMPLE_HTML_START, end=EXAMPLE_HTML_END):
- output = request.response.consumeBody()
+ output = request.response.consumeBody().decode('UTF-8')
return output[len(start):-len(end)]
def getMemoryLog(self):
@@ -590,7 +590,7 @@ class TestBothProfilersRequestEndHandler(BaseRequestEndHandlerTest):
# to verify that these two files are different.
data = []
for filename in self.getAllProfilePaths():
- with open(filename) as f:
+ with open(filename, 'rb') as f:
data.append(f.read())
self.assertEqual(2, len(data))
self.assertNotEqual(data[0], data[1])
@@ -797,7 +797,8 @@ def test_suite():
suite = unittest.TestSuite()
doctest = LayeredDocFileSuite(
- './profiling.txt', setUp=setUp, tearDown=tearDown,
+ './profiling.txt',
+ setUp=lambda test: setUp(test, future=True), tearDown=tearDown,
layer=LaunchpadFunctionalLayer, stdout_logging_level=logging.WARNING)
suite.addTest(doctest)
suite.addTest(unittest.TestLoader().loadTestsFromName(__name__))