Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Lib/test/test_robotparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,19 @@ class DisallowQueryStringTest(BaseRobotTest, unittest.TestCase):
'/yet/one/path?name=value&more']


class CanFetchMalformedURLTest(unittest.TestCase):
def test_malformed_url_is_allowed(self):
# A URL that cannot be parsed matches no rule, so can_fetch() returns
# True (RFC 9309 default) rather than raising.
parser = urllib.robotparser.RobotFileParser()
parser.parse(['User-agent: *', 'Disallow: /'])
# The rule above disallows a well-formed path.
self.assertFalse(parser.can_fetch('*', '/x'))
# An unparsable URL is allowed, not raised.
self.assertTrue(parser.can_fetch('*', 'http://[::1'))
self.assertTrue(parser.can_fetch('*', 'http://['))


class PercentEncodingTest(BaseRobotTest, unittest.TestCase):
robots_txt = """\
User-agent: *
Expand Down
6 changes: 5 additions & 1 deletion Lib/urllib/robotparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,11 @@ def can_fetch(self, useragent, url):
return False
# TODO: The private API is used in order to preserve an empty query.
# This is temporary until the public API starts supporting this feature.
parsed_url = urllib.parse._urlsplit(url, '')
try:
parsed_url = urllib.parse._urlsplit(url, '')
except ValueError:
# A malformed URL matches no rule.
return True
url = urllib.parse._urlunsplit(None, None, *parsed_url[2:])
url = normalize_uri(url)
if not url:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:meth:`urllib.robotparser.RobotFileParser.can_fetch` no longer raises
:exc:`ValueError` for a malformed URL. Patch by tonghuaroot.
Loading