Edit File by line
/home/barbar84/www/wp-conte.../plugins/sujqvwi/AnonR/smanonr..../usr/lib64/python2....
File: urllib2.py
"""An extensible library for opening URLs using a variety of protocols
[0] Fix | Delete
[1] Fix | Delete
The simplest way to use this module is to call the urlopen function,
[2] Fix | Delete
which accepts a string containing a URL or a Request object (described
[3] Fix | Delete
below). It opens the URL and returns the results as file-like
[4] Fix | Delete
object; the returned object has some extra methods described below.
[5] Fix | Delete
[6] Fix | Delete
The OpenerDirector manages a collection of Handler objects that do
[7] Fix | Delete
all the actual work. Each Handler implements a particular protocol or
[8] Fix | Delete
option. The OpenerDirector is a composite object that invokes the
[9] Fix | Delete
Handlers needed to open the requested URL. For example, the
[10] Fix | Delete
HTTPHandler performs HTTP GET and POST requests and deals with
[11] Fix | Delete
non-error returns. The HTTPRedirectHandler automatically deals with
[12] Fix | Delete
HTTP 301, 302, 303 and 307 redirect errors, and the HTTPDigestAuthHandler
[13] Fix | Delete
deals with digest authentication.
[14] Fix | Delete
[15] Fix | Delete
urlopen(url, data=None) -- Basic usage is the same as original
[16] Fix | Delete
urllib. pass the url and optionally data to post to an HTTP URL, and
[17] Fix | Delete
get a file-like object back. One difference is that you can also pass
[18] Fix | Delete
a Request instance instead of URL. Raises a URLError (subclass of
[19] Fix | Delete
IOError); for HTTP errors, raises an HTTPError, which can also be
[20] Fix | Delete
treated as a valid response.
[21] Fix | Delete
[22] Fix | Delete
build_opener -- Function that creates a new OpenerDirector instance.
[23] Fix | Delete
Will install the default handlers. Accepts one or more Handlers as
[24] Fix | Delete
arguments, either instances or Handler classes that it will
[25] Fix | Delete
instantiate. If one of the argument is a subclass of the default
[26] Fix | Delete
handler, the argument will be installed instead of the default.
[27] Fix | Delete
[28] Fix | Delete
install_opener -- Installs a new opener as the default opener.
[29] Fix | Delete
[30] Fix | Delete
objects of interest:
[31] Fix | Delete
[32] Fix | Delete
OpenerDirector -- Sets up the User Agent as the Python-urllib client and manages
[33] Fix | Delete
the Handler classes, while dealing with requests and responses.
[34] Fix | Delete
[35] Fix | Delete
Request -- An object that encapsulates the state of a request. The
[36] Fix | Delete
state can be as simple as the URL. It can also include extra HTTP
[37] Fix | Delete
headers, e.g. a User-Agent.
[38] Fix | Delete
[39] Fix | Delete
BaseHandler --
[40] Fix | Delete
[41] Fix | Delete
exceptions:
[42] Fix | Delete
URLError -- A subclass of IOError, individual protocols have their own
[43] Fix | Delete
specific subclass.
[44] Fix | Delete
[45] Fix | Delete
HTTPError -- Also a valid HTTP response, so you can treat an HTTP error
[46] Fix | Delete
as an exceptional event or valid response.
[47] Fix | Delete
[48] Fix | Delete
internals:
[49] Fix | Delete
BaseHandler and parent
[50] Fix | Delete
_call_chain conventions
[51] Fix | Delete
[52] Fix | Delete
Example usage:
[53] Fix | Delete
[54] Fix | Delete
import urllib2
[55] Fix | Delete
[56] Fix | Delete
# set up authentication info
[57] Fix | Delete
authinfo = urllib2.HTTPBasicAuthHandler()
[58] Fix | Delete
authinfo.add_password(realm='PDQ Application',
[59] Fix | Delete
uri='https://mahler:8092/site-updates.py',
[60] Fix | Delete
user='klem',
[61] Fix | Delete
passwd='geheim$parole')
[62] Fix | Delete
[63] Fix | Delete
proxy_support = urllib2.ProxyHandler({"http" : "http://ahad-haam:3128"})
[64] Fix | Delete
[65] Fix | Delete
# build a new opener that adds authentication and caching FTP handlers
[66] Fix | Delete
opener = urllib2.build_opener(proxy_support, authinfo, urllib2.CacheFTPHandler)
[67] Fix | Delete
[68] Fix | Delete
# install it
[69] Fix | Delete
urllib2.install_opener(opener)
[70] Fix | Delete
[71] Fix | Delete
f = urllib2.urlopen('http://www.python.org/')
[72] Fix | Delete
[73] Fix | Delete
[74] Fix | Delete
"""
[75] Fix | Delete
[76] Fix | Delete
# XXX issues:
[77] Fix | Delete
# If an authentication error handler that tries to perform
[78] Fix | Delete
# authentication for some reason but fails, how should the error be
[79] Fix | Delete
# signalled? The client needs to know the HTTP error code. But if
[80] Fix | Delete
# the handler knows that the problem was, e.g., that it didn't know
[81] Fix | Delete
# that hash algo that requested in the challenge, it would be good to
[82] Fix | Delete
# pass that information along to the client, too.
[83] Fix | Delete
# ftp errors aren't handled cleanly
[84] Fix | Delete
# check digest against correct (i.e. non-apache) implementation
[85] Fix | Delete
[86] Fix | Delete
# Possible extensions:
[87] Fix | Delete
# complex proxies XXX not sure what exactly was meant by this
[88] Fix | Delete
# abstract factory for opener
[89] Fix | Delete
[90] Fix | Delete
import base64
[91] Fix | Delete
import hashlib
[92] Fix | Delete
import httplib
[93] Fix | Delete
import mimetools
[94] Fix | Delete
import os
[95] Fix | Delete
import posixpath
[96] Fix | Delete
import random
[97] Fix | Delete
import re
[98] Fix | Delete
import socket
[99] Fix | Delete
import sys
[100] Fix | Delete
import time
[101] Fix | Delete
import urlparse
[102] Fix | Delete
import bisect
[103] Fix | Delete
import warnings
[104] Fix | Delete
[105] Fix | Delete
try:
[106] Fix | Delete
from cStringIO import StringIO
[107] Fix | Delete
except ImportError:
[108] Fix | Delete
from StringIO import StringIO
[109] Fix | Delete
[110] Fix | Delete
# check for SSL
[111] Fix | Delete
try:
[112] Fix | Delete
import ssl
[113] Fix | Delete
except ImportError:
[114] Fix | Delete
_have_ssl = False
[115] Fix | Delete
else:
[116] Fix | Delete
_have_ssl = True
[117] Fix | Delete
[118] Fix | Delete
from urllib import (unwrap, unquote, splittype, splithost, quote,
[119] Fix | Delete
addinfourl, splitport, splittag, toBytes,
[120] Fix | Delete
splitattr, ftpwrapper, splituser, splitpasswd, splitvalue)
[121] Fix | Delete
[122] Fix | Delete
# support for FileHandler, proxies via environment variables
[123] Fix | Delete
from urllib import localhost, url2pathname, getproxies, proxy_bypass
[124] Fix | Delete
[125] Fix | Delete
# used in User-Agent header sent
[126] Fix | Delete
__version__ = sys.version[:3]
[127] Fix | Delete
[128] Fix | Delete
_opener = None
[129] Fix | Delete
def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
[130] Fix | Delete
cafile=None, capath=None, cadefault=False, context=None):
[131] Fix | Delete
global _opener
[132] Fix | Delete
if cafile or capath or cadefault:
[133] Fix | Delete
if context is not None:
[134] Fix | Delete
raise ValueError(
[135] Fix | Delete
"You can't pass both context and any of cafile, capath, and "
[136] Fix | Delete
"cadefault"
[137] Fix | Delete
)
[138] Fix | Delete
if not _have_ssl:
[139] Fix | Delete
raise ValueError('SSL support not available')
[140] Fix | Delete
context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH,
[141] Fix | Delete
cafile=cafile,
[142] Fix | Delete
capath=capath)
[143] Fix | Delete
https_handler = HTTPSHandler(context=context)
[144] Fix | Delete
opener = build_opener(https_handler)
[145] Fix | Delete
elif context:
[146] Fix | Delete
https_handler = HTTPSHandler(context=context)
[147] Fix | Delete
opener = build_opener(https_handler)
[148] Fix | Delete
elif _opener is None:
[149] Fix | Delete
_opener = opener = build_opener()
[150] Fix | Delete
else:
[151] Fix | Delete
opener = _opener
[152] Fix | Delete
return opener.open(url, data, timeout)
[153] Fix | Delete
[154] Fix | Delete
def install_opener(opener):
[155] Fix | Delete
global _opener
[156] Fix | Delete
_opener = opener
[157] Fix | Delete
[158] Fix | Delete
# do these error classes make sense?
[159] Fix | Delete
# make sure all of the IOError stuff is overridden. we just want to be
[160] Fix | Delete
# subtypes.
[161] Fix | Delete
[162] Fix | Delete
class URLError(IOError):
[163] Fix | Delete
# URLError is a sub-type of IOError, but it doesn't share any of
[164] Fix | Delete
# the implementation. need to override __init__ and __str__.
[165] Fix | Delete
# It sets self.args for compatibility with other EnvironmentError
[166] Fix | Delete
# subclasses, but args doesn't have the typical format with errno in
[167] Fix | Delete
# slot 0 and strerror in slot 1. This may be better than nothing.
[168] Fix | Delete
def __init__(self, reason):
[169] Fix | Delete
self.args = reason,
[170] Fix | Delete
self.reason = reason
[171] Fix | Delete
[172] Fix | Delete
def __str__(self):
[173] Fix | Delete
return '<urlopen error %s>' % self.reason
[174] Fix | Delete
[175] Fix | Delete
class HTTPError(URLError, addinfourl):
[176] Fix | Delete
"""Raised when HTTP error occurs, but also acts like non-error return"""
[177] Fix | Delete
__super_init = addinfourl.__init__
[178] Fix | Delete
[179] Fix | Delete
def __init__(self, url, code, msg, hdrs, fp):
[180] Fix | Delete
self.code = code
[181] Fix | Delete
self.msg = msg
[182] Fix | Delete
self.hdrs = hdrs
[183] Fix | Delete
self.fp = fp
[184] Fix | Delete
self.filename = url
[185] Fix | Delete
# The addinfourl classes depend on fp being a valid file
[186] Fix | Delete
# object. In some cases, the HTTPError may not have a valid
[187] Fix | Delete
# file object. If this happens, the simplest workaround is to
[188] Fix | Delete
# not initialize the base classes.
[189] Fix | Delete
if fp is not None:
[190] Fix | Delete
self.__super_init(fp, hdrs, url, code)
[191] Fix | Delete
[192] Fix | Delete
def __str__(self):
[193] Fix | Delete
return 'HTTP Error %s: %s' % (self.code, self.msg)
[194] Fix | Delete
[195] Fix | Delete
# since URLError specifies a .reason attribute, HTTPError should also
[196] Fix | Delete
# provide this attribute. See issue13211 fo discussion.
[197] Fix | Delete
@property
[198] Fix | Delete
def reason(self):
[199] Fix | Delete
return self.msg
[200] Fix | Delete
[201] Fix | Delete
def info(self):
[202] Fix | Delete
return self.hdrs
[203] Fix | Delete
[204] Fix | Delete
# copied from cookielib.py
[205] Fix | Delete
_cut_port_re = re.compile(r":\d+$")
[206] Fix | Delete
def request_host(request):
[207] Fix | Delete
"""Return request-host, as defined by RFC 2965.
[208] Fix | Delete
[209] Fix | Delete
Variation from RFC: returned value is lowercased, for convenient
[210] Fix | Delete
comparison.
[211] Fix | Delete
[212] Fix | Delete
"""
[213] Fix | Delete
url = request.get_full_url()
[214] Fix | Delete
host = urlparse.urlparse(url)[1]
[215] Fix | Delete
if host == "":
[216] Fix | Delete
host = request.get_header("Host", "")
[217] Fix | Delete
[218] Fix | Delete
# remove port, if present
[219] Fix | Delete
host = _cut_port_re.sub("", host, 1)
[220] Fix | Delete
return host.lower()
[221] Fix | Delete
[222] Fix | Delete
class Request:
[223] Fix | Delete
[224] Fix | Delete
def __init__(self, url, data=None, headers={},
[225] Fix | Delete
origin_req_host=None, unverifiable=False):
[226] Fix | Delete
# unwrap('<URL:type://host/path>') --> 'type://host/path'
[227] Fix | Delete
self.__original = unwrap(url)
[228] Fix | Delete
self.__original, self.__fragment = splittag(self.__original)
[229] Fix | Delete
self.type = None
[230] Fix | Delete
# self.__r_type is what's left after doing the splittype
[231] Fix | Delete
self.host = None
[232] Fix | Delete
self.port = None
[233] Fix | Delete
self._tunnel_host = None
[234] Fix | Delete
self.data = data
[235] Fix | Delete
self.headers = {}
[236] Fix | Delete
for key, value in headers.items():
[237] Fix | Delete
self.add_header(key, value)
[238] Fix | Delete
self.unredirected_hdrs = {}
[239] Fix | Delete
if origin_req_host is None:
[240] Fix | Delete
origin_req_host = request_host(self)
[241] Fix | Delete
self.origin_req_host = origin_req_host
[242] Fix | Delete
self.unverifiable = unverifiable
[243] Fix | Delete
[244] Fix | Delete
def __getattr__(self, attr):
[245] Fix | Delete
# XXX this is a fallback mechanism to guard against these
[246] Fix | Delete
# methods getting called in a non-standard order. this may be
[247] Fix | Delete
# too complicated and/or unnecessary.
[248] Fix | Delete
# XXX should the __r_XXX attributes be public?
[249] Fix | Delete
if attr in ('_Request__r_type', '_Request__r_host'):
[250] Fix | Delete
getattr(self, 'get_' + attr[12:])()
[251] Fix | Delete
return self.__dict__[attr]
[252] Fix | Delete
raise AttributeError, attr
[253] Fix | Delete
[254] Fix | Delete
def get_method(self):
[255] Fix | Delete
if self.has_data():
[256] Fix | Delete
return "POST"
[257] Fix | Delete
else:
[258] Fix | Delete
return "GET"
[259] Fix | Delete
[260] Fix | Delete
# XXX these helper methods are lame
[261] Fix | Delete
[262] Fix | Delete
def add_data(self, data):
[263] Fix | Delete
self.data = data
[264] Fix | Delete
[265] Fix | Delete
def has_data(self):
[266] Fix | Delete
return self.data is not None
[267] Fix | Delete
[268] Fix | Delete
def get_data(self):
[269] Fix | Delete
return self.data
[270] Fix | Delete
[271] Fix | Delete
def get_full_url(self):
[272] Fix | Delete
if self.__fragment:
[273] Fix | Delete
return '%s#%s' % (self.__original, self.__fragment)
[274] Fix | Delete
else:
[275] Fix | Delete
return self.__original
[276] Fix | Delete
[277] Fix | Delete
def get_type(self):
[278] Fix | Delete
if self.type is None:
[279] Fix | Delete
self.type, self.__r_type = splittype(self.__original)
[280] Fix | Delete
if self.type is None:
[281] Fix | Delete
raise ValueError, "unknown url type: %s" % self.__original
[282] Fix | Delete
return self.type
[283] Fix | Delete
[284] Fix | Delete
def get_host(self):
[285] Fix | Delete
if self.host is None:
[286] Fix | Delete
self.host, self.__r_host = splithost(self.__r_type)
[287] Fix | Delete
if self.host:
[288] Fix | Delete
self.host = unquote(self.host)
[289] Fix | Delete
return self.host
[290] Fix | Delete
[291] Fix | Delete
def get_selector(self):
[292] Fix | Delete
return self.__r_host
[293] Fix | Delete
[294] Fix | Delete
def set_proxy(self, host, type):
[295] Fix | Delete
if self.type == 'https' and not self._tunnel_host:
[296] Fix | Delete
self._tunnel_host = self.host
[297] Fix | Delete
else:
[298] Fix | Delete
self.type = type
[299] Fix | Delete
self.__r_host = self.__original
[300] Fix | Delete
[301] Fix | Delete
self.host = host
[302] Fix | Delete
[303] Fix | Delete
def has_proxy(self):
[304] Fix | Delete
return self.__r_host == self.__original
[305] Fix | Delete
[306] Fix | Delete
def get_origin_req_host(self):
[307] Fix | Delete
return self.origin_req_host
[308] Fix | Delete
[309] Fix | Delete
def is_unverifiable(self):
[310] Fix | Delete
return self.unverifiable
[311] Fix | Delete
[312] Fix | Delete
def add_header(self, key, val):
[313] Fix | Delete
# useful for something like authentication
[314] Fix | Delete
self.headers[key.capitalize()] = val
[315] Fix | Delete
[316] Fix | Delete
def add_unredirected_header(self, key, val):
[317] Fix | Delete
# will not be added to a redirected request
[318] Fix | Delete
self.unredirected_hdrs[key.capitalize()] = val
[319] Fix | Delete
[320] Fix | Delete
def has_header(self, header_name):
[321] Fix | Delete
return (header_name in self.headers or
[322] Fix | Delete
header_name in self.unredirected_hdrs)
[323] Fix | Delete
[324] Fix | Delete
def get_header(self, header_name, default=None):
[325] Fix | Delete
return self.headers.get(
[326] Fix | Delete
header_name,
[327] Fix | Delete
self.unredirected_hdrs.get(header_name, default))
[328] Fix | Delete
[329] Fix | Delete
def header_items(self):
[330] Fix | Delete
hdrs = self.unredirected_hdrs.copy()
[331] Fix | Delete
hdrs.update(self.headers)
[332] Fix | Delete
return hdrs.items()
[333] Fix | Delete
[334] Fix | Delete
class OpenerDirector:
[335] Fix | Delete
def __init__(self):
[336] Fix | Delete
client_version = "Python-urllib/%s" % __version__
[337] Fix | Delete
self.addheaders = [('User-agent', client_version)]
[338] Fix | Delete
# self.handlers is retained only for backward compatibility
[339] Fix | Delete
self.handlers = []
[340] Fix | Delete
# manage the individual handlers
[341] Fix | Delete
self.handle_open = {}
[342] Fix | Delete
self.handle_error = {}
[343] Fix | Delete
self.process_response = {}
[344] Fix | Delete
self.process_request = {}
[345] Fix | Delete
[346] Fix | Delete
def add_handler(self, handler):
[347] Fix | Delete
if not hasattr(handler, "add_parent"):
[348] Fix | Delete
raise TypeError("expected BaseHandler instance, got %r" %
[349] Fix | Delete
type(handler))
[350] Fix | Delete
[351] Fix | Delete
added = False
[352] Fix | Delete
for meth in dir(handler):
[353] Fix | Delete
if meth in ["redirect_request", "do_open", "proxy_open"]:
[354] Fix | Delete
# oops, coincidental match
[355] Fix | Delete
continue
[356] Fix | Delete
[357] Fix | Delete
i = meth.find("_")
[358] Fix | Delete
protocol = meth[:i]
[359] Fix | Delete
condition = meth[i+1:]
[360] Fix | Delete
[361] Fix | Delete
if condition.startswith("error"):
[362] Fix | Delete
j = condition.find("_") + i + 1
[363] Fix | Delete
kind = meth[j+1:]
[364] Fix | Delete
try:
[365] Fix | Delete
kind = int(kind)
[366] Fix | Delete
except ValueError:
[367] Fix | Delete
pass
[368] Fix | Delete
lookup = self.handle_error.get(protocol, {})
[369] Fix | Delete
self.handle_error[protocol] = lookup
[370] Fix | Delete
elif condition == "open":
[371] Fix | Delete
kind = protocol
[372] Fix | Delete
lookup = self.handle_open
[373] Fix | Delete
elif condition == "response":
[374] Fix | Delete
kind = protocol
[375] Fix | Delete
lookup = self.process_response
[376] Fix | Delete
elif condition == "request":
[377] Fix | Delete
kind = protocol
[378] Fix | Delete
lookup = self.process_request
[379] Fix | Delete
else:
[380] Fix | Delete
continue
[381] Fix | Delete
[382] Fix | Delete
handlers = lookup.setdefault(kind, [])
[383] Fix | Delete
if handlers:
[384] Fix | Delete
bisect.insort(handlers, handler)
[385] Fix | Delete
else:
[386] Fix | Delete
handlers.append(handler)
[387] Fix | Delete
added = True
[388] Fix | Delete
[389] Fix | Delete
if added:
[390] Fix | Delete
bisect.insort(self.handlers, handler)
[391] Fix | Delete
handler.add_parent(self)
[392] Fix | Delete
[393] Fix | Delete
def close(self):
[394] Fix | Delete
# Only exists for backwards compatibility.
[395] Fix | Delete
pass
[396] Fix | Delete
[397] Fix | Delete
def _call_chain(self, chain, kind, meth_name, *args):
[398] Fix | Delete
# Handlers raise an exception if no one else should try to handle
[399] Fix | Delete
# the request, or return None if they can't but another handler
[400] Fix | Delete
# could. Otherwise, they return the response.
[401] Fix | Delete
handlers = chain.get(kind, ())
[402] Fix | Delete
for handler in handlers:
[403] Fix | Delete
func = getattr(handler, meth_name)
[404] Fix | Delete
[405] Fix | Delete
result = func(*args)
[406] Fix | Delete
if result is not None:
[407] Fix | Delete
return result
[408] Fix | Delete
[409] Fix | Delete
def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
[410] Fix | Delete
# accept a URL or a Request object
[411] Fix | Delete
if isinstance(fullurl, basestring):
[412] Fix | Delete
req = Request(fullurl, data)
[413] Fix | Delete
else:
[414] Fix | Delete
req = fullurl
[415] Fix | Delete
if data is not None:
[416] Fix | Delete
req.add_data(data)
[417] Fix | Delete
[418] Fix | Delete
req.timeout = timeout
[419] Fix | Delete
protocol = req.get_type()
[420] Fix | Delete
[421] Fix | Delete
# pre-process request
[422] Fix | Delete
meth_name = protocol+"_request"
[423] Fix | Delete
for processor in self.process_request.get(protocol, []):
[424] Fix | Delete
meth = getattr(processor, meth_name)
[425] Fix | Delete
req = meth(req)
[426] Fix | Delete
[427] Fix | Delete
response = self._open(req, data)
[428] Fix | Delete
[429] Fix | Delete
# post-process response
[430] Fix | Delete
meth_name = protocol+"_response"
[431] Fix | Delete
for processor in self.process_response.get(protocol, []):
[432] Fix | Delete
meth = getattr(processor, meth_name)
[433] Fix | Delete
response = meth(req, response)
[434] Fix | Delete
[435] Fix | Delete
return response
[436] Fix | Delete
[437] Fix | Delete
def _open(self, req, data=None):
[438] Fix | Delete
result = self._call_chain(self.handle_open, 'default',
[439] Fix | Delete
'default_open', req)
[440] Fix | Delete
if result:
[441] Fix | Delete
return result
[442] Fix | Delete
[443] Fix | Delete
protocol = req.get_type()
[444] Fix | Delete
result = self._call_chain(self.handle_open, protocol, protocol +
[445] Fix | Delete
'_open', req)
[446] Fix | Delete
if result:
[447] Fix | Delete
return result
[448] Fix | Delete
[449] Fix | Delete
return self._call_chain(self.handle_open, 'unknown',
[450] Fix | Delete
'unknown_open', req)
[451] Fix | Delete
[452] Fix | Delete
def error(self, proto, *args):
[453] Fix | Delete
if proto in ('http', 'https'):
[454] Fix | Delete
# XXX http[s] protocols are special-cased
[455] Fix | Delete
dict = self.handle_error['http'] # https is not different than http
[456] Fix | Delete
proto = args[2] # YUCK!
[457] Fix | Delete
meth_name = 'http_error_%s' % proto
[458] Fix | Delete
http_err = 1
[459] Fix | Delete
orig_args = args
[460] Fix | Delete
else:
[461] Fix | Delete
dict = self.handle_error
[462] Fix | Delete
meth_name = proto + '_error'
[463] Fix | Delete
http_err = 0
[464] Fix | Delete
args = (dict, proto, meth_name) + args
[465] Fix | Delete
result = self._call_chain(*args)
[466] Fix | Delete
if result:
[467] Fix | Delete
return result
[468] Fix | Delete
[469] Fix | Delete
if http_err:
[470] Fix | Delete
args = (dict, 'default', 'http_error_default') + orig_args
[471] Fix | Delete
return self._call_chain(*args)
[472] Fix | Delete
[473] Fix | Delete
# XXX probably also want an abstract factory that knows when it makes
[474] Fix | Delete
# sense to skip a superclass in favor of a subclass and when it might
[475] Fix | Delete
# make sense to include both
[476] Fix | Delete
[477] Fix | Delete
def build_opener(*handlers):
[478] Fix | Delete
"""Create an opener object from a list of handlers.
[479] Fix | Delete
[480] Fix | Delete
The opener will use several default handlers, including support
[481] Fix | Delete
for HTTP, FTP and when applicable, HTTPS.
[482] Fix | Delete
[483] Fix | Delete
If any of the handlers passed as arguments are subclasses of the
[484] Fix | Delete
default handlers, the default handlers will not be used.
[485] Fix | Delete
"""
[486] Fix | Delete
import types
[487] Fix | Delete
def isclass(obj):
[488] Fix | Delete
return isinstance(obj, (types.ClassType, type))
[489] Fix | Delete
[490] Fix | Delete
opener = OpenerDirector()
[491] Fix | Delete
default_classes = [ProxyHandler, UnknownHandler, HTTPHandler,
[492] Fix | Delete
HTTPDefaultErrorHandler, HTTPRedirectHandler,
[493] Fix | Delete
FTPHandler, FileHandler, HTTPErrorProcessor]
[494] Fix | Delete
if hasattr(httplib, 'HTTPS'):
[495] Fix | Delete
default_classes.append(HTTPSHandler)
[496] Fix | Delete
skip = set()
[497] Fix | Delete
for klass in default_classes:
[498] Fix | Delete
for check in handlers:
[499] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function