mirror of
https://github.com/python/cpython.git
synced 2025-12-09 02:35:14 +00:00
Fix [ #465502 ] urllib2: urlopen unicode problem
When checking for strings use, ! if isinstance(uri, (types.StringType, types.UnicodeType)): Also get rid of some dodgy code that tried to guess whether attributes were callable or not.
This commit is contained in:
parent
2f6a0b00a0
commit
8b78b99647
1 changed files with 35 additions and 66 deletions
|
|
@ -89,6 +89,7 @@ f = urllib2.urlopen('http://www.python.org/')
|
||||||
|
|
||||||
import socket
|
import socket
|
||||||
import httplib
|
import httplib
|
||||||
|
import inspect
|
||||||
import re
|
import re
|
||||||
import base64
|
import base64
|
||||||
import types
|
import types
|
||||||
|
|
@ -252,7 +253,7 @@ class OpenerDirector:
|
||||||
|
|
||||||
def add_handler(self, handler):
|
def add_handler(self, handler):
|
||||||
added = 0
|
added = 0
|
||||||
for meth in get_methods(handler):
|
for meth in dir(handler):
|
||||||
if meth[-5:] == '_open':
|
if meth[-5:] == '_open':
|
||||||
protocol = meth[:-5]
|
protocol = meth[:-5]
|
||||||
if self.handle_open.has_key(protocol):
|
if self.handle_open.has_key(protocol):
|
||||||
|
|
@ -303,7 +304,7 @@ class OpenerDirector:
|
||||||
|
|
||||||
def open(self, fullurl, data=None):
|
def open(self, fullurl, data=None):
|
||||||
# accept a URL or a Request object
|
# accept a URL or a Request object
|
||||||
if isinstance(fullurl, types.StringType):
|
if isinstance(fullurl, (types.StringType, types.UnicodeType)):
|
||||||
req = Request(fullurl, data)
|
req = Request(fullurl, data)
|
||||||
else:
|
else:
|
||||||
req = fullurl
|
req = fullurl
|
||||||
|
|
@ -346,34 +347,6 @@ class OpenerDirector:
|
||||||
args = (dict, 'default', 'http_error_default') + orig_args
|
args = (dict, 'default', 'http_error_default') + orig_args
|
||||||
return self._call_chain(*args)
|
return self._call_chain(*args)
|
||||||
|
|
||||||
def is_callable(obj):
|
|
||||||
# not quite like builtin callable (which I didn't know existed),
|
|
||||||
# not entirely sure it needs to be different
|
|
||||||
if type(obj) in (types.BuiltinFunctionType,
|
|
||||||
types.BuiltinMethodType, types.LambdaType,
|
|
||||||
types.MethodType):
|
|
||||||
return 1
|
|
||||||
if isinstance(obj, types.InstanceType):
|
|
||||||
return hasattr(obj, '__call__')
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def get_methods(inst):
|
|
||||||
methods = {}
|
|
||||||
classes = []
|
|
||||||
classes.append(inst.__class__)
|
|
||||||
while classes:
|
|
||||||
klass = classes[0]
|
|
||||||
del classes[0]
|
|
||||||
classes = classes + list(klass.__bases__)
|
|
||||||
for name in dir(klass):
|
|
||||||
attr = getattr(klass, name)
|
|
||||||
if isinstance(attr, types.UnboundMethodType):
|
|
||||||
methods[name] = 1
|
|
||||||
for name in dir(inst):
|
|
||||||
if is_callable(getattr(inst, name)):
|
|
||||||
methods[name] = 1
|
|
||||||
return methods.keys()
|
|
||||||
|
|
||||||
# XXX probably also want an abstract factory that knows things like
|
# XXX probably also want an abstract factory that knows things like
|
||||||
# the fact that a ProxyHandler needs to get inserted first.
|
# the fact that a ProxyHandler needs to get inserted first.
|
||||||
# would also know when it makes sense to skip a superclass in favor of
|
# would also know when it makes sense to skip a superclass in favor of
|
||||||
|
|
@ -399,11 +372,10 @@ def build_opener(*handlers):
|
||||||
skip = []
|
skip = []
|
||||||
for klass in default_classes:
|
for klass in default_classes:
|
||||||
for check in handlers:
|
for check in handlers:
|
||||||
if isinstance(check, types.ClassType):
|
if inspect.isclass(check):
|
||||||
if issubclass(check, klass):
|
if issubclass(check, klass):
|
||||||
skip.append(klass)
|
skip.append(klass)
|
||||||
elif isinstance(check, types.InstanceType):
|
elif isinstance(check, klass):
|
||||||
if isinstance(check, klass):
|
|
||||||
skip.append(klass)
|
skip.append(klass)
|
||||||
for klass in skip:
|
for klass in skip:
|
||||||
default_classes.remove(klass)
|
default_classes.remove(klass)
|
||||||
|
|
@ -412,7 +384,7 @@ def build_opener(*handlers):
|
||||||
opener.add_handler(klass())
|
opener.add_handler(klass())
|
||||||
|
|
||||||
for h in handlers:
|
for h in handlers:
|
||||||
if isinstance(h, types.ClassType):
|
if inspect.isclass(h):
|
||||||
h = h()
|
h = h()
|
||||||
opener.add_handler(h)
|
opener.add_handler(h)
|
||||||
return opener
|
return opener
|
||||||
|
|
@ -545,7 +517,7 @@ class HTTPPasswordMgr:
|
||||||
|
|
||||||
def add_password(self, realm, uri, user, passwd):
|
def add_password(self, realm, uri, user, passwd):
|
||||||
# uri could be a single URI or a sequence
|
# uri could be a single URI or a sequence
|
||||||
if isinstance(uri, types.StringType):
|
if isinstance(uri, (types.StringType, types.UnicodeType)):
|
||||||
uri = [uri]
|
uri = [uri]
|
||||||
uri = tuple(map(self.reduce_uri, uri))
|
uri = tuple(map(self.reduce_uri, uri))
|
||||||
if not self.passwd.has_key(realm):
|
if not self.passwd.has_key(realm):
|
||||||
|
|
@ -1067,7 +1039,7 @@ class OpenerFactory:
|
||||||
def build_opener(self):
|
def build_opener(self):
|
||||||
opener = OpenerDirector()
|
opener = OpenerDirector()
|
||||||
for ph in self.proxy_handlers:
|
for ph in self.proxy_handlers:
|
||||||
if isinstance(ph, types.ClassType):
|
if inspect.isclass(ph):
|
||||||
ph = ph()
|
ph = ph()
|
||||||
opener.add_handler(ph)
|
opener.add_handler(ph)
|
||||||
|
|
||||||
|
|
@ -1088,49 +1060,46 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
'file:/etc/passwd',
|
'file:/etc/passwd',
|
||||||
'file://nonsensename/etc/passwd',
|
'file://nonsensename/etc/passwd',
|
||||||
'ftp://www.python.org/pub/tmp/httplib.py',
|
'ftp://www.python.org/pub/python/misc/sousa.au',
|
||||||
'ftp://www.python.org/pub/tmp/imageop.c',
|
|
||||||
'ftp://www.python.org/pub/tmp/blat',
|
'ftp://www.python.org/pub/tmp/blat',
|
||||||
'http://www.espn.com/', # redirect
|
'http://www.espn.com/', # redirect
|
||||||
'http://www.python.org/Spanish/Inquistion/',
|
'http://www.python.org/Spanish/Inquistion/',
|
||||||
('http://grail.cnri.reston.va.us/cgi-bin/faqw.py',
|
('http://www.python.org/cgi-bin/faqw.py',
|
||||||
'query=pythonistas&querytype=simple&casefold=yes&req=search'),
|
'query=pythonistas&querytype=simple&casefold=yes&req=search'),
|
||||||
'http://www.python.org/',
|
'http://www.python.org/',
|
||||||
'ftp://prep.ai.mit.edu/welcome.msg',
|
'ftp://gatekeeper.research.compaq.com/pub/DEC/SRC/research-reports/00README-Legal-Rules-Regs',
|
||||||
'ftp://www.python.org/pub/tmp/figure.prn',
|
|
||||||
'ftp://www.python.org/pub/tmp/interp.pl',
|
|
||||||
'http://checkproxy.cnri.reston.va.us/test/test.html',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if localhost is not None:
|
## if localhost is not None:
|
||||||
urls = urls + [
|
## urls = urls + [
|
||||||
'file://%s/etc/passwd' % localhost,
|
## 'file://%s/etc/passwd' % localhost,
|
||||||
'http://%s/simple/' % localhost,
|
## 'http://%s/simple/' % localhost,
|
||||||
'http://%s/digest/' % localhost,
|
## 'http://%s/digest/' % localhost,
|
||||||
'http://%s/not/found.h' % localhost,
|
## 'http://%s/not/found.h' % localhost,
|
||||||
]
|
## ]
|
||||||
|
|
||||||
bauth = HTTPBasicAuthHandler()
|
## bauth = HTTPBasicAuthHandler()
|
||||||
bauth.add_password('basic_test_realm', localhost, 'jhylton',
|
## bauth.add_password('basic_test_realm', localhost, 'jhylton',
|
||||||
'password')
|
## 'password')
|
||||||
dauth = HTTPDigestAuthHandler()
|
## dauth = HTTPDigestAuthHandler()
|
||||||
dauth.add_password('digest_test_realm', localhost, 'jhylton',
|
## dauth.add_password('digest_test_realm', localhost, 'jhylton',
|
||||||
'password')
|
## 'password')
|
||||||
|
|
||||||
|
|
||||||
cfh = CacheFTPHandler()
|
cfh = CacheFTPHandler()
|
||||||
cfh.setTimeout(1)
|
cfh.setTimeout(1)
|
||||||
|
|
||||||
# XXX try out some custom proxy objects too!
|
## # XXX try out some custom proxy objects too!
|
||||||
def at_cnri(req):
|
## def at_cnri(req):
|
||||||
host = req.get_host()
|
## host = req.get_host()
|
||||||
print host
|
## print host
|
||||||
if host[-18:] == '.cnri.reston.va.us':
|
## if host[-18:] == '.cnri.reston.va.us':
|
||||||
return 1
|
## return 1
|
||||||
p = CustomProxy('http', at_cnri, 'proxy.cnri.reston.va.us')
|
## p = CustomProxy('http', at_cnri, 'proxy.cnri.reston.va.us')
|
||||||
ph = CustomProxyHandler(p)
|
## ph = CustomProxyHandler(p)
|
||||||
|
|
||||||
#install_opener(build_opener(dauth, bauth, cfh, GopherHandler, ph))
|
## install_opener(build_opener(dauth, bauth, cfh, GopherHandler, ph))
|
||||||
|
install_opener(build_opener(cfh, GopherHandler))
|
||||||
|
|
||||||
for url in urls:
|
for url in urls:
|
||||||
if isinstance(url, types.TupleType):
|
if isinstance(url, types.TupleType):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue