]> granicus.if.org Git - python/commitdiff
bpo-32861: urllib.robotparser fix incomplete __str__ methods. (GH-5711)
authorMichael Lazar <lazar.michael22@gmail.com>
Mon, 14 May 2018 14:10:41 +0000 (10:10 -0400)
committerSerhiy Storchaka <storchaka@gmail.com>
Mon, 14 May 2018 14:10:41 +0000 (17:10 +0300)
The urllib.robotparser's __str__ representation now includes wildcard
entries and the "Crawl-delay" and "Request-rate" fields. Also removes extra
newlines that were being appended to the end of the string.

Lib/test/test_robotparser.py
Lib/urllib/robotparser.py
Misc/NEWS.d/next/Library/2018-04-02-20-44-54.bpo-32861.HeBjzN.rst [new file with mode: 0644]

index 75198b70ad4ff5fc04eaf2d56860cb3abb6ca258..bee8d238be6b2fa0e2f2184ee7041059fed72372 100644 (file)
@@ -246,6 +246,32 @@ Disallow: /cyberworld/map/
     bad = ['/cyberworld/map/index.html']
 
 
+class StringFormattingTest(BaseRobotTest, unittest.TestCase):
+    robots_txt = """\
+User-agent: *
+Crawl-delay: 1
+Request-rate: 3/15
+Disallow: /cyberworld/map/ # This is an infinite virtual URL space
+
+# Cybermapper knows where to go.
+User-agent: cybermapper
+Disallow: /some/path
+    """
+
+    expected_output = """\
+User-agent: cybermapper
+Disallow: /some/path
+
+User-agent: *
+Crawl-delay: 1
+Request-rate: 3/15
+Disallow: /cyberworld/map/\
+"""
+
+    def test_string_formatting(self):
+        self.assertEqual(str(self.parser), self.expected_output)
+
+
 class RobotHandler(BaseHTTPRequestHandler):
 
     def do_GET(self):
index daac29c68dc36d2c771ae2a8f13b07aa36a4b2c9..92e4efe6865e1f82e45dbfb27bb213e16011ec7a 100644 (file)
@@ -190,7 +190,10 @@ class RobotFileParser:
         return self.default_entry.req_rate
 
     def __str__(self):
-        return ''.join([str(entry) + "\n" for entry in self.entries])
+        entries = self.entries
+        if self.default_entry is not None:
+            entries = entries + [self.default_entry]
+        return '\n\n'.join(map(str, entries))
 
 
 class RuleLine:
@@ -222,10 +225,14 @@ class Entry:
     def __str__(self):
         ret = []
         for agent in self.useragents:
-            ret.extend(["User-agent: ", agent, "\n"])
-        for line in self.rulelines:
-            ret.extend([str(line), "\n"])
-        return ''.join(ret)
+            ret.append(f"User-agent: {agent}")
+        if self.delay is not None:
+            ret.append(f"Crawl-delay: {self.delay}")
+        if self.req_rate is not None:
+            rate = self.req_rate
+            ret.append(f"Request-rate: {rate.requests}/{rate.seconds}")
+        ret.extend(map(str, self.rulelines))
+        return '\n'.join(ret)
 
     def applies_to(self, useragent):
         """check if this entry applies to the specified agent"""
diff --git a/Misc/NEWS.d/next/Library/2018-04-02-20-44-54.bpo-32861.HeBjzN.rst b/Misc/NEWS.d/next/Library/2018-04-02-20-44-54.bpo-32861.HeBjzN.rst
new file mode 100644 (file)
index 0000000..2bb24d7
--- /dev/null
@@ -0,0 +1,4 @@
+The urllib.robotparser's ``__str__`` representation now includes wildcard
+entries and the "Crawl-delay" and "Request-rate" fields. Also removes extra
+newlines that were being appended to the end of the string. Patch by
+Michael Lazar.