Merge pull request #62 from methane/modernize
Run modernize over the codebase (work toward Python 3).
diff --git a/googleapiclient/channel.py b/googleapiclient/channel.py
index 265273e..702186b 100644
--- a/googleapiclient/channel.py
+++ b/googleapiclient/channel.py
@@ -55,12 +55,14 @@
service.channels().stop(channel.body())
"""
+from __future__ import absolute_import
import datetime
import uuid
from googleapiclient import errors
from oauth2client import util
+import six
# The unix time epoch starts at midnight 1970.
@@ -88,7 +90,7 @@
def _upper_header_keys(headers):
new_headers = {}
- for k, v in headers.iteritems():
+ for k, v in six.iteritems(headers):
new_headers[k.upper()] = v
return new_headers
@@ -218,7 +220,7 @@
Args:
resp: dict, The response from a watch() method.
"""
- for json_name, param_name in CHANNEL_PARAMS.iteritems():
+ for json_name, param_name in six.iteritems(CHANNEL_PARAMS):
value = resp.get(json_name)
if value is not None:
setattr(self, param_name, value)
diff --git a/googleapiclient/discovery.py b/googleapiclient/discovery.py
index cbb10db..cdbf140 100644
--- a/googleapiclient/discovery.py
+++ b/googleapiclient/discovery.py
@@ -17,6 +17,8 @@
A client library for Google's discovery based APIs.
"""
from __future__ import absolute_import
+import six
+from six.moves import zip
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
__all__ = [
@@ -254,7 +256,7 @@
# future is no longer used.
future = {}
- if isinstance(service, basestring):
+ if isinstance(service, six.string_types):
service = json.loads(service)
base = urlparse.urljoin(service['rootUrl'], service['servicePath'])
schema = Schemas(service)
@@ -272,7 +274,7 @@
credentials.create_scoped_required()):
scopes = service.get('auth', {}).get('oauth2', {}).get('scopes', {})
if scopes:
- credentials = credentials.create_scoped(scopes.keys())
+ credentials = credentials.create_scoped(list(scopes.keys()))
else:
# No need to authorize the http object
# if the service does not require authentication.
@@ -386,7 +388,7 @@
parameters = method_desc.setdefault('parameters', {})
# Add in the parameters common to all methods.
- for name, description in root_desc.get('parameters', {}).iteritems():
+ for name, description in six.iteritems(root_desc.get('parameters', {})):
parameters[name] = description
# Add in undocumented query parameters.
@@ -569,7 +571,7 @@
comes from the dictionary of methods stored in the 'methods' key in
the deserialized discovery document.
"""
- for arg, desc in method_desc.get('parameters', {}).iteritems():
+ for arg, desc in six.iteritems(method_desc.get('parameters', {})):
param = key2param(arg)
self.argmap[param] = arg
@@ -617,12 +619,12 @@
def method(self, **kwargs):
# Don't bother with doc string, it will be over-written by createMethod.
- for name in kwargs.iterkeys():
+ for name in six.iterkeys(kwargs):
if name not in parameters.argmap:
raise TypeError('Got an unexpected keyword argument "%s"' % name)
# Remove args that have a value of None.
- keys = kwargs.keys()
+ keys = list(kwargs.keys())
for name in keys:
if kwargs[name] is None:
del kwargs[name]
@@ -631,9 +633,9 @@
if name not in kwargs:
raise TypeError('Missing required parameter "%s"' % name)
- for name, regex in parameters.pattern_params.iteritems():
+ for name, regex in six.iteritems(parameters.pattern_params):
if name in kwargs:
- if isinstance(kwargs[name], basestring):
+ if isinstance(kwargs[name], six.string_types):
pvalues = [kwargs[name]]
else:
pvalues = kwargs[name]
@@ -643,13 +645,13 @@
'Parameter "%s" value "%s" does not match the pattern "%s"' %
(name, pvalue, regex))
- for name, enums in parameters.enum_params.iteritems():
+ for name, enums in six.iteritems(parameters.enum_params):
if name in kwargs:
# We need to handle the case of a repeated enum
# name differently, since we want to handle both
# arg='value' and arg=['value1', 'value2']
if (name in parameters.repeated_params and
- not isinstance(kwargs[name], basestring)):
+ not isinstance(kwargs[name], six.string_types)):
values = kwargs[name]
else:
values = [kwargs[name]]
@@ -661,7 +663,7 @@
actual_query_params = {}
actual_path_params = {}
- for key, value in kwargs.iteritems():
+ for key, value in six.iteritems(kwargs):
to_type = parameters.param_types.get(key, 'string')
# For repeated parameters we cast each member of the list.
if key in parameters.repeated_params and type(value) == type([]):
@@ -696,7 +698,7 @@
if media_filename:
# Ensure we end up with a valid MediaUpload object.
- if isinstance(media_filename, basestring):
+ if isinstance(media_filename, six.string_types):
(media_mime_type, encoding) = mimetypes.guess_type(media_filename)
if media_mime_type is None:
raise UnknownFileType(media_filename)
@@ -775,10 +777,10 @@
docs.append('Args:\n')
# Skip undocumented params and params common to all methods.
- skip_parameters = rootDesc.get('parameters', {}).keys()
+ skip_parameters = list(rootDesc.get('parameters', {}).keys())
skip_parameters.extend(STACK_QUERY_PARAMETERS)
- all_args = parameters.argmap.keys()
+ all_args = list(parameters.argmap.keys())
args_ordered = [key2param(s) for s in methodDesc.get('parameterOrder', [])]
# Move body to the front of the line.
@@ -950,7 +952,7 @@
def _add_basic_methods(self, resourceDesc, rootDesc, schema):
# Add basic methods to Resource
if 'methods' in resourceDesc:
- for methodName, methodDesc in resourceDesc['methods'].iteritems():
+ for methodName, methodDesc in six.iteritems(resourceDesc['methods']):
fixedMethodName, method = createMethod(
methodName, methodDesc, rootDesc, schema)
self._set_dynamic_attr(fixedMethodName,
@@ -989,7 +991,7 @@
return (methodName, methodResource)
- for methodName, methodDesc in resourceDesc['resources'].iteritems():
+ for methodName, methodDesc in six.iteritems(resourceDesc['resources']):
fixedMethodName, method = createResourceMethod(methodName, methodDesc)
self._set_dynamic_attr(fixedMethodName,
method.__get__(self, self.__class__))
@@ -999,7 +1001,7 @@
# Look for response bodies in schema that contain nextPageToken, and methods
# that take a pageToken parameter.
if 'methods' in resourceDesc:
- for methodName, methodDesc in resourceDesc['methods'].iteritems():
+ for methodName, methodDesc in six.iteritems(resourceDesc['methods']):
if 'response' in methodDesc:
responseSchema = methodDesc['response']
if '$ref' in responseSchema:
diff --git a/googleapiclient/errors.py b/googleapiclient/errors.py
index e31ffe4..6656bd1 100644
--- a/googleapiclient/errors.py
+++ b/googleapiclient/errors.py
@@ -17,6 +17,7 @@
All exceptions defined by the library
should be defined in this file.
"""
+from __future__ import absolute_import
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
diff --git a/googleapiclient/http.py b/googleapiclient/http.py
index 0edf884..f0e9133 100644
--- a/googleapiclient/http.py
+++ b/googleapiclient/http.py
@@ -19,6 +19,8 @@
actuall HTTP request.
"""
from __future__ import absolute_import
+import six
+from six.moves import range
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
@@ -539,7 +541,7 @@
}
http = self._request.http
- for retry_num in xrange(num_retries + 1):
+ for retry_num in range(num_retries + 1):
if retry_num > 0:
self._sleep(self._rand() * 2**retry_num)
logging.warning(
@@ -709,7 +711,7 @@
self.headers['content-length'] = str(len(self.body))
# Handle retries for server-side errors.
- for retry_num in xrange(num_retries + 1):
+ for retry_num in range(num_retries + 1):
if retry_num > 0:
self._sleep(self._rand() * 2**retry_num)
logging.warning('Retry #%d for request: %s %s, following status: %d'
@@ -792,7 +794,7 @@
start_headers['X-Upload-Content-Length'] = size
start_headers['content-length'] = str(self.body_size)
- for retry_num in xrange(num_retries + 1):
+ for retry_num in range(num_retries + 1):
if retry_num > 0:
self._sleep(self._rand() * 2**retry_num)
logging.warning(
@@ -857,7 +859,7 @@
'Content-Length': str(chunk_end - self.resumable_progress + 1)
}
- for retry_num in xrange(num_retries + 1):
+ for retry_num in range(num_retries + 1):
if retry_num > 0:
self._sleep(self._rand() * 2**retry_num)
logging.warning(
@@ -1101,7 +1103,7 @@
if 'content-type' in headers:
del headers['content-type']
- for key, value in headers.iteritems():
+ for key, value in six.iteritems(headers):
msg[key] = value
msg['Host'] = parsed.netloc
msg.set_unixfrom(None)
@@ -1457,7 +1459,7 @@
if headers is None:
headers = {'status': '200 OK'}
if filename:
- f = file(filename, 'r')
+ f = open(filename, 'r')
self.data = f.read()
f.close()
else:
diff --git a/googleapiclient/mimeparse.py b/googleapiclient/mimeparse.py
index 68d3a3c..bc9ad09 100644
--- a/googleapiclient/mimeparse.py
+++ b/googleapiclient/mimeparse.py
@@ -21,7 +21,9 @@
- best_match(): Choose the mime-type with the highest quality ('q')
from a list of candidates.
"""
+from __future__ import absolute_import
from functools import reduce
+import six
__version__ = '0.1.3'
__author__ = 'Joe Gregorio'
@@ -99,7 +101,7 @@
target_subtype == '*')
if type_match and subtype_match:
param_matches = reduce(lambda x, y: x + y, [1 for (key, value) in \
- target_params.iteritems() if key != 'q' and \
+ six.iteritems(target_params) if key != 'q' and \
key in params and value == params[key]], 0)
fitness = (type == target_type) and 100 or 0
fitness += (subtype == target_subtype) and 10 or 0
diff --git a/googleapiclient/model.py b/googleapiclient/model.py
index e55b4fa..9be5a59 100644
--- a/googleapiclient/model.py
+++ b/googleapiclient/model.py
@@ -20,6 +20,7 @@
object representation.
"""
from __future__ import absolute_import
+import six
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
@@ -105,11 +106,11 @@
if dump_request_response:
logging.info('--request-start--')
logging.info('-headers-start-')
- for h, v in headers.iteritems():
+ for h, v in six.iteritems(headers):
logging.info('%s: %s', h, v)
logging.info('-headers-end-')
logging.info('-path-parameters-start-')
- for h, v in path_params.iteritems():
+ for h, v in six.iteritems(path_params):
logging.info('%s: %s', h, v)
logging.info('-path-parameters-end-')
logging.info('body: %s', body)
@@ -160,13 +161,13 @@
if self.alt_param is not None:
params.update({'alt': self.alt_param})
astuples = []
- for key, value in params.iteritems():
+ for key, value in six.iteritems(params):
if type(value) == type([]):
for x in value:
x = x.encode('utf-8')
astuples.append((key, x))
else:
- if isinstance(value, unicode) and callable(value.encode):
+ if isinstance(value, six.text_type) and callable(value.encode):
value = value.encode('utf-8')
astuples.append((key, value))
return '?' + urllib.urlencode(astuples)
@@ -175,7 +176,7 @@
"""Logs debugging information about the response if requested."""
if dump_request_response:
logging.info('--response-start--')
- for h, v in resp.iteritems():
+ for h, v in six.iteritems(resp):
logging.info('%s: %s', h, v)
if content:
logging.info(content)
@@ -360,7 +361,7 @@
body=makepatch(original, item)).execute()
"""
patch = {}
- for key, original_value in original.iteritems():
+ for key, original_value in six.iteritems(original):
modified_value = modified.get(key, None)
if modified_value is None:
# Use None to signal that the element is deleted
diff --git a/googleapiclient/sample_tools.py b/googleapiclient/sample_tools.py
index 69f698e..3e56c0a 100644
--- a/googleapiclient/sample_tools.py
+++ b/googleapiclient/sample_tools.py
@@ -16,6 +16,7 @@
Consolidates a lot of code commonly repeated in sample applications.
"""
+from __future__ import absolute_import
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
__all__ = ['init']
diff --git a/googleapiclient/schema.py b/googleapiclient/schema.py
index af41317..ecb3f8b 100644
--- a/googleapiclient/schema.py
+++ b/googleapiclient/schema.py
@@ -56,6 +56,8 @@
The constructor takes a discovery document in which to look up named schema.
"""
+from __future__ import absolute_import
+import six
# TODO(jcgregorio) support format, enum, minimum, maximum
@@ -249,7 +251,7 @@
self.emitEnd('{', schema.get('description', ''))
self.indent()
if 'properties' in schema:
- for pname, pschema in schema.get('properties', {}).iteritems():
+ for pname, pschema in six.iteritems(schema.get('properties', {})):
self.emitBegin('"%s": ' % pname)
self._to_str_impl(pschema)
elif 'additionalProperties' in schema:
diff --git a/setup.py b/setup.py
index 40dbc0f..eb5f5f6 100644
--- a/setup.py
+++ b/setup.py
@@ -60,6 +60,7 @@
install_requires = [
'httplib2>=0.8',
'oauth2client>=1.3',
+ 'six>=1.6.1',
'uritemplate>=0.6',
]
diff --git a/tests/__init__.py b/tests/__init__.py
index 7913e6f..c4022b7 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -11,6 +11,7 @@
# limitations under the License.
"""Test Package set up."""
+from __future__ import absolute_import
__author__ = 'afshar@google.com (Ali Afshar)'
diff --git a/tests/test_channel.py b/tests/test_channel.py
index 0e348a5..2651fcd 100644
--- a/tests/test_channel.py
+++ b/tests/test_channel.py
@@ -1,4 +1,5 @@
"""Notification channels tests."""
+from __future__ import absolute_import
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
diff --git a/tests/test_discovery.py b/tests/test_discovery.py
index c16f470..b8cc959 100644
--- a/tests/test_discovery.py
+++ b/tests/test_discovery.py
@@ -20,6 +20,8 @@
Unit tests for objects created from discovery documents.
"""
+from __future__ import absolute_import
+import six
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
@@ -89,9 +91,9 @@
testcase.assertEqual(expected.fragment, actual.fragment)
expected_query = parse_qs(expected.query)
actual_query = parse_qs(actual.query)
- for name in expected_query.keys():
+ for name in list(expected_query.keys()):
testcase.assertEqual(expected_query[name], actual_query[name])
- for name in actual_query.keys():
+ for name in list(actual_query.keys()):
testcase.assertEqual(expected_query[name], actual_query[name])
@@ -133,7 +135,7 @@
self.assertEqual(STACK_QUERY_PARAMETER_DEFAULT_VALUE,
parameters[param_name])
- for param_name, value in root_desc.get('parameters', {}).iteritems():
+ for param_name, value in six.iteritems(root_desc.get('parameters', {})):
self.assertEqual(value, parameters[param_name])
return parameters
@@ -300,7 +302,7 @@
'o': 'object',
'q': 'string',
'rr': 'string'}
- keys = param_types.keys()
+ keys = list(param_types.keys())
self.assertEqual(parameters.argmap, dict((key, key) for key in keys))
self.assertEqual(parameters.required_params, [])
self.assertEqual(sorted(parameters.repeated_params), ['er', 'rr'])
@@ -318,7 +320,7 @@
parameters = ResourceMethodParameters(method_desc)
param_types = {'name': 'string'}
- keys = param_types.keys()
+ keys = list(param_types.keys())
self.assertEqual(parameters.argmap, dict((key, key) for key in keys))
self.assertEqual(parameters.required_params, ['name'])
self.assertEqual(parameters.repeated_params, [])
diff --git a/tests/test_errors.py b/tests/test_errors.py
index efb4afd..0cef892 100644
--- a/tests/test_errors.py
+++ b/tests/test_errors.py
@@ -16,6 +16,7 @@
"""Tests for errors handling
"""
+from __future__ import absolute_import
__author__ = 'afshar@google.com (Ali Afshar)'
diff --git a/tests/test_http.py b/tests/test_http.py
index 8989409..c0ec5f9 100644
--- a/tests/test_http.py
+++ b/tests/test_http.py
@@ -18,6 +18,8 @@
Unit tests for the googleapiclient.http.
"""
+from __future__ import absolute_import
+from six.moves import range
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
@@ -624,7 +626,7 @@
request.execute(num_retries=num_retries)
self.assertEqual(num_retries, len(sleeptimes))
- for retry_num in xrange(num_retries):
+ for retry_num in range(num_retries):
self.assertEqual(10 * 2**(retry_num + 1), sleeptimes[retry_num])
def test_no_retry_fails_fast(self):
diff --git a/tests/test_json_model.py b/tests/test_json_model.py
index af9841a..fec7191 100644
--- a/tests/test_json_model.py
+++ b/tests/test_json_model.py
@@ -18,6 +18,8 @@
Unit tests for the JSON model.
"""
+from __future__ import absolute_import
+import six
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
@@ -214,7 +216,7 @@
def __init__(self, items):
super(MockResponse, self).__init__()
self.status = items['status']
- for key, value in items.iteritems():
+ for key, value in six.iteritems(items):
self[key] = value
old_logging = googleapiclient.model.logging
googleapiclient.model.logging = MockLogging()
diff --git a/tests/test_mocks.py b/tests/test_mocks.py
index e3c550f..34cc8a9 100644
--- a/tests/test_mocks.py
+++ b/tests/test_mocks.py
@@ -18,6 +18,7 @@
Unit tests for the Mocks.
"""
+from __future__ import absolute_import
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
diff --git a/tests/test_model.py b/tests/test_model.py
index 9f29db9..1d48194 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -19,6 +19,7 @@
Unit tests for model utility methods.
"""
+from __future__ import absolute_import
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
diff --git a/tests/test_protobuf_model.py b/tests/test_protobuf_model.py
index fe3abc7..b765943 100644
--- a/tests/test_protobuf_model.py
+++ b/tests/test_protobuf_model.py
@@ -18,6 +18,7 @@
Unit tests for the Protocol Buffer model.
"""
+from __future__ import absolute_import
__author__ = 'mmcdonald@google.com (Matt McDonald)'
diff --git a/tests/test_schema.py b/tests/test_schema.py
index 476575c..eb41adf 100644
--- a/tests/test_schema.py
+++ b/tests/test_schema.py
@@ -13,6 +13,7 @@
# limitations under the License.
"""Unit tests for googleapiclient.schema."""
+from __future__ import absolute_import
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
@@ -48,7 +49,7 @@
class SchemasTest(unittest.TestCase):
def setUp(self):
- f = file(datafile('zoo.json'))
+ f = open(datafile('zoo.json'))
discovery = f.read()
f.close()
discovery = json.loads(discovery)