summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Yan <felixonmars@gmail.com>2014-09-14 11:43:53 +0800
committerFelix Yan <felixonmars@gmail.com>2014-09-14 11:43:53 +0800
commit6733d6065583d098276d66f31a431b0dfc25810f (patch)
tree7601d63dcf2ee1629275b64b974d1ba24b2be270
parentd149a870b7315fb663eeffb5d4beba2d841ea3d1 (diff)
downloadboto-6733d6065583d098276d66f31a431b0dfc25810f.tar.gz
common modules: tidy up to meet PEP8 better
-rw-r--r--boto/auth.py20
-rw-r--r--boto/auth_handler.py10
-rw-r--r--boto/connection.py78
-rw-r--r--boto/contrib/__init__.py3
-rw-r--r--boto/contrib/ymlmessage.py1
-rw-r--r--boto/exception.py33
-rw-r--r--boto/handler.py3
-rw-r--r--boto/https_connection.py189
-rw-r--r--boto/jsonresponse.py5
-rw-r--r--boto/plugin.py25
-rw-r--r--boto/provider.py6
-rw-r--r--boto/regioninfo.py2
-rw-r--r--boto/requestlog.py14
-rw-r--r--boto/resultset.py12
-rwxr-xr-xboto/storage_uri.py145
-rw-r--r--boto/utils.py7
-rwxr-xr-xscripts/git-release-notes.py2
-rw-r--r--scripts/rebuild_endpoints.py1
-rw-r--r--tests/__init__.py2
-rw-r--r--tests/integration/__init__.py2
-rwxr-xr-xtests/test.py3
-rw-r--r--tests/unit/__init__.py2
-rw-r--r--tests/unit/test_connection.py29
-rw-r--r--tests/unit/test_exception.py17
-rw-r--r--tests/unit/test_regioninfo.py2
25 files changed, 328 insertions, 285 deletions
diff --git a/boto/auth.py b/boto/auth.py
index df8dcccd..bc8d3b7c 100644
--- a/boto/auth.py
+++ b/boto/auth.py
@@ -37,8 +37,6 @@ import datetime
from email.utils import formatdate
import hmac
import os
-import sys
-import time
import posixpath
from boto.compat import urllib, encodebytes
@@ -378,7 +376,7 @@ class HmacAuthV4Handler(AuthHandler, HmacKeys):
path = http_request.auth_path
# Normalize the path
# in windows normpath('/') will be '\\' so we chane it back to '/'
- normalized = posixpath.normpath(path).replace('\\','/')
+ normalized = posixpath.normpath(path).replace('\\', '/')
# Then urlencode whatever's left.
encoded = urllib.parse.quote(normalized)
if len(path) > 1 and path.endswith('/'):
@@ -474,7 +472,7 @@ class HmacAuthV4Handler(AuthHandler, HmacKeys):
def signature(self, http_request, string_to_sign):
key = self._provider.secret_key
k_date = self._sign(('AWS4' + key).encode('utf-8'),
- http_request.timestamp)
+ http_request.timestamp)
k_region = self._sign(k_date, http_request.region_name)
k_service = self._sign(k_region, http_request.service_name)
k_signing = self._sign(k_service, 'aws4_request')
@@ -570,7 +568,7 @@ class S3HmacAuthV4Handler(HmacAuthV4Handler, AuthHandler):
# Hooray for the only difference! The main SigV4 signer only does
# ``Host`` + ``x-amz-*``. But S3 wants pretty much everything
# signed, except for authorization itself.
- if not lname in ['authorization']:
+ if lname not in ['authorization']:
headers_to_sign[name] = value
return headers_to_sign
@@ -667,7 +665,7 @@ class S3HmacAuthV4Handler(HmacAuthV4Handler, AuthHandler):
return super(S3HmacAuthV4Handler, self).payload(http_request)
def add_auth(self, req, **kwargs):
- if not 'x-amz-content-sha256' in req.headers:
+ if 'x-amz-content-sha256' not in req.headers:
if '_sha256' in req.headers:
req.headers['x-amz-content-sha256'] = req.headers.pop('_sha256')
else:
@@ -751,7 +749,6 @@ class QueryAuthHandler(AuthHandler):
def add_auth(self, http_request, **kwargs):
headers = http_request.headers
- params = http_request.params
qs = self._build_query_string(
http_request.params
)
@@ -899,7 +896,7 @@ class POSTPathQSV2AuthHandler(QuerySignatureV2AuthHandler, AuthHandler):
# already be there, we need to get rid of that and rebuild it
req.path = req.path.split('?')[0]
req.path = (req.path + '?' + qs +
- '&Signature=' + urllib.parse.quote_plus(signature))
+ '&Signature=' + urllib.parse.quote_plus(signature))
def get_auth_handler(host, config, provider, requested_capability=None):
@@ -925,7 +922,6 @@ def get_auth_handler(host, config, provider, requested_capability=None):
"""
ready_handlers = []
auth_handlers = boto.plugin.get_plugin(AuthHandler, requested_capability)
- total_handlers = len(auth_handlers)
for handler in auth_handlers:
try:
ready_handlers.append(handler(host, config, provider))
@@ -936,9 +932,9 @@ def get_auth_handler(host, config, provider, requested_capability=None):
checked_handlers = auth_handlers
names = [handler.__name__ for handler in checked_handlers]
raise boto.exception.NoAuthHandlerFound(
- 'No handler was ready to authenticate. %d handlers were checked.'
- ' %s '
- 'Check your credentials' % (len(names), str(names)))
+ 'No handler was ready to authenticate. %d handlers were checked.'
+ ' %s '
+ 'Check your credentials' % (len(names), str(names)))
# We select the last ready auth handler that was loaded, to allow users to
# customize how auth works in environments where there are shared boto
diff --git a/boto/auth_handler.py b/boto/auth_handler.py
index e6d131af..a8583f8a 100644
--- a/boto/auth_handler.py
+++ b/boto/auth_handler.py
@@ -14,7 +14,7 @@
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
@@ -25,8 +25,10 @@ Defines an interface which all Auth handlers need to implement.
from boto.plugin import Plugin
+
class NotReadyToAuthenticate(Exception):
- pass
+ pass
+
class AuthHandler(Plugin):
@@ -37,10 +39,10 @@ class AuthHandler(Plugin):
:type host: string
:param host: The host to which the request is being sent.
- :type config: boto.pyami.Config
+ :type config: boto.pyami.Config
:param config: Boto configuration.
- :type provider: boto.provider.Provider
+ :type provider: boto.provider.Provider
:param provider: Provider details.
Raises:
diff --git a/boto/connection.py b/boto/connection.py
index 8640ec48..09452358 100644
--- a/boto/connection.py
+++ b/boto/connection.py
@@ -90,7 +90,7 @@ ON_APP_ENGINE = all(key in os.environ for key in (
PORTS_BY_SECURITY = {True: 443,
False: 80}
-DEFAULT_CA_CERTS_FILE = os.path.join(os.path.dirname(os.path.abspath(boto.cacerts.__file__ )), "cacerts.txt")
+DEFAULT_CA_CERTS_FILE = os.path.join(os.path.dirname(os.path.abspath(boto.cacerts.__file__)), "cacerts.txt")
class HostConnectionPool(object):
@@ -485,13 +485,13 @@ class AWSAuthConnection(object):
validate_certs)
if self.https_validate_certificates and not HAVE_HTTPS_CONNECTION:
raise BotoClientError(
- "SSL server certificate validation is enabled in boto "
- "configuration, but Python dependencies required to "
- "support this feature are not available. Certificate "
- "validation is only supported when running under Python "
- "2.6 or later.")
+ "SSL server certificate validation is enabled in boto "
+ "configuration, but Python dependencies required to "
+ "support this feature are not available. Certificate "
+ "validation is only supported when running under Python "
+ "2.6 or later.")
certs_file = config.get_value(
- 'Boto', 'ca_certificates_file', DEFAULT_CA_CERTS_FILE)
+ 'Boto', 'ca_certificates_file', DEFAULT_CA_CERTS_FILE)
if certs_file == 'system':
certs_file = None
self.ca_certificates_file = certs_file
@@ -508,7 +508,7 @@ class AWSAuthConnection(object):
self.http_unretryable_exceptions = []
if HAVE_HTTPS_CONNECTION:
self.http_unretryable_exceptions.append(
- https_connection.InvalidCertificateException)
+ https_connection.InvalidCertificateException)
# define values in socket exceptions we don't want to catch
self.socket_exception_values = (errno.EINTR,)
@@ -565,7 +565,7 @@ class AWSAuthConnection(object):
self._connection = (self.host, self.port, self.is_secure)
self._last_rs = None
self._auth_handler = auth.get_auth_handler(
- host, config, self.provider, self._required_auth_capability())
+ host, config, self.provider, self._required_auth_capability())
if getattr(self, 'AuthServiceName', None) is not None:
self.auth_service_name = self.AuthServiceName
self.request_hook = None
@@ -667,9 +667,9 @@ class AWSAuthConnection(object):
self.proxy_pass = proxy_pass
if 'http_proxy' in os.environ and not self.proxy:
pattern = re.compile(
- '(?:http://)?' \
- '(?:(?P<user>[\w\-\.]+):(?P<pass>.*)@)?' \
- '(?P<host>[\w\-\.]+)' \
+ '(?:http://)?'
+ '(?:(?P<user>[\w\-\.]+):(?P<pass>.*)@)?'
+ '(?P<host>[\w\-\.]+)'
'(?::(?P<port>\d+))?'
)
match = pattern.match(os.environ['http_proxy'])
@@ -689,8 +689,8 @@ class AWSAuthConnection(object):
self.proxy_pass = config.get_value('Boto', 'proxy_pass', None)
if not self.proxy_port and self.proxy:
- print("http_proxy environment variable does not specify " \
- "a port, using default")
+ print("http_proxy environment variable does not specify "
+ "a port, using default")
self.proxy_port = self.port
self.no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '')
@@ -740,30 +740,30 @@ class AWSAuthConnection(object):
if is_secure:
boto.log.debug(
- 'establishing HTTPS connection: host=%s, kwargs=%s',
- host, http_connection_kwargs)
+ 'establishing HTTPS connection: host=%s, kwargs=%s',
+ host, http_connection_kwargs)
if self.use_proxy and not self.skip_proxy(host):
connection = self.proxy_ssl(host, is_secure and 443 or 80)
elif self.https_connection_factory:
connection = self.https_connection_factory(host)
elif self.https_validate_certificates and HAVE_HTTPS_CONNECTION:
connection = https_connection.CertValidatingHTTPSConnection(
- host, ca_certs=self.ca_certificates_file,
- **http_connection_kwargs)
+ host, ca_certs=self.ca_certificates_file,
+ **http_connection_kwargs)
else:
- connection = http_client.HTTPSConnection(host,
- **http_connection_kwargs)
+ connection = http_client.HTTPSConnection(
+ host, **http_connection_kwargs)
else:
boto.log.debug('establishing HTTP connection: kwargs=%s' %
- http_connection_kwargs)
+ http_connection_kwargs)
if self.https_connection_factory:
# even though the factory says https, this is too handy
# to not be able to allow overriding for http also.
- connection = self.https_connection_factory(host,
- **http_connection_kwargs)
+ connection = self.https_connection_factory(
+ host, **http_connection_kwargs)
else:
- connection = http_client.HTTPConnection(host,
- **http_connection_kwargs)
+ connection = http_client.HTTPConnection(
+ host, **http_connection_kwargs)
if self.debug > 1:
connection.set_debuglevel(self.debug)
# self.connection must be maintained for backwards-compatibility
@@ -822,7 +822,7 @@ class AWSAuthConnection(object):
if self.https_validate_certificates and HAVE_HTTPS_CONNECTION:
msg = "wrapping ssl socket for proxied connection; "
if self.ca_certificates_file:
- msg += "CA certificate file=%s" %self.ca_certificates_file
+ msg += "CA certificate file=%s" % self.ca_certificates_file
else:
msg += "using system provided SSL certs"
boto.log.debug(msg)
@@ -836,7 +836,7 @@ class AWSAuthConnection(object):
hostname = self.host.split(':', 0)[0]
if not https_connection.ValidateCertificateHostname(cert, hostname):
raise https_connection.InvalidCertificateException(
- hostname, cert, 'hostname mismatch')
+ hostname, cert, 'hostname mismatch')
else:
# Fallback for old Python without ssl.wrap_socket
if hasattr(http_client, 'ssl'):
@@ -1008,8 +1008,8 @@ class AWSAuthConnection(object):
'encountered unretryable %s exception, re-raising' %
e.__class__.__name__)
raise
- boto.log.debug('encountered %s exception, reconnecting' % \
- e.__class__.__name__)
+ boto.log.debug('encountered %s exception, reconnecting' %
+ e.__class__.__name__)
connection = self.new_http_connection(request.host, request.port,
self.is_secure)
time.sleep(next_sleep)
@@ -1041,8 +1041,7 @@ class AWSAuthConnection(object):
headers = {}
else:
headers = headers.copy()
- if (self.host_header and
- not boto.utils.find_matching_headers('host', headers)):
+ if self.host_header and not boto.utils.find_matching_headers('host', headers):
headers['host'] = self.host_header
host = host or self.host
if self.use_proxy:
@@ -1085,14 +1084,15 @@ class AWSQueryConnection(AWSAuthConnection):
proxy_user=None, proxy_pass=None, host=None, debug=0,
https_connection_factory=None, path='/', security_token=None,
validate_certs=True, profile_name=None):
- super(AWSQueryConnection, self).__init__(host, aws_access_key_id,
- aws_secret_access_key,
- is_secure, port, proxy,
- proxy_port, proxy_user, proxy_pass,
- debug, https_connection_factory, path,
- security_token=security_token,
- validate_certs=validate_certs,
- profile_name=profile_name)
+ super(AWSQueryConnection, self).__init__(
+ host, aws_access_key_id,
+ aws_secret_access_key,
+ is_secure, port, proxy,
+ proxy_port, proxy_user, proxy_pass,
+ debug, https_connection_factory, path,
+ security_token=security_token,
+ validate_certs=validate_certs,
+ profile_name=profile_name)
def _required_auth_capability(self):
return []
diff --git a/boto/contrib/__init__.py b/boto/contrib/__init__.py
index 303dbb66..a7e571e2 100644
--- a/boto/contrib/__init__.py
+++ b/boto/contrib/__init__.py
@@ -14,9 +14,8 @@
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
-
diff --git a/boto/contrib/ymlmessage.py b/boto/contrib/ymlmessage.py
index 6f3dd20c..ae6aea48 100644
--- a/boto/contrib/ymlmessage.py
+++ b/boto/contrib/ymlmessage.py
@@ -28,6 +28,7 @@ This module requires the yaml module.
from boto.sqs.message import Message
import yaml
+
class YAMLMessage(Message):
"""
The YAMLMessage class provides a YAML compatible message. Encoding and
diff --git a/boto/exception.py b/boto/exception.py
index 9baa0999..36c226fa 100644
--- a/boto/exception.py
+++ b/boto/exception.py
@@ -30,9 +30,10 @@ import xml.sax
import boto
from boto import handler
-from boto.compat import json, six, StandardError
+from boto.compat import json, StandardError
from boto.resultset import ResultSet
+
class BotoClientError(StandardError):
"""
General Boto Client error (error accessing AWS)
@@ -112,7 +113,7 @@ class BotoServerError(StandardError):
try:
h = handler.XmlHandlerWrapper(self, self)
h.parseString(self.body)
- except (TypeError, xml.sax.SAXParseException) as pe:
+ except (TypeError, xml.sax.SAXParseException):
# What if it's JSON? Let's try that.
try:
parsed = json.loads(self.body)
@@ -209,6 +210,7 @@ class StorageCreateError(BotoServerError):
else:
return super(StorageCreateError, self).endElement(name, value, connection)
+
class S3CreateError(StorageCreateError):
"""
Error creating a bucket or key on S3.
@@ -294,15 +296,15 @@ class StorageResponseError(BotoServerError):
super(StorageResponseError, self).__init__(status, reason, body)
def startElement(self, name, attrs, connection):
- return super(StorageResponseError, self).startElement(name, attrs,
- connection)
+ return super(StorageResponseError, self).startElement(
+ name, attrs, connection)
def endElement(self, name, value, connection):
if name == 'Resource':
self.resource = value
else:
- return super(StorageResponseError, self).endElement(name, value,
- connection)
+ return super(StorageResponseError, self).endElement(
+ name, value, connection)
def _cleanupParsedProperties(self):
super(StorageResponseError, self)._cleanupParsedProperties()
@@ -332,8 +334,8 @@ class EC2ResponseError(BotoServerError):
self.errors = None
self._errorResultSet = []
super(EC2ResponseError, self).__init__(status, reason, body)
- self.errors = [ (e.error_code, e.error_message) \
- for e in self._errorResultSet ]
+ self.errors = [
+ (e.error_code, e.error_message) for e in self._errorResultSet]
if len(self.errors):
self.error_code, self.error_message = self.errors[0]
@@ -348,7 +350,7 @@ class EC2ResponseError(BotoServerError):
if name == 'RequestID':
self.request_id = value
else:
- return None # don't call subclass here
+ return None # don't call subclass here
def _cleanupParsedProperties(self):
super(EC2ResponseError, self)._cleanupParsedProperties()
@@ -420,30 +422,35 @@ class SDBResponseError(BotoServerError):
"""
pass
+
class AWSConnectionError(BotoClientError):
"""
General error connecting to Amazon Web Services.
"""
pass
+
class StorageDataError(BotoClientError):
"""
Error receiving data from a storage service.
"""
pass
+
class S3DataError(StorageDataError):
"""
Error receiving data from S3.
"""
pass
+
class GSDataError(StorageDataError):
"""
Error receiving data from GS.
"""
pass
+
class InvalidUriError(Exception):
"""Exception raised when URI is invalid."""
@@ -451,6 +458,7 @@ class InvalidUriError(Exception):
super(InvalidUriError, self).__init__(message)
self.message = message
+
class InvalidAclError(Exception):
"""Exception raised when ACL XML is invalid."""
@@ -458,6 +466,7 @@ class InvalidAclError(Exception):
super(InvalidAclError, self).__init__(message)
self.message = message
+
class InvalidCorsError(Exception):
"""Exception raised when CORS XML is invalid."""
@@ -465,10 +474,12 @@ class InvalidCorsError(Exception):
super(InvalidCorsError, self).__init__(message)
self.message = message
+
class NoAuthHandlerFound(Exception):
"""Is raised when no auth handlers were found ready to authenticate."""
pass
+
class InvalidLifecycleConfigError(Exception):
"""Exception raised when GCS lifecycle configuration XML is invalid."""
@@ -476,6 +487,7 @@ class InvalidLifecycleConfigError(Exception):
super(InvalidLifecycleConfigError, self).__init__(message)
self.message = message
+
# Enum class for resumable upload failure disposition.
class ResumableTransferDisposition(object):
# START_OVER means an attempt to resume an existing transfer failed,
@@ -500,6 +512,7 @@ class ResumableTransferDisposition(object):
# upload ID.
ABORT = 'ABORT'
+
class ResumableUploadException(Exception):
"""
Exception raised for various resumable upload problems.
@@ -516,6 +529,7 @@ class ResumableUploadException(Exception):
return 'ResumableUploadException("%s", %s)' % (
self.message, self.disposition)
+
class ResumableDownloadException(Exception):
"""
Exception raised for various resumable download problems.
@@ -532,6 +546,7 @@ class ResumableDownloadException(Exception):
return 'ResumableDownloadException("%s", %s)' % (
self.message, self.disposition)
+
class TooManyRecordsException(Exception):
"""
Exception raised when a search of Route53 records returns more
diff --git a/boto/handler.py b/boto/handler.py
index b079ada6..3b5f0732 100644
--- a/boto/handler.py
+++ b/boto/handler.py
@@ -14,7 +14,7 @@
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
@@ -23,6 +23,7 @@ import xml.sax
from boto.compat import StringIO
+
class XmlHandler(xml.sax.ContentHandler):
def __init__(self, root_node, connection):
diff --git a/boto/https_connection.py b/boto/https_connection.py
index 9222fbde..ddc31a15 100644
--- a/boto/https_connection.py
+++ b/boto/https_connection.py
@@ -27,111 +27,112 @@ import boto
from boto.compat import six, http_client
-class InvalidCertificateException(http_client.HTTPException):
- """Raised when a certificate is provided with an invalid hostname."""
- def __init__(self, host, cert, reason):
- """Constructor.
+class InvalidCertificateException(http_client.HTTPException):
+ """Raised when a certificate is provided with an invalid hostname."""
- Args:
- host: The hostname the connection was made to.
- cert: The SSL certificate (as a dictionary) the host returned.
- """
- http_client.HTTPException.__init__(self)
- self.host = host
- self.cert = cert
- self.reason = reason
+ def __init__(self, host, cert, reason):
+ """Constructor.
- def __str__(self):
- return ('Host %s returned an invalid certificate (%s): %s' %
- (self.host, self.reason, self.cert))
+ Args:
+ host: The hostname the connection was made to.
+ cert: The SSL certificate (as a dictionary) the host returned.
+ """
+ http_client.HTTPException.__init__(self)
+ self.host = host
+ self.cert = cert
+ self.reason = reason
-def GetValidHostsForCert(cert):
- """Returns a list of valid host globs for an SSL certificate.
-
- Args:
- cert: A dictionary representing an SSL certificate.
- Returns:
- list: A list of valid host globs.
- """
- if 'subjectAltName' in cert:
- return [x[1] for x in cert['subjectAltName'] if x[0].lower() == 'dns']
- else:
- return [x[0][1] for x in cert['subject']
- if x[0][0].lower() == 'commonname']
+ def __str__(self):
+ return ('Host %s returned an invalid certificate (%s): %s' %
+ (self.host, self.reason, self.cert))
-def ValidateCertificateHostname(cert, hostname):
- """Validates that a given hostname is valid for an SSL certificate.
-
- Args:
- cert: A dictionary representing an SSL certificate.
- hostname: The hostname to test.
- Returns:
- bool: Whether or not the hostname is valid for this certificate.
- """
- hosts = GetValidHostsForCert(cert)
- boto.log.debug(
- "validating server certificate: hostname=%s, certificate hosts=%s",
- hostname, hosts)
- for host in hosts:
- host_re = host.replace('.', '\.').replace('*', '[^.]*')
- if re.search('^%s$' % (host_re,), hostname, re.I):
- return True
- return False
+def GetValidHostsForCert(cert):
+ """Returns a list of valid host globs for an SSL certificate.
-class CertValidatingHTTPSConnection(http_client.HTTPConnection):
- """An HTTPConnection that connects over SSL and validates certificates."""
+ Args:
+ cert: A dictionary representing an SSL certificate.
+ Returns:
+ list: A list of valid host globs.
+ """
+ if 'subjectAltName' in cert:
+ return [x[1] for x in cert['subjectAltName'] if x[0].lower() == 'dns']
+ else:
+ return [x[0][1] for x in cert['subject']
+ if x[0][0].lower() == 'commonname']
- default_port = http_client.HTTPS_PORT
- def __init__(self, host, port=default_port, key_file=None, cert_file=None,
- ca_certs=None, strict=None, **kwargs):
- """Constructor.
+def ValidateCertificateHostname(cert, hostname):
+ """Validates that a given hostname is valid for an SSL certificate.
Args:
- host: The hostname. Can be in 'host:port' form.
- port: The port. Defaults to 443.
- key_file: A file containing the client's private key
- cert_file: A file containing the client's certificates
- ca_certs: A file contianing a set of concatenated certificate authority
- certs for validating the server against.
- strict: When true, causes BadStatusLine to be raised if the status line
- can't be parsed as a valid HTTP/1.0 or 1.1 status line.
+ cert: A dictionary representing an SSL certificate.
+ hostname: The hostname to test.
+ Returns:
+ bool: Whether or not the hostname is valid for this certificate.
"""
- if six.PY2:
- # Python 3.2 and newer have deprecated and removed the strict
- # parameter. Since the params are supported as keyword arguments
- # we conditionally add it here.
- kwargs['strict'] = strict
-
- http_client.HTTPConnection.__init__(self, host=host, port=port, **kwargs)
- self.key_file = key_file
- self.cert_file = cert_file
- self.ca_certs = ca_certs
-
- def connect(self):
- "Connect to a host on a given (SSL) port."
- if hasattr(self, "timeout"):
- sock = socket.create_connection((self.host, self.port), self.timeout)
- else:
- sock = socket.create_connection((self.host, self.port))
- msg = "wrapping ssl socket; "
- if self.ca_certs:
- msg += "CA certificate file=%s" %self.ca_certs
- else:
- msg += "using system provided SSL certs"
- boto.log.debug(msg)
- self.sock = ssl.wrap_socket(sock, keyfile=self.key_file,
- certfile=self.cert_file,
- cert_reqs=ssl.CERT_REQUIRED,
- ca_certs=self.ca_certs)
- cert = self.sock.getpeercert()
- hostname = self.host.split(':', 0)[0]
- if not ValidateCertificateHostname(cert, hostname):
- raise InvalidCertificateException(hostname,
- cert,
- 'remote hostname "%s" does not match '\
- 'certificate' % hostname)
+ hosts = GetValidHostsForCert(cert)
+ boto.log.debug(
+ "validating server certificate: hostname=%s, certificate hosts=%s",
+ hostname, hosts)
+ for host in hosts:
+ host_re = host.replace('.', '\.').replace('*', '[^.]*')
+ if re.search('^%s$' % (host_re,), hostname, re.I):
+ return True
+ return False
+class CertValidatingHTTPSConnection(http_client.HTTPConnection):
+ """An HTTPConnection that connects over SSL and validates certificates."""
+
+ default_port = http_client.HTTPS_PORT
+
+ def __init__(self, host, port=default_port, key_file=None, cert_file=None,
+ ca_certs=None, strict=None, **kwargs):
+ """Constructor.
+
+ Args:
+ host: The hostname. Can be in 'host:port' form.
+ port: The port. Defaults to 443.
+ key_file: A file containing the client's private key
+ cert_file: A file containing the client's certificates
+ ca_certs: A file contianing a set of concatenated certificate authority
+ certs for validating the server against.
+ strict: When true, causes BadStatusLine to be raised if the status line
+ can't be parsed as a valid HTTP/1.0 or 1.1 status line.
+ """
+ if six.PY2:
+ # Python 3.2 and newer have deprecated and removed the strict
+ # parameter. Since the params are supported as keyword arguments
+ # we conditionally add it here.
+ kwargs['strict'] = strict
+
+ http_client.HTTPConnection.__init__(self, host=host, port=port, **kwargs)
+ self.key_file = key_file
+ self.cert_file = cert_file
+ self.ca_certs = ca_certs
+
+ def connect(self):
+ "Connect to a host on a given (SSL) port."
+ if hasattr(self, "timeout"):
+ sock = socket.create_connection((self.host, self.port), self.timeout)
+ else:
+ sock = socket.create_connection((self.host, self.port))
+ msg = "wrapping ssl socket; "
+ if self.ca_certs:
+ msg += "CA certificate file=%s" % self.ca_certs
+ else:
+ msg += "using system provided SSL certs"
+ boto.log.debug(msg)
+ self.sock = ssl.wrap_socket(sock, keyfile=self.key_file,
+ certfile=self.cert_file,
+ cert_reqs=ssl.CERT_REQUIRED,
+ ca_certs=self.ca_certs)
+ cert = self.sock.getpeercert()
+ hostname = self.host.split(':', 0)[0]
+ if not ValidateCertificateHostname(cert, hostname):
+ raise InvalidCertificateException(hostname,
+ cert,
+ 'remote hostname "%s" does not match '
+ 'certificate' % hostname)
diff --git a/boto/jsonresponse.py b/boto/jsonresponse.py
index ac3f1b4a..f872b429 100644
--- a/boto/jsonresponse.py
+++ b/boto/jsonresponse.py
@@ -23,6 +23,7 @@
import xml.sax
from boto import utils
+
class XmlHandler(xml.sax.ContentHandler):
def __init__(self, root_node, connection):
@@ -52,7 +53,8 @@ class XmlHandler(xml.sax.ContentHandler):
if not isinstance(s, bytes):
s = s.encode('utf-8')
xml.sax.parseString(s, self)
-
+
+
class Element(dict):
def __init__(self, connection=None, element_name=None,
@@ -116,6 +118,7 @@ class Element(dict):
elif isinstance(self.parent, ListElement):
self.parent.append(value)
+
class ListElement(list):
def __init__(self, connection=None, element_name=None,
diff --git a/boto/plugin.py b/boto/plugin.py
index f8b592cc..2c2931c9 100644
--- a/boto/plugin.py
+++ b/boto/plugin.py
@@ -14,7 +14,7 @@
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
@@ -26,19 +26,20 @@ Implements plugin related api.
To define a new plugin just subclass Plugin, like this.
class AuthPlugin(Plugin):
- pass
+ pass
Then start creating subclasses of your new plugin.
class MyFancyAuth(AuthPlugin):
- capability = ['sign', 'vmac']
+ capability = ['sign', 'vmac']
The actual interface is duck typed.
-
"""
import glob
-import imp, os.path
+import imp
+import os.path
+
class Plugin(object):
"""Base class for all plugins."""
@@ -50,10 +51,11 @@ class Plugin(object):
"""Returns true if the requested capability is supported by this plugin
"""
for c in requested_capability:
- if not c in cls.capability:
+ if c not in cls.capability:
return False
return True
+
def get_plugin(cls, requested_capability=None):
if not requested_capability:
requested_capability = []
@@ -63,18 +65,20 @@ def get_plugin(cls, requested_capability=None):
result.append(handler)
return result
+
def _import_module(filename):
(path, name) = os.path.split(filename)
(name, ext) = os.path.splitext(name)
(file, filename, data) = imp.find_module(name, [path])
try:
- return imp.load_module(name, file, filename, data)
+ return imp.load_module(name, file, filename, data)
finally:
- if file:
- file.close()
+ if file:
+ file.close()
+
+_plugin_loaded = False
-_plugin_loaded = False
def load_plugins(config):
global _plugin_loaded
@@ -87,4 +91,3 @@ def load_plugins(config):
directory = config.get('Plugin', 'plugin_directory')
for file in glob.glob(os.path.join(directory, '*.py')):
_import_module(file)
-
diff --git a/boto/provider.py b/boto/provider.py
index 8e04bff3..0da2f78a 100644
--- a/boto/provider.py
+++ b/boto/provider.py
@@ -69,7 +69,8 @@ STORAGE_PERMISSIONS_ERROR = 'StoragePermissionsError'
STORAGE_RESPONSE_ERROR = 'StorageResponseError'
-class ProfileNotFoundError(ValueError): pass
+class ProfileNotFoundError(ValueError):
+ pass
class Provider(object):
@@ -252,7 +253,7 @@ class Provider(object):
# datetime docs.
seconds_left = (
(delta.microseconds + (delta.seconds + delta.days * 24 * 3600)
- * 10**6) / 10**6)
+ * 10 ** 6) / 10 ** 6)
if seconds_left < (5 * 60):
boto.log.debug("Credentials need to be refreshed.")
return True
@@ -444,6 +445,7 @@ class Provider(object):
def supports_chunked_transfer(self):
return self.ChunkedTransferSupport[self.name]
+
# Static utility method for getting default Provider.
def get_default():
return Provider('aws')
diff --git a/boto/regioninfo.py b/boto/regioninfo.py
index 5862f16d..6aeda122 100644
--- a/boto/regioninfo.py
+++ b/boto/regioninfo.py
@@ -124,7 +124,7 @@ def get_regions(service_name, region_cls=None, connection_cls=None):
"""
endpoints = load_regions()
- if not service_name in endpoints:
+ if service_name not in endpoints:
raise BotoClientError(
"Service '%s' not found in endpoints." % service_name
)
diff --git a/boto/requestlog.py b/boto/requestlog.py
index 5f1c2551..d8009fe7 100644
--- a/boto/requestlog.py
+++ b/boto/requestlog.py
@@ -1,9 +1,11 @@
-
+import sys
from datetime import datetime
from threading import Thread
import Queue
from boto.utils import RequestHook
+from boto.compat import long_type
+
class RequestLogger(RequestHook):
"""
@@ -14,18 +16,16 @@ class RequestLogger(RequestHook):
self.request_log_file = open(filename, 'w')
self.request_log_queue = Queue.Queue(100)
Thread(target=self._request_log_worker).start()
-
def handle_request_data(self, request, response, error=False):
len = 0 if error else response.getheader('Content-Length')
now = datetime.now()
time = now.strftime('%Y-%m-%d %H:%M:%S')
td = (now - request.start_time)
- duration = (td.microseconds + long(td.seconds + td.days*24*3600) * 1e6) / 1e6
-
+ duration = (td.microseconds + long_type(td.seconds + td.days * 24 * 3600) * 1e6) / 1e6
+
# write output including timestamp, status code, response time, response size, request action
self.request_log_queue.put("'%s', '%s', '%s', '%s', '%s'\n" % (time, response.status, duration, len, request.params['Action']))
-
def _request_log_worker(self):
while True:
@@ -35,5 +35,5 @@ class RequestLogger(RequestHook):
self.request_log_file.flush()
self.request_log_queue.task_done()
except:
- import traceback; traceback.print_exc(file=sys.stdout)
-
+ import traceback
+ traceback.print_exc(file=sys.stdout)
diff --git a/boto/resultset.py b/boto/resultset.py
index 83052582..189a47a3 100644
--- a/boto/resultset.py
+++ b/boto/resultset.py
@@ -21,14 +21,15 @@
from boto.s3.user import User
+
class ResultSet(list):
"""
The ResultSet is used to pass results back from the Amazon services
to the client. It is light wrapper around Python's :py:class:`list` class,
- with some additional methods for parsing XML results from AWS.
- Because I don't really want any dependencies on external libraries,
- I'm using the standard SAX parser that comes with Python. The good news is
- that it's quite fast and efficient but it makes some things rather
+ with some additional methods for parsing XML results from AWS.
+ Because I don't really want any dependencies on external libraries,
+ I'm using the standard SAX parser that comes with Python. The good news is
+ that it's quite fast and efficient but it makes some things rather
difficult.
You can pass in, as the marker_elem parameter, a list of tuples.
@@ -54,7 +55,7 @@ class ResultSet(list):
self.next_key_marker = None
self.next_upload_id_marker = None
self.next_version_id_marker = None
- self.next_generation_marker= None
+ self.next_generation_marker = None
self.version_id_marker = None
self.is_truncated = False
self.next_token = None
@@ -132,6 +133,7 @@ class ResultSet(list):
else:
setattr(self, name, value)
+
class BooleanResult(object):
def __init__(self, marker_elem=None):
diff --git a/boto/storage_uri.py b/boto/storage_uri.py
index 40fee473..34b7b060 100755
--- a/boto/storage_uri.py
+++ b/boto/storage_uri.py
@@ -87,8 +87,8 @@ class StorageUri(object):
for arg in args:
if args[arg]:
sys.stderr.write(
- 'Warning: %s ignores argument: %s=%s\n' %
- (function_name, arg, str(args[arg])))
+ 'Warning: %s ignores argument: %s=%s\n' %
+ (function_name, arg, str(args[arg])))
def connect(self, access_key_id=None, secret_access_key=None, **kwargs):
"""
@@ -103,7 +103,7 @@ class StorageUri(object):
connection_args = dict(self.connection_args or ())
if (hasattr(self, 'suppress_consec_slashes') and
- 'suppress_consec_slashes' not in connection_args):
+ 'suppress_consec_slashes' not in connection_args):
connection_args['suppress_consec_slashes'] = (
self.suppress_consec_slashes)
connection_args.update(kwargs)
@@ -167,7 +167,7 @@ class StorageUri(object):
if all_versions:
return (v for v in bucket.list_versions(
prefix=prefix, delimiter=delimiter, headers=headers)
- if not isinstance(v, DeleteMarker))
+ if not isinstance(v, DeleteMarker))
else:
return bucket.list(prefix=prefix, delimiter=delimiter,
headers=headers)
@@ -247,7 +247,7 @@ class BucketStorageUri(StorageUri):
"""
delim = '/'
- capabilities = set([]) # A set of additional capabilities.
+ capabilities = set([]) # A set of additional capabilities.
def __init__(self, scheme, bucket_name=None, object_name=None,
debug=0, connection_args=None, suppress_consec_slashes=True,
@@ -299,37 +299,37 @@ class BucketStorageUri(StorageUri):
self._build_uri_strings()
def _build_uri_strings(self):
- if self.bucket_name and self.object_name:
- self.versionless_uri = '%s://%s/%s' % (self.scheme, self.bucket_name,
- self.object_name)
- if self.generation:
- self.version_specific_uri = '%s#%s' % (self.versionless_uri,
- self.generation)
- elif self.version_id:
- self.version_specific_uri = '%s#%s' % (
- self.versionless_uri, self.version_id)
- if self.is_version_specific:
- self.uri = self.version_specific_uri
- else:
- self.uri = self.versionless_uri
- elif self.bucket_name:
- self.uri = ('%s://%s/' % (self.scheme, self.bucket_name))
- else:
- self.uri = ('%s://' % self.scheme)
+ if self.bucket_name and self.object_name:
+ self.versionless_uri = '%s://%s/%s' % (self.scheme, self.bucket_name,
+ self.object_name)
+ if self.generation:
+ self.version_specific_uri = '%s#%s' % (self.versionless_uri,
+ self.generation)
+ elif self.version_id:
+ self.version_specific_uri = '%s#%s' % (
+ self.versionless_uri, self.version_id)
+ if self.is_version_specific:
+ self.uri = self.version_specific_uri
+ else:
+ self.uri = self.versionless_uri
+ elif self.bucket_name:
+ self.uri = ('%s://%s/' % (self.scheme, self.bucket_name))
+ else:
+ self.uri = ('%s://' % self.scheme)
def _update_from_key(self, key):
- self._update_from_values(
- getattr(key, 'version_id', None),
- getattr(key, 'generation', None),
- getattr(key, 'is_latest', None),
- getattr(key, 'md5', None))
+ self._update_from_values(
+ getattr(key, 'version_id', None),
+ getattr(key, 'generation', None),
+ getattr(key, 'is_latest', None),
+ getattr(key, 'md5', None))
def _update_from_values(self, version_id, generation, is_latest, md5):
- self.version_id = version_id
- self.generation = generation
- self.is_latest = is_latest
- self._build_uri_strings()
- self.md5 = md5
+ self.version_id = version_id
+ self.generation = generation
+ self.is_latest = is_latest
+ self._build_uri_strings()
+ self.md5 = md5
def get_key(self, validate=False, headers=None, version_id=None):
self._check_object_uri('get_key')
@@ -388,14 +388,14 @@ class BucketStorageUri(StorageUri):
is_latest = key.is_latest
return BucketStorageUri(
- key.provider.get_provider_name(),
- bucket_name=key.bucket.name,
- object_name=key.name,
- debug=self.debug,
- suppress_consec_slashes=self.suppress_consec_slashes,
- version_id=version_id,
- generation=generation,
- is_latest=is_latest)
+ key.provider.get_provider_name(),
+ bucket_name=key.bucket.name,
+ object_name=key.name,
+ debug=self.debug,
+ suppress_consec_slashes=self.suppress_consec_slashes,
+ version_id=version_id,
+ generation=generation,
+ is_latest=is_latest)
def get_acl(self, validate=False, headers=None, version_id=None):
"""returns a bucket's acl"""
@@ -464,8 +464,8 @@ class BucketStorageUri(StorageUri):
'URIs.' % self.scheme)
if self.object_name:
if recursive:
- raise ValueError('add_group_email_grant() on key-ful URI cannot '
- 'specify recursive=True')
+ raise ValueError('add_group_email_grant() on key-ful URI cannot '
+ 'specify recursive=True')
key = self.get_key(validate, headers)
self.check_response(key, 'key', self.uri)
key.add_group_email_grant(permission, email_address, headers)
@@ -556,10 +556,10 @@ class BucketStorageUri(StorageUri):
# Pass storage_class param only if this is a GCS bucket. (In S3 the
# storage class is specified on the key object.)
if self.scheme == 'gs':
- return conn.create_bucket(self.bucket_name, headers, location, policy,
- storage_class)
+ return conn.create_bucket(self.bucket_name, headers, location, policy,
+ storage_class)
else:
- return conn.create_bucket(self.bucket_name, headers, location, policy)
+ return conn.create_bucket(self.bucket_name, headers, location, policy)
def delete_bucket(self, headers=None):
self._check_bucket_uri('delete_bucket')
@@ -583,27 +583,27 @@ class BucketStorageUri(StorageUri):
key_name = key_name or self.object_name or ''
bucket = self.get_bucket(validate, headers)
if self.generation:
- bucket.set_acl(
- acl_or_str, key_name, headers, generation=self.generation,
- if_generation=if_generation, if_metageneration=if_metageneration)
+ bucket.set_acl(
+ acl_or_str, key_name, headers, generation=self.generation,
+ if_generation=if_generation, if_metageneration=if_metageneration)
else:
- version_id = version_id or self.version_id
- bucket.set_acl(acl_or_str, key_name, headers, version_id)
+ version_id = version_id or self.version_id
+ bucket.set_acl(acl_or_str, key_name, headers, version_id)
def set_xml_acl(self, xmlstring, key_name='', validate=False, headers=None,
- version_id=None, if_generation=None, if_metageneration=None):
+ version_id=None, if_generation=None, if_metageneration=None):
"""Sets or updates a bucket's ACL with an XML string."""
self._check_bucket_uri('set_xml_acl')
key_name = key_name or self.object_name or ''
bucket = self.get_bucket(validate, headers)
if self.generation:
- bucket.set_xml_acl(
- xmlstring, key_name, headers, generation=self.generation,
- if_generation=if_generation, if_metageneration=if_metageneration)
+ bucket.set_xml_acl(
+ xmlstring, key_name, headers, generation=self.generation,
+ if_generation=if_generation, if_metageneration=if_metageneration)
else:
- version_id = version_id or self.version_id
- bucket.set_xml_acl(xmlstring, key_name, headers,
- version_id=version_id)
+ version_id = version_id or self.version_id
+ bucket.set_xml_acl(xmlstring, key_name, headers,
+ version_id=version_id)
def set_def_xml_acl(self, xmlstring, validate=False, headers=None):
"""Sets or updates a bucket's default object ACL with an XML string."""
@@ -699,14 +699,16 @@ class BucketStorageUri(StorageUri):
self._check_object_uri('copy_key')
dst_bucket = self.get_bucket(validate=False, headers=headers)
if src_generation:
- return dst_bucket.copy_key(new_key_name=self.object_name,
+ return dst_bucket.copy_key(
+ new_key_name=self.object_name,
src_bucket_name=src_bucket_name,
src_key_name=src_key_name, metadata=metadata,
storage_class=storage_class, preserve_acl=preserve_acl,
encrypt_key=encrypt_key, headers=headers, query_args=query_args,
src_generation=src_generation)
else:
- return dst_bucket.copy_key(new_key_name=self.object_name,
+ return dst_bucket.copy_key(
+ new_key_name=self.object_name,
src_bucket_name=src_bucket_name, src_key_name=src_key_name,
metadata=metadata, src_version_id=src_version_id,
storage_class=storage_class, preserve_acl=preserve_acl,
@@ -766,7 +768,7 @@ class BucketStorageUri(StorageUri):
component_keys.append(suri.new_key())
component_keys[-1].generation = suri.generation
self.generation = self.new_key().compose(
- component_keys, content_type=content_type, headers=headers)
+ component_keys, content_type=content_type, headers=headers)
self._build_uri_strings()
return self
@@ -786,12 +788,13 @@ class BucketStorageUri(StorageUri):
bucket.configure_lifecycle(lifecycle_config, headers)
def exists(self, headers=None):
- """Returns True if the object exists or False if it doesn't"""
- if not self.object_name:
- raise InvalidUriError('exists on object-less URI (%s)' % self.uri)
- bucket = self.get_bucket()
- key = bucket.get_key(self.object_name, headers=headers)
- return bool(key)
+ """Returns True if the object exists or False if it doesn't"""
+ if not self.object_name:
+ raise InvalidUriError('exists on object-less URI (%s)' % self.uri)
+ bucket = self.get_bucket()
+ key = bucket.get_key(self.object_name, headers=headers)
+ return bool(key)
+
class FileStorageUri(StorageUri):
"""
@@ -881,8 +884,8 @@ class FileStorageUri(StorageUri):
self.get_key().close()
def exists(self, _headers_not_used=None):
- """Returns True if the file exists or False if it doesn't"""
- # The _headers_not_used parameter is ignored. It is only there to ensure
- # that this method's signature is identical to the exists method on the
- # BucketStorageUri class.
- return os.path.exists(self.object_name)
+ """Returns True if the file exists or False if it doesn't"""
+ # The _headers_not_used parameter is ignored. It is only there to ensure
+ # that this method's signature is identical to the exists method on the
+ # BucketStorageUri class.
+ return os.path.exists(self.object_name)
diff --git a/boto/utils.py b/boto/utils.py
index dca332fe..0e7e3a79 100644
--- a/boto/utils.py
+++ b/boto/utils.py
@@ -392,7 +392,7 @@ def get_instance_metadata(version='latest', url='http://169.254.169.254',
try:
metadata_url = _build_instance_metadata_url(url, version, data)
return _get_instance_metadata(metadata_url, num_retries=num_retries, timeout=timeout)
- except urllib.error.URLError as e:
+ except urllib.error.URLError:
return None
@@ -414,7 +414,7 @@ def get_instance_identity(version='latest', url='http://169.254.169.254',
if field:
iid[field] = val
return iid
- except urllib.error.URLError as e:
+ except urllib.error.URLError:
return None
@@ -436,6 +436,7 @@ ISO8601_MS = '%Y-%m-%dT%H:%M:%S.%fZ'
RFC1123 = '%a, %d %b %Y %H:%M:%S %Z'
LOCALE_LOCK = threading.Lock()
+
@contextmanager
def setlocale(name):
"""
@@ -449,6 +450,7 @@ def setlocale(name):
finally:
locale.setlocale(locale.LC_ALL, saved)
+
def get_ts(ts=None):
if not ts:
ts = time.gmtime()
@@ -1038,6 +1040,7 @@ def merge_headers_by_name(name, headers):
return ','.join(str(headers[h]) for h in matching_headers
if headers[h] is not None)
+
class RequestHook(object):
"""
This can be extended and supplied to the connection object
diff --git a/scripts/git-release-notes.py b/scripts/git-release-notes.py
index 6655b61c..5b6faaaf 100755
--- a/scripts/git-release-notes.py
+++ b/scripts/git-release-notes.py
@@ -30,7 +30,7 @@ for hunk in revisions.split('~~~')[:-1]:
parents = lines[1].split(' ', 1)[1].split(' ')
message = ' '.join(lines[2:])
- #print(commit, parents)
+ # print(commit, parents)
if RELEASE.search(message):
print('Found release commit, stopping:')
diff --git a/scripts/rebuild_endpoints.py b/scripts/rebuild_endpoints.py
index f5f12809..37ac37d8 100644
--- a/scripts/rebuild_endpoints.py
+++ b/scripts/rebuild_endpoints.py
@@ -19,6 +19,7 @@ def fetch_endpoints():
return resp.text
+
def parse_xml(raw_xml):
return pq(raw_xml, parser='xml')
diff --git a/tests/__init__.py b/tests/__init__.py
index b3fc3a0c..771ca94b 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -14,7 +14,7 @@
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py
index ed359279..f03a609b 100644
--- a/tests/integration/__init__.py
+++ b/tests/integration/__init__.py
@@ -24,6 +24,7 @@
Base class to make checking the certs easier.
"""
+
# We subclass from ``object`` instead of ``TestCase`` here so that this doesn't
# add noise to the test suite (otherwise these no-ops would run on every
# import).
@@ -60,4 +61,3 @@ class ServiceCertVerificationTest(object):
always succeed (like fetch a list, even if it's empty).
"""
pass
-
diff --git a/tests/test.py b/tests/test.py
index 7e91af35..692ed4dd 100755
--- a/tests/test.py
+++ b/tests/test.py
@@ -71,6 +71,7 @@ PY3_WHITELIST = (
'tests/unit/test_regioninfo.py',
)
+
def main(whitelist=[]):
description = ("Runs boto unit and/or integration tests. "
"Arguments will be passed on to nosetests. "
@@ -83,7 +84,7 @@ def main(whitelist=[]):
known_args, remaining_args = parser.parse_known_args()
attribute_args = []
for service_attribute in known_args.service_tests:
- attribute_args.extend(['-a', '!notdefault,' +service_attribute])
+ attribute_args.extend(['-a', '!notdefault,' + service_attribute])
if not attribute_args:
# If the user did not specify any filtering criteria, we at least
# will filter out any test tagged 'notdefault'.
diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py
index 56d386f8..9751decd 100644
--- a/tests/unit/__init__.py
+++ b/tests/unit/__init__.py
@@ -1,6 +1,7 @@
from boto.compat import http_client
from tests.compat import mock, unittest
+
class AWSMockServiceTestCase(unittest.TestCase):
"""Base class for mocking aws services."""
# This param is used by the unittest module to display a full
@@ -46,6 +47,7 @@ class AWSMockServiceTestCase(unittest.TestCase):
response.getheaders.return_value = header
response.msg = dict(header)
+
def overwrite_header(arg, default=None):
header_dict = dict(header)
if arg in header_dict:
diff --git a/tests/unit/test_connection.py b/tests/unit/test_connection.py
index 97514361..432e44e9 100644
--- a/tests/unit/test_connection.py
+++ b/tests/unit/test_connection.py
@@ -72,6 +72,7 @@ class MockAWSService(AWSQueryConnection):
"""
APIVersion = '2012-01-01'
+
def _required_auth_capability(self):
return ['sign-v2']
@@ -95,6 +96,7 @@ class MockAWSService(AWSQueryConnection):
validate_certs=validate_certs,
profile_name=profile_name)
+
class TestAWSAuthConnection(unittest.TestCase):
def test_get_path(self):
conn = AWSAuthConnection(
@@ -182,8 +184,9 @@ class TestAWSAuthConnection(unittest.TestCase):
'testhost',
aws_access_key_id='access_key',
aws_secret_access_key='secret')
- request = conn.build_base_http_request(method='POST', path='/',
- auth_path=None, params=None, headers=None, data='', host=None)
+ request = conn.build_base_http_request(
+ method='POST', path='/', auth_path=None, params=None, headers=None,
+ data='', host=None)
conn.set_host_header(request)
self.assertEqual(request.headers['Host'], 'testhost')
@@ -193,15 +196,17 @@ class TestAWSAuthConnection(unittest.TestCase):
aws_access_key_id='access_key',
aws_secret_access_key='secret',
port=8773)
- request = conn.build_base_http_request(method='POST', path='/',
- auth_path=None, params=None, headers=None, data='', host=None)
+ request = conn.build_base_http_request(
+ method='POST', path='/', auth_path=None, params=None, headers=None,
+ data='', host=None)
conn.set_host_header(request)
self.assertEqual(request.headers['Host'], 'testhost:8773')
+
class V4AuthConnection(AWSAuthConnection):
def __init__(self, host, aws_access_key_id, aws_secret_access_key, port=443):
- AWSAuthConnection.__init__(self, host, aws_access_key_id,
- aws_secret_access_key, port=port)
+ AWSAuthConnection.__init__(
+ self, host, aws_access_key_id, aws_secret_access_key, port=port)
def _required_auth_capability(self):
return ['hmac-v4']
@@ -209,15 +214,17 @@ class V4AuthConnection(AWSAuthConnection):
class TestAWSQueryConnection(unittest.TestCase):
def setUp(self):
- self.region = RegionInfo(name='cc-zone-1',
- endpoint='mockservice.cc-zone-1.amazonaws.com',
- connection_cls=MockAWSService)
+ self.region = RegionInfo(
+ name='cc-zone-1',
+ endpoint='mockservice.cc-zone-1.amazonaws.com',
+ connection_cls=MockAWSService)
HTTPretty.enable()
def tearDown(self):
HTTPretty.disable()
+
class TestAWSQueryConnectionSimple(TestAWSQueryConnection):
def test_query_connection_basis(self):
HTTPretty.register_uri(HTTPretty.POST,
@@ -263,7 +270,7 @@ class TestAWSQueryConnectionSimple(TestAWSQueryConnection):
aws_secret_access_key='secret',
proxy="NON_EXISTENT_HOSTNAME",
proxy_port="3128",
- is_secure = False)
+ is_secure=False)
resp = conn.make_request('myCmd',
{'par1': 'foo', 'par2': 'baz'},
@@ -453,7 +460,7 @@ class TestAWSQueryStatus(TestAWSQueryConnection):
content_type='text/xml')
conn = self.region.connect(aws_access_key_id='access_key',
- aws_secret_access_key='secret')
+ aws_secret_access_key='secret')
with self.assertRaises(BotoServerError):
resp = conn.get_status('getStatus',
{'par1': 'foo', 'par2': 'baz'},
diff --git a/tests/unit/test_exception.py b/tests/unit/test_exception.py
index a14f0dca..d9a2bdd3 100644
--- a/tests/unit/test_exception.py
+++ b/tests/unit/test_exception.py
@@ -4,6 +4,7 @@ from boto.exception import BotoServerError, S3CreateError, JSONResponseError
from httpretty import HTTPretty, httprettified
+
class TestBotoServerError(unittest.TestCase):
def test_botoservererror_basics(self):
@@ -45,7 +46,8 @@ class TestBotoServerError(unittest.TestCase):
<RequestID>e73bb2bb-63e3-9cdc-f220-6332de66dbbe</RequestID>
</Response>"""
bse = BotoServerError('403', 'Forbidden', body=xml)
- self.assertEqual(bse.error_message,
+ self.assertEqual(
+ bse.error_message,
'Session does not have permission to perform (sdb:CreateDomain) on '
'resource (arn:aws:sdb:us-east-1:xxxxxxx:domain/test_domain). '
'Contact account owner.')
@@ -84,18 +86,19 @@ class TestBotoServerError(unittest.TestCase):
self.assertEqual(s3ce.error_code, 'BucketAlreadyOwnedByYou')
self.assertEqual(s3ce.status, '409')
self.assertEqual(s3ce.reason, 'Conflict')
- self.assertEqual(s3ce.error_message,
- 'Your previous request to create the named bucket succeeded '
- 'and you already own it.')
+ self.assertEqual(
+ s3ce.error_message,
+ 'Your previous request to create the named bucket succeeded '
+ 'and you already own it.')
self.assertEqual(s3ce.error_message, s3ce.message)
self.assertEqual(s3ce.request_id, 'FF8B86A32CC3FE4F')
def test_message_json_response_error(self):
# This test comes from https://forums.aws.amazon.com/thread.jspa?messageID=374936
body = {
- '__type': 'com.amazon.coral.validate#ValidationException',
- 'message': 'The attempted filter operation is not supported '
- 'for the provided filter argument count'}
+ '__type': 'com.amazon.coral.validate#ValidationException',
+ 'message': 'The attempted filter operation is not supported '
+ 'for the provided filter argument count'}
jre = JSONResponseError('400', 'Bad Request', body=body)
diff --git a/tests/unit/test_regioninfo.py b/tests/unit/test_regioninfo.py
index 0f492788..c46614d4 100644
--- a/tests/unit/test_regioninfo.py
+++ b/tests/unit/test_regioninfo.py
@@ -23,8 +23,6 @@ import os
from tests.unit import unittest
import boto
-from boto.compat import json
-from boto.exception import BotoServerError
from boto.regioninfo import RegionInfo, load_endpoint_json, merge_endpoints
from boto.regioninfo import load_regions, get_regions