Issue #23563: Optimized utility functions in urllib.parse.

This commit is contained in:
Serhiy Storchaka 2015-03-03 20:21:35 +02:00
parent 87e691240b
commit 44eceb6e2a
2 changed files with 30 additions and 60 deletions

View File

@ -869,12 +869,12 @@ def splittype(url):
"""splittype('type:opaquestring') --> 'type', 'opaquestring'.""" """splittype('type:opaquestring') --> 'type', 'opaquestring'."""
global _typeprog global _typeprog
if _typeprog is None: if _typeprog is None:
_typeprog = re.compile('^([^/:]+):') _typeprog = re.compile('([^/:]+):(.*)', re.DOTALL)
match = _typeprog.match(url) match = _typeprog.match(url)
if match: if match:
scheme = match.group(1) scheme, data = match.groups()
return scheme.lower(), url[len(scheme) + 1:] return scheme.lower(), data
return None, url return None, url
_hostprog = None _hostprog = None
@ -882,38 +882,25 @@ def splithost(url):
"""splithost('//host[:port]/path') --> 'host[:port]', '/path'.""" """splithost('//host[:port]/path') --> 'host[:port]', '/path'."""
global _hostprog global _hostprog
if _hostprog is None: if _hostprog is None:
_hostprog = re.compile('^//([^/?]*)(.*)$') _hostprog = re.compile('//([^/?]*)(.*)', re.DOTALL)
match = _hostprog.match(url) match = _hostprog.match(url)
if match: if match:
host_port = match.group(1) host_port, path = match.groups()
path = match.group(2) if path and path[0] != '/':
if path and not path.startswith('/'):
path = '/' + path path = '/' + path
return host_port, path return host_port, path
return None, url return None, url
_userprog = None
def splituser(host): def splituser(host):
"""splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'."""
global _userprog user, delim, host = host.rpartition('@')
if _userprog is None: return (user if delim else None), host
_userprog = re.compile('^(.*)@(.*)$')
match = _userprog.match(host)
if match: return match.group(1, 2)
return None, host
_passwdprog = None
def splitpasswd(user): def splitpasswd(user):
"""splitpasswd('user:passwd') -> 'user', 'passwd'.""" """splitpasswd('user:passwd') -> 'user', 'passwd'."""
global _passwdprog user, delim, passwd = user.partition(':')
if _passwdprog is None: return user, (passwd if delim else None)
_passwdprog = re.compile('^([^:]*):(.*)$',re.S)
match = _passwdprog.match(user)
if match: return match.group(1, 2)
return user, None
# splittag('/path#tag') --> '/path', 'tag' # splittag('/path#tag') --> '/path', 'tag'
_portprog = None _portprog = None
@ -921,7 +908,7 @@ def splitport(host):
"""splitport('host:port') --> 'host', 'port'.""" """splitport('host:port') --> 'host', 'port'."""
global _portprog global _portprog
if _portprog is None: if _portprog is None:
_portprog = re.compile('^(.*):([0-9]*)$') _portprog = re.compile('(.*):([0-9]*)$', re.DOTALL)
match = _portprog.match(host) match = _portprog.match(host)
if match: if match:
@ -930,47 +917,34 @@ def splitport(host):
return host, port return host, port
return host, None return host, None
_nportprog = None
def splitnport(host, defport=-1): def splitnport(host, defport=-1):
"""Split host and port, returning numeric port. """Split host and port, returning numeric port.
Return given default port if no ':' found; defaults to -1. Return given default port if no ':' found; defaults to -1.
Return numerical port if a valid number are found after ':'. Return numerical port if a valid number are found after ':'.
Return None if ':' but not a valid number.""" Return None if ':' but not a valid number."""
global _nportprog host, delim, port = host.rpartition(':')
if _nportprog is None: if not delim:
_nportprog = re.compile('^(.*):(.*)$') host = port
elif port:
match = _nportprog.match(host) try:
if match: nport = int(port)
host, port = match.group(1, 2) except ValueError:
if port: nport = None
try: return host, nport
nport = int(port)
except ValueError:
nport = None
return host, nport
return host, defport return host, defport
_queryprog = None
def splitquery(url): def splitquery(url):
"""splitquery('/path?query') --> '/path', 'query'.""" """splitquery('/path?query') --> '/path', 'query'."""
global _queryprog path, delim, query = url.rpartition('?')
if _queryprog is None: if delim:
_queryprog = re.compile('^(.*)\?([^?]*)$') return path, query
match = _queryprog.match(url)
if match: return match.group(1, 2)
return url, None return url, None
_tagprog = None
def splittag(url): def splittag(url):
"""splittag('/path#tag') --> '/path', 'tag'.""" """splittag('/path#tag') --> '/path', 'tag'."""
global _tagprog path, delim, tag = url.rpartition('#')
if _tagprog is None: if delim:
_tagprog = re.compile('^(.*)#([^#]*)$') return path, tag
match = _tagprog.match(url)
if match: return match.group(1, 2)
return url, None return url, None
def splitattr(url): def splitattr(url):
@ -979,13 +953,7 @@ def splitattr(url):
words = url.split(';') words = url.split(';')
return words[0], words[1:] return words[0], words[1:]
_valueprog = None
def splitvalue(attr): def splitvalue(attr):
"""splitvalue('attr=value') --> 'attr', 'value'.""" """splitvalue('attr=value') --> 'attr', 'value'."""
global _valueprog attr, delim, value = attr.partition('=')
if _valueprog is None: return attr, (value if delim else None)
_valueprog = re.compile('^([^=]*)=(.*)$')
match = _valueprog.match(attr)
if match: return match.group(1, 2)
return attr, None

View File

@ -13,6 +13,8 @@ Core and Builtins
Library Library
------- -------
- Issue #23563: Optimized utility functions in urllib.parse.
- Issue #7830: Flatten nested functools.partial. - Issue #7830: Flatten nested functools.partial.
- Issue #20204: Added the __module__ attribute to _tkinter classes. - Issue #20204: Added the __module__ attribute to _tkinter classes.