← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:py3-services-raw-strings into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:py3-services-raw-strings into launchpad:master.

Commit message:
Use raw strings where necessary for \-escapes in lp.services

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/392040

This fixes a number of DeprecationWarnings with Python >= 3.6.  The only slight oddity was in TestTwistedJobRunner, since backslash-newline line continuations don't work in raw strings.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3-services-raw-strings into launchpad:master.
diff --git a/lib/lp/services/browser_helpers.py b/lib/lp/services/browser_helpers.py
index 617f4c4..f010205 100644
--- a/lib/lp/services/browser_helpers.py
+++ b/lib/lp/services/browser_helpers.py
@@ -19,7 +19,7 @@ def get_user_agent_distroseries(user_agent_string):
         return None
 
     # We're matching on the Ubuntu/10.09 section of the user-agent string.
-    pattern = 'Ubuntu/(?P<version>\d*\.\d*)'
+    pattern = r'Ubuntu/(?P<version>\d*\.\d*)'
     match = re.search(pattern, user_agent_string)
 
     if match is not None:
diff --git a/lib/lp/services/database/postgresql.py b/lib/lp/services/database/postgresql.py
index 967a5a8..a3fae61 100644
--- a/lib/lp/services/database/postgresql.py
+++ b/lib/lp/services/database/postgresql.py
@@ -217,7 +217,7 @@ def listSequences(cur):
     rv = []
     cur.execute(sql)
     for schema, sequence in list(cur.fetchall()):
-        match = re.search('^(\w+)_(\w+)_seq$', sequence)
+        match = re.search(r'^(\w+)_(\w+)_seq$', sequence)
         if match is None:
             rv.append((schema, sequence, None, None))
         else:
@@ -308,7 +308,7 @@ def resetSequences(cur):
         cur.execute(sql)
 
 # Regular expression used to parse row count estimate from EXPLAIN output
-_rows_re = re.compile("rows=(\d+)\swidth=")
+_rows_re = re.compile(r"rows=(\d+)\swidth=")
 
 
 def estimateRowCount(cur, query):
diff --git a/lib/lp/services/database/sort_sql.py b/lib/lp/services/database/sort_sql.py
index e43b727..360e5a4 100644
--- a/lib/lp/services/database/sort_sql.py
+++ b/lib/lp/services/database/sort_sql.py
@@ -116,7 +116,7 @@ class Parser:
         if not self.is_complete_insert_statement(line):
             raise ValueError("Incomplete line")
 
-        insert_pattern = re.compile('''
+        insert_pattern = re.compile(r'''
             ^INSERT \s+ INTO \s+ \S+ \s+ \([^)]+\) \s+ VALUES \s+ \((\d+)
             ''', re.X)
         match = insert_pattern.match(line)
diff --git a/lib/lp/services/fields/__init__.py b/lib/lp/services/fields/__init__.py
index 9ad33f6..9224282 100644
--- a/lib/lp/services/fields/__init__.py
+++ b/lib/lp/services/fields/__init__.py
@@ -111,10 +111,11 @@ from lp.services.webapp.interfaces import ILaunchBag
 # Marker object to tell BaseImageUpload to keep the existing image.
 KEEP_SAME_IMAGE = object()
 # Regexp for detecting milestone headers in work items text.
-MILESTONE_RE = re.compile('^work items(.*)\s*:\s*$', re.I)
+MILESTONE_RE = re.compile(r'^work items(.*)\s*:\s*$', re.I)
 # Regexp for work items.
 WORKITEM_RE = re.compile(
-    '^(\[(?P<assignee>.*?)\])?\s*(?P<title>.*)\s*:\s*(?P<status>.*)\s*$', re.I)
+    r'^(\[(?P<assignee>.*?)\])?\s*(?P<title>.*)\s*:\s*(?P<status>.*)\s*$',
+    re.I)
 
 
 # Field Interfaces
diff --git a/lib/lp/services/httpproxy/connect_tunneling.py b/lib/lp/services/httpproxy/connect_tunneling.py
index 96d49e6..59a542c 100644
--- a/lib/lp/services/httpproxy/connect_tunneling.py
+++ b/lib/lp/services/httpproxy/connect_tunneling.py
@@ -29,7 +29,7 @@ class TunnelingTCP4ClientEndpoint(TCP4ClientEndpoint):
     To accomplish that, this endpoint sends an HTTP CONNECT to the proxy.
     """
 
-    _responseMatcher = re.compile('HTTP/1\.. 200')
+    _responseMatcher = re.compile(r'HTTP/1\.. 200')
 
     def __init__(self, reactor, host, port, proxyConf, contextFactory,
                  timeout=30, bindAddress=None):
diff --git a/lib/lp/services/job/tests/test_runner.py b/lib/lp/services/job/tests/test_runner.py
index 3e2e19d..9827f1c 100644
--- a/lib/lp/services/job/tests/test_runner.py
+++ b/lib/lp/services/job/tests/test_runner.py
@@ -656,12 +656,12 @@ class TestTwistedJobRunner(TestCaseWithFactory):
         expected_exception = ('TimeoutError', 'Job ran too long.')
         self.assertEqual(expected_exception, (oops['type'], oops['value']))
         self.assertThat(logger.getLogBuffer(), MatchesRegex(
-            dedent("""\
+            dedent(r"""
                 INFO Running through Twisted.
                 INFO Running <StuckJob.*?> \(ID .*?\).
                 INFO Running <StuckJob.*?> \(ID .*?\).
                 INFO Job resulted in OOPS: .*
-            """)))
+            """).lstrip("\n")))
 
     # XXX: BradCrittenden 2012-05-09 bug=994777: Disabled as a spurious
     # failure.  In isolation this test fails 5% of the time.
@@ -685,12 +685,12 @@ class TestTwistedJobRunner(TestCaseWithFactory):
             (1, 1), (len(runner.completed_jobs), len(runner.incomplete_jobs)))
         self.assertThat(
             logger.getLogBuffer(), MatchesRegex(
-                dedent("""\
+                dedent(r"""
                 INFO Running through Twisted.
                 INFO Running <ShorterStuckJob.*?> \(ID .*?\).
                 INFO Running <ShorterStuckJob.*?> \(ID .*?\).
                 INFO Job resulted in OOPS: %s
-                """) % oops['id']))
+                """).lstrip("\n") % oops['id']))
         self.assertEqual(('TimeoutError', 'Job ran too long.'),
                          (oops['type'], oops['value']))
 
diff --git a/lib/lp/services/librarianserver/librariangc.py b/lib/lp/services/librarianserver/librariangc.py
index a16e769..3072629 100644
--- a/lib/lp/services/librarianserver/librariangc.py
+++ b/lib/lp/services/librarianserver/librariangc.py
@@ -639,7 +639,7 @@ def delete_unwanted_disk_files(con):
     removed_count = 0
     content_id = next_wanted_content_id = -1
 
-    hex_content_id_re = re.compile('^([0-9a-f]{8})(\.migrated)?$')
+    hex_content_id_re = re.compile(r'^([0-9a-f]{8})(\.migrated)?$')
     ONE_DAY = 24 * 60 * 60
 
     for dirpath, dirnames, filenames in scandir.walk(
diff --git a/lib/lp/services/mail/helpers.py b/lib/lp/services/mail/helpers.py
index 21ced5b..4ed4b95 100644
--- a/lib/lp/services/mail/helpers.py
+++ b/lib/lp/services/mail/helpers.py
@@ -88,16 +88,16 @@ def reformat_wiki_text(text):
     # This implementation is neither correct nor complete.
 
     # Strip macros (anchors, TOC, etc'...)
-    re_macro = re.compile('\[\[.*?\]\]')
+    re_macro = re.compile(r'\[\[.*?\]\]')
     text = re_macro.sub('', text)
 
     # sterilize links
-    re_link = re.compile('\[(.*?)\]')
+    re_link = re.compile(r'\[(.*?)\]')
     text = re_link.sub(
         lambda match: ' '.join(match.group(1).split(' ')[1:]), text)
 
     # Strip comments
-    re_comment = re.compile('^#.*?$', re.MULTILINE)
+    re_comment = re.compile(r'^#.*?$', re.MULTILINE)
     text = re_comment.sub('', text)
 
     return text
diff --git a/lib/lp/services/mail/notification.py b/lib/lp/services/mail/notification.py
index adf0f95..827cdf9 100644
--- a/lib/lp/services/mail/notification.py
+++ b/lib/lp/services/mail/notification.py
@@ -113,7 +113,7 @@ def get_unified_diff(old_text, new_text, text_width):
         if not diff_line.startswith('?')]
     # Add a whitespace between the +/- and the text line.
     text_diff = [
-        re.sub('^([\+\- ])(.*)', r'\1 \2', line)
+        re.sub(r'^([\+\- ])(.*)', r'\1 \2', line)
         for line in text_diff]
     text_diff = '\n'.join(text_diff)
     return text_diff
diff --git a/lib/lp/services/oauth/model.py b/lib/lp/services/oauth/model.py
index 0559bb9..1ecb188 100644
--- a/lib/lp/services/oauth/model.py
+++ b/lib/lp/services/oauth/model.py
@@ -126,7 +126,7 @@ class OAuthConsumer(OAuthBase, StormBase):
     #  - A Mac OS X computer called "hostname"
     #    (Presumably an iPhone will also send this string,
     #     but we're not sure.)
-    integrated_desktop_re = re.compile("^System-wide: (.*) \(([^)]*)\)$")
+    integrated_desktop_re = re.compile(r"^System-wide: (.*) \(([^)]*)\)$")
 
     def _integrated_desktop_match_group(self, position):
         """Return information about a desktop integration token.
diff --git a/lib/lp/services/profile/profile.py b/lib/lp/services/profile/profile.py
index e38de21..85e98f1 100644
--- a/lib/lp/services/profile/profile.py
+++ b/lib/lp/services/profile/profile.py
@@ -583,7 +583,7 @@ _condition_functions = {
     'INCLUDES': _make_includes
     }
 
-_normalize_whitespace = partial(re.compile('\s+').sub, ' ')
+_normalize_whitespace = partial(re.compile(r'\s+').sub, ' ')
 
 
 def _make_condition_function(condition_string):
diff --git a/lib/lp/services/utils.py b/lib/lp/services/utils.py
index dc15176..1d481d4 100644
--- a/lib/lp/services/utils.py
+++ b/lib/lp/services/utils.py
@@ -403,5 +403,5 @@ def sanitise_urls(s):
     example).  This function removes them.
     """
     # Remove credentials from URLs.
-    password_re = re.compile('://([^:@/]*:[^@/]*@)(\S+)')
+    password_re = re.compile(r'://([^:@/]*:[^@/]*@)(\S+)')
     return password_re.sub(r'://<redacted>@\2', s)
diff --git a/lib/lp/services/webapp/adapter.py b/lib/lp/services/webapp/adapter.py
index 727aafc..24620b3 100644
--- a/lib/lp/services/webapp/adapter.py
+++ b/lib/lp/services/webapp/adapter.py
@@ -665,7 +665,7 @@ class LaunchpadTimeoutTracer(PostgresTimeoutTracer):
 class LaunchpadStatementTracer:
     """Storm tracer class to log executed statements."""
 
-    _normalize_whitespace = partial(re.compile('\s+').sub, ' ')
+    _normalize_whitespace = partial(re.compile(r'\s+').sub, ' ')
 
     def __init__(self):
         self._debug_sql = bool(os.environ.get('LP_DEBUG_SQL'))
diff --git a/lib/lp/services/webapp/batching.py b/lib/lp/services/webapp/batching.py
index 2eb6522..925515b 100644
--- a/lib/lp/services/webapp/batching.py
+++ b/lib/lp/services/webapp/batching.py
@@ -625,7 +625,7 @@ class StormRangeFactory:
             *columns)
         explain = 'EXPLAIN ' + convert_storm_clause_to_string(select)
         result = ISlaveStore(LibraryFileAlias).execute(explain)
-        _rows_re = re.compile("rows=(\d+)\swidth=")
+        _rows_re = re.compile(r"rows=(\d+)\swidth=")
         first_line = result.get_one()[0]
         match = _rows_re.search(first_line)
         if match is None:
diff --git a/lib/lp/services/webapp/sorting.py b/lib/lp/services/webapp/sorting.py
index 72d04dc..dc1a453 100644
--- a/lib/lp/services/webapp/sorting.py
+++ b/lib/lp/services/webapp/sorting.py
@@ -30,7 +30,7 @@ def expand_numbers(unicode_text, fill_digits=4):
 
     def substitute_filled_numbers(match):
         return match.group(0).zfill(fill_digits)
-    return re.sub(u'\d+', substitute_filled_numbers, unicode_text)
+    return re.sub(r'\d+', substitute_filled_numbers, unicode_text)
 
 
 # Create translation table for numeric ordinals to their
diff --git a/lib/lp/services/webhooks/tests/test_job.py b/lib/lp/services/webhooks/tests/test_job.py
index a395b53..7f794e0 100644
--- a/lib/lp/services/webhooks/tests/test_job.py
+++ b/lib/lp/services/webhooks/tests/test_job.py
@@ -154,7 +154,7 @@ class TestWebhookClient(TestCase):
     def sendToWebhook(self, body='Content', **kwargs):
         with responses.RequestsMock() as requests_mock:
             requests_mock.add(
-                'POST', re.compile('^http://example\.com/'), body=body,
+                'POST', re.compile(r'^http://example\.com/'), body=body,
                 **kwargs)
             result = WebhookClient().deliver(
                 'http://example.com/ep', 'http://squid.example.com:3128',