← Back to team overview

launchpad-reviewers team mailing list archive

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

 

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

Commit message:
Correct remaining spelling of \-escapes

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

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

Use raw strings or double-\, depending on whether it's more convenient for '\n' to mean a newline character or the two characters '\' 'n'.  This fixes a number of DeprecationWarnings with Python >= 3.6.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:py3-raw-strings into launchpad:master.
diff --git a/database/schema/security.py b/database/schema/security.py
index b3bdbbf..254ad94 100755
--- a/database/schema/security.py
+++ b/database/schema/security.py
@@ -54,8 +54,8 @@ POSTGRES_ACL_MAP = {
 # PostgreSQL's putid emits an unquoted string if every character in the role
 # name isalnum or is _. Otherwise the name is enclosed in double quotes, and
 # any embedded double quotes are doubled.
-QUOTED_STRING_RE = '(?:([A-Za-z0-9_]+)|"([^"]*(?:""[^"]*)*)")?'
-ACLITEM_RE = re.compile('^%(qs)s=([\w*]*)/%(qs)s$' % {'qs': QUOTED_STRING_RE})
+QUOTED_STRING_RE = r'(?:([A-Za-z0-9_]+)|"([^"]*(?:""[^"]*)*)")?'
+ACLITEM_RE = re.compile(r'^%(qs)s=([\w*]*)/%(qs)s$' % {'qs': QUOTED_STRING_RE})
 
 
 def _split_postgres_aclitem(aclitem):
diff --git a/database/schema/upgrade.py b/database/schema/upgrade.py
index fa536ef..a6ddc0c 100755
--- a/database/schema/upgrade.py
+++ b/database/schema/upgrade.py
@@ -177,7 +177,7 @@ def get_patchlist(con):
         os.path.join(SCHEMA_DIR, 'patch-????-??-?.sql'))
     all_patch_files.sort()
     for patch_file in all_patch_files:
-        m = re.search('patch-(\d+)-(\d+)-(\d).sql$', patch_file)
+        m = re.search(r'patch-(\d+)-(\d+)-(\d).sql$', patch_file)
         if m is None:
             log.fatal('Invalid patch filename %s' % repr(patch_file))
             raise SystemExit(1)
diff --git a/lib/contrib/apachelog.py b/lib/contrib/apachelog.py
index 48a30d9..20c1a3c 100644
--- a/lib/contrib/apachelog.py
+++ b/lib/contrib/apachelog.py
@@ -148,7 +148,7 @@ class parser:
             
             self._names.append(self.alias(element))
             
-            subpattern = '(\S*)'
+            subpattern = r'(\S*)'
             
             if hasquotes:
                 if element == '%r' or findreferreragent.search(element):
diff --git a/lib/contrib/glock.py b/lib/contrib/glock.py
index d1ced09..fb835e2 100644
--- a/lib/contrib/glock.py
+++ b/lib/contrib/glock.py
@@ -101,7 +101,7 @@ class GlobalLock:
            std module msvcrt.locking(), because global lock is OK, but
            blocks also for 2 calls from the same thread!
     '''
-    RE_ERROR_MSG = re.compile ("^\[Errno ([0-9]+)\]")
+    RE_ERROR_MSG = re.compile (r"^\[Errno ([0-9]+)\]")
 
     def __init__(self, fpath, lockInitially=False, logger=None):
         ''' Creates (or opens) a global lock.
diff --git a/lib/lp/answers/browser/question.py b/lib/lp/answers/browser/question.py
index 491ff16..b039552 100644
--- a/lib/lp/answers/browser/question.py
+++ b/lib/lp/answers/browser/question.py
@@ -1187,7 +1187,7 @@ class SearchAllQuestionsView(SearchQuestionsView):
 
     display_target_column = True
     # Match contiguous digits, optionally prefixed with a '#'.
-    id_pattern = re.compile('^#?(\d+)$')
+    id_pattern = re.compile(r'^#?(\d+)$')
 
     @property
     def pageheading(self):
diff --git a/lib/lp/answers/tests/test_faq_webservice.py b/lib/lp/answers/tests/test_faq_webservice.py
index dc1e1e7..33ad24b 100644
--- a/lib/lp/answers/tests/test_faq_webservice.py
+++ b/lib/lp/answers/tests/test_faq_webservice.py
@@ -46,8 +46,9 @@ class TestFAQWebService(TestCaseWithFactory):
                     "title": Equals("Nothing works"),
                     "keywords": Equals("foo bar"),
                     "content": Equals("It is all broken."),
-                    "date_created": MatchesRegex("\d\d\d\d-\d\d-\d\dT.*"),
-                    "date_last_updated": MatchesRegex("\d\d\d\d-\d\d-\d\dT.*"),
+                    "date_created": MatchesRegex(r"\d\d\d\d-\d\d-\d\dT.*"),
+                    "date_last_updated": MatchesRegex(
+                        r"\d\d\d\d-\d\d-\d\dT.*"),
                     "last_updated_by_link": Contains(
                         "/devel/~%s" % faq.owner.name),
                     "target_link": Contains(
diff --git a/lib/lp/app/browser/launchpad.py b/lib/lp/app/browser/launchpad.py
index 4c1eb59..7388562 100644
--- a/lib/lp/app/browser/launchpad.py
+++ b/lib/lp/app/browser/launchpad.py
@@ -1012,7 +1012,7 @@ class LaunchpadRootNavigation(Navigation):
             return None
 
         # If the request is for a bug then redirect straight to that bug.
-        bug_match = re.match("/bugs/(\d+)$", self.request['PATH_INFO'])
+        bug_match = re.match(r"/bugs/(\d+)$", self.request['PATH_INFO'])
         if bug_match:
             bug_number = bug_match.group(1)
             bug_set = getUtility(IBugSet)
diff --git a/lib/lp/app/browser/root.py b/lib/lp/app/browser/root.py
index 0d47b6b..83aa4e5 100644
--- a/lib/lp/app/browser/root.py
+++ b/lib/lp/app/browser/root.py
@@ -477,7 +477,7 @@ class LaunchpadSearchView(LaunchpadFormView):
         return match.group(1)
 
     def _getNameToken(self, text):
-        """Return the search text as a Launchpad name.
+        r"""Return the search text as a Launchpad name.
 
         Launchpad names may contain ^[a-z0-9][a-z0-9\+\.\-]+$.
         See `valid_name_pattern`.
diff --git a/lib/lp/app/browser/stringformatter.py b/lib/lp/app/browser/stringformatter.py
index 638ebbd..f66bb43 100644
--- a/lib/lp/app/browser/stringformatter.py
+++ b/lib/lp/app/browser/stringformatter.py
@@ -199,12 +199,12 @@ def extract_bug_numbers(text):
     unique_bug_matches = dict()
 
     line_matches = re.finditer(
-        'LP:\s*(?P<buglist>(.+?[^,]))($|\n)', text,
+        r'LP:\s*(?P<buglist>(.+?[^,]))($|\n)', text,
         re.DOTALL | re.IGNORECASE)
 
     for line_match in line_matches:
         bug_matches = re.finditer(
-            '\s*((?P<bug>#(?P<bugnum>\d+)),?\s*)',
+            r'\s*((?P<bug>#(?P<bugnum>\d+)),?\s*)',
             line_match.group('buglist'))
 
         for bug_match in bug_matches:
@@ -467,7 +467,7 @@ class FormattersAPI:
             # 'leader' is the 'LP: ' bit at the beginning.
             bug_parts = []
             # Split the bug numbers into multiple bugs.
-            splitted = re.split("(,(?:\s|<br\s*/>)+)",
+            splitted = re.split(r"(,(?:\s|<br\s*/>)+)",
                     match.group("bugnumbers")) + [""]
             for bug_id, spacer in zip(splitted[::2], splitted[1::2]):
                 bug_parts.append(FormattersAPI._linkify_bug_number(
@@ -620,7 +620,7 @@ class FormattersAPI:
         \blp:(?:///|/)?
         (?P<branch>%(unreserved)s(?:%(unreserved)s|/)*)
       )
-    ''' % {'unreserved': "(?:[-a-zA-Z0-9._~%!$'()*+,;=]|&amp;|&\#x27;)"},
+    ''' % {'unreserved': r"(?:[-a-zA-Z0-9._~%!$'()*+,;=]|&amp;|&\#x27;)"},
                              re.IGNORECASE | re.VERBOSE)
 
     # There is various punctuation that can occur at the end of a link that
diff --git a/lib/lp/app/widgets/tests/test_popup.py b/lib/lp/app/widgets/tests/test_popup.py
index 346e7d7..95bfc9c 100644
--- a/lib/lp/app/widgets/tests/test_popup.py
+++ b/lib/lp/app/widgets/tests/test_popup.py
@@ -147,8 +147,8 @@ class TestVocabularyPickerWidget(TestCaseWithFactory):
         self.assertIn(
             "Y.DOM.byId('field.test_valid.item-suggestions')", markup)
         self.assertTextMatchesExpressionIgnoreWhitespace(
-            'Y.lp.app.picker.connect_select_menu\( '
-            'select_menu, text_input\);',
+            r'Y.lp.app.picker.connect_select_menu\( '
+            r'select_menu, text_input\);',
             markup)
 
     def test_widget_extra_buttons(self):
diff --git a/lib/lp/buildmaster/tests/test_manager.py b/lib/lp/buildmaster/tests/test_manager.py
index d9bbf9e..18e8379 100644
--- a/lib/lp/buildmaster/tests/test_manager.py
+++ b/lib/lp/buildmaster/tests/test_manager.py
@@ -1006,8 +1006,8 @@ class TestSlaveScannerWithoutDB(TestCase):
 
         with ExpectedException(
                 BuildDaemonIsolationError,
-                "Allegedly clean slave not idle "
-                "\(u'BuilderStatus.BUILDING' instead\)"):
+                r"Allegedly clean slave not idle "
+                r"\(u'BuilderStatus.BUILDING' instead\)"):
             yield scanner.scan()
         self.assertEqual(['status'], slave.call_log)
 
diff --git a/lib/lp/oci/browser/tests/test_ocirecipe.py b/lib/lp/oci/browser/tests/test_ocirecipe.py
index 0ab9a59..e22665d 100644
--- a/lib/lp/oci/browser/tests/test_ocirecipe.py
+++ b/lib/lp/oci/browser/tests/test_ocirecipe.py
@@ -817,7 +817,7 @@ class TestOCIRecipeView(BaseTestOCIRecipeView):
         build = self.makeBuild(
             status=BuildStatus.FULLYBUILT, duration=timedelta(minutes=30))
         build.setLog(self.factory.makeLibraryFileAlias())
-        self.assertTextMatchesExpressionIgnoreWhitespace("""\
+        self.assertTextMatchesExpressionIgnoreWhitespace(r"""\
             Latest builds
             Status When complete Architecture
             Successfully built 30 minutes ago buildlog \(.*\) 386
@@ -834,7 +834,7 @@ class TestOCIRecipeView(BaseTestOCIRecipeView):
         # A pending build is listed as such.
         build = self.makeBuild()
         build.queueBuild()
-        self.assertTextMatchesExpressionIgnoreWhitespace("""\
+        self.assertTextMatchesExpressionIgnoreWhitespace(r"""\
             Latest builds
             Status When complete Architecture
             Needs building in .* \(estimated\) 386
diff --git a/lib/lp/snappy/browser/tests/test_snap.py b/lib/lp/snappy/browser/tests/test_snap.py
index bbda603..33da319 100644
--- a/lib/lp/snappy/browser/tests/test_snap.py
+++ b/lib/lp/snappy/browser/tests/test_snap.py
@@ -1,3 +1,7 @@
+# -*- coding: utf-8 -*-
+# NOTE: The first line above must stay first; do not move the copyright
+# notice to the top.  See http://www.python.org/dev/peps/pep-0263/.
+#
 # Copyright 2015-2020 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
@@ -1424,13 +1428,13 @@ class TestSnapView(BaseTestSnapView):
         build = self.makeBuild(
             snap=snap, status=BuildStatus.FULLYBUILT,
             duration=timedelta(minutes=30))
-        self.assertTextMatchesExpressionIgnoreWhitespace("""\
+        self.assertTextMatchesExpressionIgnoreWhitespace(r"""\
             Snap packages snap-name
             .*
             Snap package information
             Owner: Test Person
             Distribution series: Ubuntu Shiny
-            Source: lp://dev/~test-person/\\+junk/snap-branch
+            Source: lp://dev/~test-person/\+junk/snap-branch
             Build source tarball: No
             Build schedule: \(\?\)
             Built on request
@@ -1452,13 +1456,13 @@ class TestSnapView(BaseTestSnapView):
         build = self.makeBuild(
             snap=snap, status=BuildStatus.FULLYBUILT,
             duration=timedelta(minutes=30))
-        self.assertTextMatchesExpressionIgnoreWhitespace("""\
+        self.assertTextMatchesExpressionIgnoreWhitespace(r"""\
             Snap packages snap-name
             .*
             Snap package information
             Owner: Test Person
             Distribution series: Ubuntu Shiny
-            Source: ~test-person/\\+git/snap-repository:master
+            Source: ~test-person/\+git/snap-repository:master
             Build source tarball: No
             Build schedule: \(\?\)
             Built on request
@@ -1480,7 +1484,7 @@ class TestSnapView(BaseTestSnapView):
         build = self.makeBuild(
             snap=snap, status=BuildStatus.FULLYBUILT,
             duration=timedelta(minutes=30))
-        self.assertTextMatchesExpressionIgnoreWhitespace("""\
+        self.assertTextMatchesExpressionIgnoreWhitespace(r"""\
             Snap packages snap-name
             .*
             Snap package information
@@ -1514,7 +1518,7 @@ class TestSnapView(BaseTestSnapView):
         build = self.makeBuild(
             status=BuildStatus.FULLYBUILT, duration=timedelta(minutes=30))
         build.setLog(self.factory.makeLibraryFileAlias())
-        self.assertTextMatchesExpressionIgnoreWhitespace("""\
+        self.assertTextMatchesExpressionIgnoreWhitespace(r"""\
             Latest builds
             Status When complete Architecture Archive
             Successfully built 30 minutes ago buildlog \(.*\) i386
@@ -1541,7 +1545,7 @@ class TestSnapView(BaseTestSnapView):
         # A pending build is listed as such.
         build = self.makeBuild()
         build.queueBuild()
-        self.assertTextMatchesExpressionIgnoreWhitespace("""\
+        self.assertTextMatchesExpressionIgnoreWhitespace(r"""\
             Latest builds
             Status When complete Architecture Archive
             Needs building in .* \(estimated\) i386
@@ -1573,7 +1577,7 @@ class TestSnapView(BaseTestSnapView):
         job.job._status = JobStatus.FAILED
         job.job.date_finished = datetime.now(pytz.UTC) - timedelta(hours=1)
         job.error_message = "Boom"
-        self.assertTextMatchesExpressionIgnoreWhitespace("""\
+        self.assertTextMatchesExpressionIgnoreWhitespace(r"""\
             Latest builds
             Status When complete Architecture Archive
             Failed build request 1 hour ago \(Boom\)
@@ -1761,7 +1765,7 @@ class TestSnapRequestBuildsView(BaseTestSnapView):
 
     def test_request_builds_page(self):
         # The +request-builds page is sane.
-        self.assertTextMatchesExpressionIgnoreWhitespace("""
+        self.assertTextMatchesExpressionIgnoreWhitespace(r"""
             Request builds for snap-name
             Snap packages
             snap-name
@@ -1769,7 +1773,7 @@ class TestSnapRequestBuildsView(BaseTestSnapView):
             Source archive:
             Primary Archive for Ubuntu Linux
             PPA
-            \(Find\u2026\)
+            \(Find…\)
             Architectures:
             amd64
             i386
diff --git a/lib/lp/snappy/browser/tests/test_snapbuild.py b/lib/lp/snappy/browser/tests/test_snapbuild.py
index 848aa0d..5d6b1b6 100644
--- a/lib/lp/snappy/browser/tests/test_snapbuild.py
+++ b/lib/lp/snappy/browser/tests/test_snapbuild.py
@@ -198,7 +198,7 @@ class TestSnapBuildView(TestCaseWithFactory):
                 soupmatchers.Within(
                     soupmatchers.Tag(
                         "store upload error message", "li",
-                        text=re.compile(".*Scan failed\..*")),
+                        text=re.compile(r".*Scan failed\..*")),
                     soupmatchers.Tag(
                         "store upload error link", "a",
                         attrs={"href": "link1"}, text="(?)")))))
@@ -210,7 +210,7 @@ class TestSnapBuildView(TestCaseWithFactory):
                 soupmatchers.Within(
                     soupmatchers.Tag(
                         "store upload error message", "li",
-                        text=re.compile(".*Classic not allowed\..*")),
+                        text=re.compile(r".*Classic not allowed\..*")),
                     soupmatchers.Tag(
                         "store upload error link", "a",
                         attrs={"href": "link2"}, text="(?)")))))
diff --git a/lib/lp/testing/pages.py b/lib/lp/testing/pages.py
index f0d37ed..161a241 100644
--- a/lib/lp/testing/pages.py
+++ b/lib/lp/testing/pages.py
@@ -238,7 +238,7 @@ def find_portlet(content, name):
     ending whitespace is also ignored, as are non-text elements such as
     images.
     """
-    whitespace_re = re.compile('\s+')
+    whitespace_re = re.compile(r'\s+')
     name = whitespace_re.sub(' ', name.strip())
     for portlet in find_tags_by_class(content, 'portlet'):
         if portlet.find('h2'):
@@ -439,7 +439,7 @@ def parse_relationship_section(content):
     """
     soup = BeautifulSoup(content)
     section = soup.find('ul')
-    whitespace_re = re.compile('\s+')
+    whitespace_re = re.compile(r'\s+')
     if section is None:
         print('EMPTY SECTION')
         return
diff --git a/lib/lp/testing/utilities/retest.py b/lib/lp/testing/utilities/retest.py
index 46906bc..740f063 100755
--- a/lib/lp/testing/utilities/retest.py
+++ b/lib/lp/testing/utilities/retest.py
@@ -39,10 +39,10 @@ from lp.services.config import config
 TEST = os.path.join(config.root, "bin/test")
 
 # Regular expression to match numbered stories.
-STORY_RE = re.compile("(.*)/\d{2}-.*")
+STORY_RE = re.compile(r"(.*)/\d{2}-.*")
 
 # Regular expression to remove terminal color escapes.
-COLOR_RE = re.compile("\x1b[[][0-9;]+m")
+COLOR_RE = re.compile(r"\x1b[[][0-9;]+m")
 
 
 def decolorize(text):
diff --git a/utilities/pglogwatch.py b/utilities/pglogwatch.py
index 23b727c..406089a 100755
--- a/utilities/pglogwatch.py
+++ b/utilities/pglogwatch.py
@@ -51,32 +51,32 @@ class Process(object):
 
 
 class Watcher(object):
-    _line_re = re.compile("""
+    _line_re = re.compile(r"""
         ^\d{4}-\d\d-\d\d \s \d\d:\d\d:\d\d \s 
         \[(?P<pid>\d+)\] \s (?P<type>LOG|ERROR|DETAIL): \s+ (?P<rest>.*)$
         """, re.X)
 
-    _statement_re = re.compile("""
+    _statement_re = re.compile(r"""
         ^statement: \s (?P<statement>.*)$
         """, re.X)
 
-    _duration_re = re.compile("""
+    _duration_re = re.compile(r"""
         ^duration: \s (?P<duration>\d+\.\d+) \s ms$
         """, re.X)
 
-    _connection_received_re = re.compile("""
+    _connection_received_re = re.compile(r"""
         ^connection \s received: \s+ (?P<connection>.*)$
         """, re.X)
 
-    _connection_authorized_re = re.compile("""
+    _connection_authorized_re = re.compile(r"""
         ^connection \s authorized: \s+ (?P<auth>.*)$
         """, re.X)
 
-    _ignored_rest_re = re.compile("""
+    _ignored_rest_re = re.compile(r"""
         ^(received \s | ERROR: \s | unexpected \s EOF \s) .*$
         """, re.X)
 
-    _ignored_statements_re = re.compile("""
+    _ignored_statements_re = re.compile(r"""
         ^(BEGIN.*|END)$
         """, re.X)