diff options
author | Daniel G. Taylor <danielgtaylor@gmail.com> | 2014-08-04 15:42:30 -0700 |
---|---|---|
committer | Daniel G. Taylor <danielgtaylor@gmail.com> | 2014-08-04 15:42:30 -0700 |
commit | ff3d8159af3c816303785e023a4182aacb6aabf5 (patch) | |
tree | 3f9ccb173904eecef829d07f9acbddc6e4b444e5 /boto | |
parent | 60603b6514268a76d9f84a8f381fd645271492a8 (diff) | |
parent | 8aea0d3381d22d7dc0a58c488db6f5d429083c9c (diff) | |
download | boto-ff3d8159af3c816303785e023a4182aacb6aabf5.tar.gz |
Merge branch 'release-2.32.1'2.32.1
Conflicts:
docs/source/index.rst
Diffstat (limited to 'boto')
-rw-r--r-- | boto/__init__.py | 2 | ||||
-rw-r--r-- | boto/auth.py | 6 | ||||
-rw-r--r-- | boto/cloudsearch/document.py | 3 | ||||
-rw-r--r-- | boto/compat.py | 10 | ||||
-rw-r--r-- | boto/connection.py | 7 | ||||
-rw-r--r-- | boto/dynamodb/types.py | 8 | ||||
-rw-r--r-- | boto/emr/emrobject.py | 6 | ||||
-rw-r--r-- | boto/fps/connection.py | 1 | ||||
-rw-r--r-- | boto/glacier/concurrent.py | 2 | ||||
-rw-r--r-- | boto/glacier/job.py | 3 | ||||
-rw-r--r-- | boto/glacier/layer1.py | 27 | ||||
-rw-r--r-- | boto/glacier/utils.py | 13 | ||||
-rw-r--r-- | boto/glacier/vault.py | 2 | ||||
-rw-r--r-- | boto/gs/resumable_upload_handler.py | 5 | ||||
-rw-r--r-- | boto/manage/volume.py | 2 | ||||
-rw-r--r-- | boto/mws/connection.py | 5 | ||||
-rw-r--r-- | boto/pyami/config.py | 14 | ||||
-rw-r--r-- | boto/pyami/installers/ubuntu/mysql.py | 4 | ||||
-rw-r--r-- | boto/regioninfo.py | 1 | ||||
-rw-r--r-- | boto/s3/key.py | 12 | ||||
-rw-r--r-- | boto/sdb/db/manager/xmlmanager.py | 5 | ||||
-rw-r--r-- | boto/utils.py | 24 | ||||
-rw-r--r-- | boto/vpc/vpc_peering_connection.py | 2 |
23 files changed, 82 insertions, 82 deletions
diff --git a/boto/__init__.py b/boto/__init__.py index 5b142e97..3d90e901 100644 --- a/boto/__init__.py +++ b/boto/__init__.py @@ -38,7 +38,7 @@ import logging.config from boto.compat import urlparse from boto.exception import InvalidUriError -__version__ = '2.32.0' +__version__ = '2.32.1' Version = __version__ # for backware compatibility # http://bugs.python.org/issue7980 diff --git a/boto/auth.py b/boto/auth.py index 6d431461..6012962a 100644 --- a/boto/auth.py +++ b/boto/auth.py @@ -41,7 +41,7 @@ import sys import time import posixpath -from boto.compat import urllib +from boto.compat import urllib, encodebytes from boto.auth_handler import AuthHandler from boto.exception import BotoClientError @@ -89,7 +89,7 @@ class HmacKeys(object): def sign_string(self, string_to_sign): new_hmac = self._get_hmac() new_hmac.update(string_to_sign.encode('utf-8')) - return base64.encodestring(new_hmac.digest()).decode('utf-8').strip() + return encodebytes(new_hmac.digest()).decode('utf-8').strip() def __getstate__(self): pickled_dict = copy.copy(self.__dict__) @@ -99,7 +99,7 @@ class HmacKeys(object): def __setstate__(self, dct): self.__dict__ = dct - self.update_provider(self._provider.encode('utf-8')) + self.update_provider(self._provider) class AnonAuthHandler(AuthHandler, HmacKeys): diff --git a/boto/cloudsearch/document.py b/boto/cloudsearch/document.py index b5a6b455..0a1d9db2 100644 --- a/boto/cloudsearch/document.py +++ b/boto/cloudsearch/document.py @@ -240,6 +240,9 @@ class CommitResponse(object): raise EncodingError("Illegal Unicode character in document") elif e == "The Content-Length is too long": raise ContentTooLongError("Content was too long") + if 'adds' not in self.content or 'deletes' not in self.content: + raise SearchServiceException("Error indexing documents" + " => %s" % self.content.get('message', '')) else: self.errors = [] diff --git a/boto/compat.py b/boto/compat.py index 21a9193d..a7503f01 100644 --- a/boto/compat.py +++ b/boto/compat.py @@ -29,6 +29,13 @@ except ImportError: import json +# Switch to use encodebytes, which deprecates encodestring in Python 3 +try: + from base64 import encodebytes +except ImportError: + from base64 import encodestring as encodebytes + + # If running in Google App Engine there is no "user" and # os.path.expanduser() will fail. Attempt to detect this case and use a # no-op expanduser function in this case. @@ -45,7 +52,6 @@ from boto.vendored.six import BytesIO, StringIO from boto.vendored.six.moves import filter, http_client, map, _thread, \ urllib, zip from boto.vendored.six.moves.queue import Queue -from boto.vendored.six.moves.configparser import SafeConfigParser from boto.vendored.six.moves.urllib.parse import parse_qs, quote, unquote, \ urlparse, urlsplit from boto.vendored.six.moves.urllib.request import urlopen @@ -54,6 +60,8 @@ if six.PY3: # StandardError was removed, so use the base exception type instead StandardError = Exception long_type = int + from configparser import ConfigParser else: StandardError = StandardError long_type = long + from ConfigParser import SafeConfigParser as ConfigParser diff --git a/boto/connection.py b/boto/connection.py index 9846a879..5fe9c198 100644 --- a/boto/connection.py +++ b/boto/connection.py @@ -42,9 +42,6 @@ """ Handles basic connections to AWS """ -from __future__ import with_statement - -import base64 from datetime import datetime import errno import os @@ -64,7 +61,7 @@ import boto.handler import boto.cacerts from boto import config, UserAgent -from boto.compat import six, http_client, urlparse, quote +from boto.compat import six, http_client, urlparse, quote, encodebytes from boto.exception import AWSConnectionError from boto.exception import BotoClientError from boto.exception import BotoServerError @@ -857,7 +854,7 @@ class AWSAuthConnection(object): return path def get_proxy_auth_header(self): - auth = base64.encodestring(self.proxy_user + ':' + self.proxy_pass) + auth = encodebytes(self.proxy_user + ':' + self.proxy_pass) return {'Proxy-Authorization': 'Basic %s' % auth} def set_host_header(self, request): diff --git a/boto/dynamodb/types.py b/boto/dynamodb/types.py index 5e3bae69..2049c219 100644 --- a/boto/dynamodb/types.py +++ b/boto/dynamodb/types.py @@ -148,10 +148,10 @@ def dynamize_value(val): if six.PY2: class Binary(object): def __init__(self, value): - if isinstance(value, six.text_type): # Support only PY2 for backward compatibility. - value = value.encode('utf-8') - elif not isinstance(value, bytes): + if not isinstance(value, (bytes, six.text_type)): raise TypeError('Value must be a string of binary data!') + if not isinstance(value, bytes): + value = value.encode("utf-8") self.value = value @@ -171,7 +171,7 @@ if six.PY2: return 'Binary(%r)' % self.value def __str__(self): - return self.value.decode('utf-8') + return self.value def __hash__(self): return hash(self.value) diff --git a/boto/emr/emrobject.py b/boto/emr/emrobject.py index 0906bfab..f605834c 100644 --- a/boto/emr/emrobject.py +++ b/boto/emr/emrobject.py @@ -301,7 +301,7 @@ class ClusterSummaryList(EmrObject): class StepConfig(EmrObject): Fields = set([ - 'Jar' + 'Jar', 'MainClass' ]) @@ -434,11 +434,15 @@ class StepSummary(EmrObject): def __init__(self, connection=None): self.connection = connection self.status = None + self.config = None def startElement(self, name, attrs, connection): if name == 'Status': self.status = ClusterStatus() return self.status + elif name == 'Config': + self.config = StepConfig() + return self.config else: return None diff --git a/boto/fps/connection.py b/boto/fps/connection.py index e8124ab2..6dc90a24 100644 --- a/boto/fps/connection.py +++ b/boto/fps/connection.py @@ -23,7 +23,6 @@ import urllib import uuid -from boto.compat import filter, map from boto.connection import AWSQueryConnection from boto.fps.exception import ResponseErrorFactory from boto.fps.response import ResponseFactory diff --git a/boto/glacier/concurrent.py b/boto/glacier/concurrent.py index 93a12d4f..a4f3a224 100644 --- a/boto/glacier/concurrent.py +++ b/boto/glacier/concurrent.py @@ -19,8 +19,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # -from __future__ import with_statement - import os import math import threading diff --git a/boto/glacier/job.py b/boto/glacier/job.py index 097312a1..33e66a19 100644 --- a/boto/glacier/job.py +++ b/boto/glacier/job.py @@ -20,7 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # -from __future__ import with_statement import math import socket @@ -124,7 +123,7 @@ class Job(object): verify_hashes, retry_exceptions) def download_to_fileobj(self, output_file, chunk_size=DefaultPartSize, - verify_hashes=True, + verify_hashes=True, retry_exceptions=(socket.error,)): """Download an archive to a file object. diff --git a/boto/glacier/layer1.py b/boto/glacier/layer1.py index 45a142d8..39136cf0 100644 --- a/boto/glacier/layer1.py +++ b/boto/glacier/layer1.py @@ -89,12 +89,13 @@ class Layer1(AWSAuthConnection): self.region = region self.account_id = account_id super(Layer1, self).__init__(region.endpoint, - aws_access_key_id, aws_secret_access_key, - is_secure, port, proxy, proxy_port, - proxy_user, proxy_pass, debug, - https_connection_factory, - path, provider, security_token, - suppress_consec_slashes, profile_name=profile_name) + aws_access_key_id, aws_secret_access_key, + is_secure, port, proxy, proxy_port, + proxy_user, proxy_pass, debug, + https_connection_factory, + path, provider, security_token, + suppress_consec_slashes, + profile_name=profile_name) def _required_auth_capability(self): return ['hmac-v4'] @@ -107,10 +108,10 @@ class Layer1(AWSAuthConnection): headers['x-amz-glacier-version'] = self.Version uri = '/%s/%s' % (self.account_id, resource) response = super(Layer1, self).make_request(verb, uri, - params=params, - headers=headers, - sender=sender, - data=data) + params=params, + headers=headers, + sender=sender, + data=data) if response.status in ok_responses: return GlacierResponse(response, response_headers) else: @@ -826,9 +827,9 @@ class Layer1(AWSAuthConnection): else: sender = None return self.make_request('POST', uri, headers=headers, - sender=sender, - data=archive, ok_responses=(201,), - response_headers=response_headers) + sender=sender, + data=archive, ok_responses=(201,), + response_headers=response_headers) def _is_file_like(self, archive): return hasattr(archive, 'seek') and hasattr(archive, 'tell') diff --git a/boto/glacier/utils.py b/boto/glacier/utils.py index 21da67ba..98847e3f 100644 --- a/boto/glacier/utils.py +++ b/boto/glacier/utils.py @@ -23,6 +23,8 @@ import hashlib import math import binascii +from boto.compat import six + _MEGABYTE = 1024 * 1024 DEFAULT_PART_SIZE = 4 * _MEGABYTE @@ -122,10 +124,19 @@ def compute_hashes_from_fileobj(fileobj, chunk_size=1024 * 1024): are returned in hex. """ + # Python 3+, not binary + if six.PY3 and hasattr(fileobj, 'mode') and 'b' not in fileobj.mode: + raise ValueError('File-like object must be opened in binary mode!') + linear_hash = hashlib.sha256() chunks = [] - chunk = fileobj.read(chunk_size).encode('utf-8') + chunk = fileobj.read(chunk_size) while chunk: + # It's possible to get a file-like object that has no mode (checked + # above) and returns something other than bytes (e.g. str). So here + # we try to catch that and encode to bytes. + if not isinstance(chunk, bytes): + chunk = chunk.encode(getattr(fileobj, 'encoding', '') or 'utf-8') linear_hash.update(chunk) chunks.append(hashlib.sha256(chunk).digest()) chunk = fileobj.read(chunk_size) diff --git a/boto/glacier/vault.py b/boto/glacier/vault.py index e447c188..45d276ca 100644 --- a/boto/glacier/vault.py +++ b/boto/glacier/vault.py @@ -21,9 +21,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # -from __future__ import with_statement import codecs -from boto.compat import six from boto.glacier.exceptions import UploadArchiveError from boto.glacier.job import Job from boto.glacier.writer import compute_hashes_from_fileobj, \ diff --git a/boto/gs/resumable_upload_handler.py b/boto/gs/resumable_upload_handler.py index 5b88b621..d7443469 100644 --- a/boto/gs/resumable_upload_handler.py +++ b/boto/gs/resumable_upload_handler.py @@ -26,16 +26,13 @@ import re import socket import time import urlparse +from hashlib import md5 from boto import config, UserAgent from boto.connection import AWSAuthConnection from boto.exception import InvalidUriError from boto.exception import ResumableTransferDisposition from boto.exception import ResumableUploadException from boto.s3.keyfile import KeyFile -try: - from hashlib import md5 -except ImportError: - from md5 import md5 """ Handler for Google Cloud Storage resumable uploads. See diff --git a/boto/manage/volume.py b/boto/manage/volume.py index a4fcb5f3..410414c7 100644 --- a/boto/manage/volume.py +++ b/boto/manage/volume.py @@ -18,7 +18,7 @@ # 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. -from __future__ import with_statement, print_function +from __future__ import print_function from boto.sdb.db.model import Model from boto.sdb.db.property import StringProperty, IntegerProperty, ListProperty, ReferenceProperty, CalculatedProperty diff --git a/boto/mws/connection.py b/boto/mws/connection.py index 6759d028..01b0b30b 100644 --- a/boto/mws/connection.py +++ b/boto/mws/connection.py @@ -20,7 +20,6 @@ # IN THE SOFTWARE. import xml.sax import hashlib -import base64 import string import collections from boto.connection import AWSQueryConnection @@ -28,7 +27,7 @@ from boto.exception import BotoServerError import boto.mws.exception import boto.mws.response from boto.handler import XmlHandler -from boto.compat import filter, map, six +from boto.compat import filter, map, six, encodebytes __all__ = ['MWSConnection'] @@ -55,7 +54,7 @@ api_version_path = { 'OffAmazonPayments': ('2013-01-01', 'SellerId', '/OffAmazonPayments/2013-01-01'), } -content_md5 = lambda c: base64.encodestring(hashlib.md5(c).digest()).strip() +content_md5 = lambda c: encodebytes(hashlib.md5(c).digest()).strip() decorated_attrs = ('action', 'response', 'section', 'quota', 'restore', 'version') api_call_map = {} diff --git a/boto/pyami/config.py b/boto/pyami/config.py index 3789113b..37445f85 100644 --- a/boto/pyami/config.py +++ b/boto/pyami/config.py @@ -26,7 +26,7 @@ import warnings import boto -from boto.compat import expanduser, SafeConfigParser, StringIO +from boto.compat import expanduser, ConfigParser, StringIO # By default we use two locations for the boto configurations, @@ -49,12 +49,12 @@ elif 'BOTO_PATH' in os.environ: BotoConfigLocations.append(expanduser(path)) -class Config(SafeConfigParser): +class Config(ConfigParser): def __init__(self, path=None, fp=None, do_load=True): # We don't use ``super`` here, because ``ConfigParser`` still uses # old-style classes. - SafeConfigParser.__init__(self, {'working_dir': '/mnt/pyami', + ConfigParser.__init__(self, {'working_dir': '/mnt/pyami', 'debug': '0'}) if do_load: if path: @@ -95,7 +95,7 @@ class Config(SafeConfigParser): Replace any previous value. If the path doesn't exist, create it. Also add the option the the in-memory config. """ - config = SafeConfigParser() + config = ConfigParser() config.read(path) if not config.has_section(section): config.add_section(section) @@ -139,21 +139,21 @@ class Config(SafeConfigParser): def get(self, section, name, default=None): try: - val = SafeConfigParser.get(self, section, name) + val = ConfigParser.get(self, section, name) except: val = default return val def getint(self, section, name, default=0): try: - val = SafeConfigParser.getint(self, section, name) + val = ConfigParser.getint(self, section, name) except: val = int(default) return val def getfloat(self, section, name, default=0.0): try: - val = SafeConfigParser.getfloat(self, section, name) + val = ConfigParser.getfloat(self, section, name) except: val = float(default) return val diff --git a/boto/pyami/installers/ubuntu/mysql.py b/boto/pyami/installers/ubuntu/mysql.py index 8dd643bf..5b0792ba 100644 --- a/boto/pyami/installers/ubuntu/mysql.py +++ b/boto/pyami/installers/ubuntu/mysql.py @@ -31,7 +31,7 @@ from boto.pyami.installers.ubuntu.installer import Installer import os import boto from boto.utils import ShellCommand -from ConfigParser import SafeConfigParser +from boto.compat import ConfigParser import time ConfigSection = """ @@ -89,7 +89,7 @@ class MySQL(Installer): self.start('mysql') else: #get the password ubuntu expects to use: - config_parser = SafeConfigParser() + config_parser = ConfigParser() config_parser.read('/etc/mysql/debian.cnf') password = config_parser.get('client', 'password') # start the mysql deamon, then mysql with the required grant statement piped into it: diff --git a/boto/regioninfo.py b/boto/regioninfo.py index eee20bbf..5862f16d 100644 --- a/boto/regioninfo.py +++ b/boto/regioninfo.py @@ -20,7 +20,6 @@ # 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. -from __future__ import with_statement import os import boto diff --git a/boto/s3/key.py b/boto/s3/key.py index ec9889b1..9674d356 100644 --- a/boto/s3/key.py +++ b/boto/s3/key.py @@ -20,8 +20,6 @@ # 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. -from __future__ import with_statement - import email.utils import errno import hashlib @@ -31,8 +29,9 @@ import re import base64 import binascii import math +from hashlib import md5 import boto.utils -from boto.compat import BytesIO, six, urllib +from boto.compat import BytesIO, six, urllib, encodebytes from boto.exception import BotoClientError from boto.exception import StorageDataError @@ -45,11 +44,6 @@ from boto.utils import compute_md5, compute_hash from boto.utils import find_matching_headers from boto.utils import merge_headers_by_name -try: - from hashlib import md5 -except ImportError: - from md5 import md5 - class Key(object): """ @@ -211,7 +205,7 @@ class Key(object): from just having a precalculated md5_hexdigest. """ digest = binascii.unhexlify(md5_hexdigest) - base64md5 = base64.encodestring(digest) + base64md5 = encodebytes(digest) if base64md5[-1] == '\n': base64md5 = base64md5[0:-1] return (md5_hexdigest, base64md5) diff --git a/boto/sdb/db/manager/xmlmanager.py b/boto/sdb/db/manager/xmlmanager.py index d19ad088..f457347a 100644 --- a/boto/sdb/db/manager/xmlmanager.py +++ b/boto/sdb/db/manager/xmlmanager.py @@ -22,7 +22,7 @@ import boto from boto.utils import find_class, Password from boto.sdb.db.key import Key from boto.sdb.db.model import Model -from boto.compat import six +from boto.compat import six, encodebytes from datetime import datetime from xml.dom.minidom import getDOMImplementation, parse, parseString, Node @@ -203,8 +203,7 @@ class XMLManager(object): self.enable_ssl = enable_ssl self.auth_header = None if self.db_user: - import base64 - base64string = base64.encodestring('%s:%s' % (self.db_user, self.db_passwd))[:-1] + base64string = encodebytes('%s:%s' % (self.db_user, self.db_passwd))[:-1] authheader = "Basic %s" % base64string self.auth_header = authheader diff --git a/boto/utils.py b/boto/utils.py index 1569209b..dd5f0956 100644 --- a/boto/utils.py +++ b/boto/utils.py @@ -57,25 +57,14 @@ import email.mime.text import email.utils import email.encoders import gzip -import base64 import threading import locale -from boto.compat import six, StringIO, urllib +from boto.compat import six, StringIO, urllib, encodebytes from contextlib import contextmanager -try: - from hashlib import md5 -except ImportError: - from md5 import md5 - - -try: - import hashlib - _hashfn = hashlib.sha512 -except ImportError: - import md5 - _hashfn = md5.md5 +from hashlib import md5, sha512 +_hashfn = sha512 from boto.compat import json @@ -224,6 +213,11 @@ def retry_url(url, retry_on_404=True, num_retries=10): req = urllib.request.Request(url) r = opener.open(req) result = r.read() + + if(not isinstance(result, six.string_types) and + hasattr(result, 'decode')): + result = result.decode('utf-8') + return result except urllib.error.HTTPError as e: code = e.getcode() @@ -1029,7 +1023,7 @@ def compute_hash(fp, buf_size=8192, size=None, hash_algorithm=md5): else: s = fp.read(buf_size) hex_digest = hash_obj.hexdigest() - base64_digest = base64.encodestring(hash_obj.digest()).decode('utf-8') + base64_digest = encodebytes(hash_obj.digest()).decode('utf-8') if base64_digest[-1] == '\n': base64_digest = base64_digest[0:-1] # data_size based on bytes read. diff --git a/boto/vpc/vpc_peering_connection.py b/boto/vpc/vpc_peering_connection.py index d7c11e8e..cdb9af8d 100644 --- a/boto/vpc/vpc_peering_connection.py +++ b/boto/vpc/vpc_peering_connection.py @@ -145,7 +145,7 @@ class VpcPeeringConnection(TaggedEC2Object): setattr(self, name, value) def delete(self): - return self.connection.delete_vpc(self.id) + return self.connection.delete_vpc_peering_connection(self.id) def _update(self, updated): self.__dict__.update(updated.__dict__) |