From 1ce8ca0f5b50eb77fc721548ffb39c8ac26f8fd1 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Wed, 3 Aug 2016 16:33:29 -0400 Subject: [PATCH 1/6] Drop support for Python 2.6. Closes #1607. --- .travis.yml | 1 - CONTRIBUTING.rst | 10 ++++------ setup.py | 1 - tox.ini | 10 ---------- 4 files changed, 4 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 85f146dd3715..6f1f870247e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,6 @@ install: - pip install --upgrade tox script: - - tox -e py26 - tox -e py27 - tox -e py34 - tox -e lint diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 13c46141b4fb..a6378a48791f 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -81,8 +81,8 @@ In order to add a feature to ``gcloud-python``: - The feature must be documented in both the API and narrative documentation (in ``docs/``). -- The feature must work fully on the following CPython versions: 2.6, - and 2.7 on both UNIX and Windows. +- The feature must work fully on the following CPython versions: 2.7 + and 3.4 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should @@ -357,12 +357,10 @@ Supported Python Versions We support: -- `Python 2.6`_ - `Python 2.7`_ - `Python 3.4`_ - `Python 3.5`_ -.. _Python 2.6: https://docs.python.org/2.6/ .. _Python 2.7: https://docs.python.org/2.7/ .. _Python 3.4: https://docs.python.org/3.4/ .. _Python 3.5: https://docs.python.org/3.5/ @@ -378,7 +376,7 @@ and lack of continuous integration `support`_. .. _decreased usage: https://caremad.io/2013/10/a-look-at-pypi-downloads/ .. _support: http://blog.travis-ci.com/2013-11-18-upcoming-build-environment-updates/ -We may `drop 2.6`_ as a supported version as well since Python 2.6 is no +We haved `dropped 2.6`_ as a supported version as well since Python 2.6 is no longer supported by the core development team. We also explicitly decided to support Python 3 beginning with version @@ -392,7 +390,7 @@ We also explicitly decided to support Python 3 beginning with version .. _prominent: https://docs.djangoproject.com/en/1.9/faq/install/#what-python-version-can-i-use-with-django .. _projects: http://flask.pocoo.org/docs/0.10/python3/ .. _Unicode literal support: https://www.python.org/dev/peps/pep-0414/ -.. _drop 2.6: https://github.com/GoogleCloudPlatform/gcloud-python/issues/995 +.. _dropped 2.6: https://github.com/GoogleCloudPlatform/gcloud-python/issues/995 Versioning ---------- diff --git a/setup.py b/setup.py index bd1bacfea065..1a1ce0ef043d 100644 --- a/setup.py +++ b/setup.py @@ -53,7 +53,6 @@ 'License :: OSI Approved :: Apache Software License', 'Operating System :: OS Independent', 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', diff --git a/tox.ini b/tox.ini index 652f57c7f21b..8172e8bfaecc 100644 --- a/tox.ini +++ b/tox.ini @@ -39,16 +39,6 @@ deps = {[testing]deps} {[grpc]deps} -[testenv:py26] -basepython = - python2.6 -deps = - {[testing]deps} -# ordereddict needed for google.protobuf, which doesn't declare it. - ordereddict -setenv = - PYTHONPATH = {toxinidir}/_testing - [testenv:py27-pandas] basepython = python2.7 From 5edab4ba9e7d98ab815d943ec7ec9228ca9e4878 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Thu, 4 Aug 2016 12:01:26 -0400 Subject: [PATCH 2/6] Drop Python 2.6 helper function. 'gcloud._helpers._total_seconds' worked around the fact that 'datetime.timedelta.total_seconds' was not added until Python 2.7. --- gcloud/_helpers.py | 31 ------------------------------ gcloud/bigtable/column_family.py | 3 +-- gcloud/bigtable/happybase/table.py | 3 +-- gcloud/test__helpers.py | 28 --------------------------- 4 files changed, 2 insertions(+), 63 deletions(-) diff --git a/gcloud/_helpers.py b/gcloud/_helpers.py index 3b4f7aabc32f..94fc3773e793 100644 --- a/gcloud/_helpers.py +++ b/gcloud/_helpers.py @@ -22,7 +22,6 @@ import os import re import socket -import sys from threading import local as Local from google.protobuf import timestamp_pb2 @@ -336,36 +335,6 @@ def _millis_from_datetime(value): return _millis(value) -def _total_seconds_backport(offset): - """Backport of timedelta.total_seconds() from python 2.7+. - - :type offset: :class:`datetime.timedelta` - :param offset: A timedelta object. - - :rtype: int - :returns: The total seconds (including microseconds) in the - duration. - """ - seconds = offset.days * 24 * 60 * 60 + offset.seconds - return seconds + offset.microseconds * 1e-6 - - -def _total_seconds(offset): - """Version independent total seconds for a time delta. - - :type offset: :class:`datetime.timedelta` - :param offset: A timedelta object. - - :rtype: int - :returns: The total seconds (including microseconds) in the - duration. - """ - if sys.version_info[:2] < (2, 7): # pragma: NO COVER Python 2.6 - return _total_seconds_backport(offset) - else: - return offset.total_seconds() - - def _rfc3339_to_datetime(dt_str): """Convert a microsecond-precision timetamp to a native datetime. diff --git a/gcloud/bigtable/column_family.py b/gcloud/bigtable/column_family.py index 8aeb0ca8a0fa..166f96ecdb72 100644 --- a/gcloud/bigtable/column_family.py +++ b/gcloud/bigtable/column_family.py @@ -19,7 +19,6 @@ from google.protobuf import duration_pb2 -from gcloud._helpers import _total_seconds from gcloud.bigtable._generated import ( table_pb2 as table_v2_pb2) from gcloud.bigtable._generated import ( @@ -40,7 +39,7 @@ def _timedelta_to_duration_pb(timedelta_val): :rtype: :class:`google.protobuf.duration_pb2.Duration` :returns: A duration object equivalent to the time delta. """ - seconds_decimal = _total_seconds(timedelta_val) + seconds_decimal = timedelta_val.total_seconds() # Truncate the parts other than the integer. seconds = int(seconds_decimal) if seconds_decimal < 0: diff --git a/gcloud/bigtable/happybase/table.py b/gcloud/bigtable/happybase/table.py index 275e0042bf14..e2173cf6bbe3 100644 --- a/gcloud/bigtable/happybase/table.py +++ b/gcloud/bigtable/happybase/table.py @@ -23,7 +23,6 @@ from gcloud._helpers import _datetime_from_microseconds from gcloud._helpers import _microseconds_from_datetime from gcloud._helpers import _to_bytes -from gcloud._helpers import _total_seconds from gcloud.bigtable.column_family import GCRuleIntersection from gcloud.bigtable.column_family import MaxAgeGCRule from gcloud.bigtable.column_family import MaxVersionsGCRule @@ -653,7 +652,7 @@ def _gc_rule_to_dict(gc_rule): if gc_rule is None: result = {} elif isinstance(gc_rule, MaxAgeGCRule): - result = {'time_to_live': _total_seconds(gc_rule.max_age)} + result = {'time_to_live': gc_rule.max_age.total_seconds()} elif isinstance(gc_rule, MaxVersionsGCRule): result = {'max_versions': gc_rule.max_num_versions} elif isinstance(gc_rule, GCRuleIntersection): diff --git a/gcloud/test__helpers.py b/gcloud/test__helpers.py index 35636fdd722a..a4b14f42e325 100644 --- a/gcloud/test__helpers.py +++ b/gcloud/test__helpers.py @@ -494,34 +494,6 @@ def test_it(self): self.assertEqual(self._callFUT(NOW_MICROS), NOW) -class Test__total_seconds_backport(unittest2.TestCase): - - def _callFUT(self, *args, **kwargs): - from gcloud._helpers import _total_seconds_backport - return _total_seconds_backport(*args, **kwargs) - - def test_it(self): - import datetime - offset = datetime.timedelta(seconds=3, - microseconds=140000) - result = self._callFUT(offset) - self.assertEqual(result, 3.14) - - -class Test__total_seconds(unittest2.TestCase): - - def _callFUT(self, *args, **kwargs): - from gcloud._helpers import _total_seconds - return _total_seconds(*args, **kwargs) - - def test_it(self): - import datetime - offset = datetime.timedelta(seconds=1, - microseconds=414000) - result = self._callFUT(offset) - self.assertEqual(result, 1.414) - - class Test__rfc3339_to_datetime(unittest2.TestCase): def _callFUT(self, dt_str): From 8f84ea073b24589327a89368ef7488ebaacbab75 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Thu, 4 Aug 2016 12:03:57 -0400 Subject: [PATCH 3/6] Drop Python 2.6 workaround. --- gcloud/exceptions.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gcloud/exceptions.py b/gcloud/exceptions.py index fffdb1f5c477..f42d2806f3fe 100644 --- a/gcloud/exceptions.py +++ b/gcloud/exceptions.py @@ -36,8 +36,7 @@ class GCloudError(Exception): """ def __init__(self, message, errors=()): - super(GCloudError, self).__init__() - # suppress deprecation warning under 2.6.x + super(GCloudError, self).__init__(message) self.message = message self._errors = errors From d8aa805bc0b0f37df294eaba7df344fbe3676959 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Thu, 4 Aug 2016 12:08:02 -0400 Subject: [PATCH 4/6] Use a dict comprehension. --- gcloud/error_reporting/client.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/gcloud/error_reporting/client.py b/gcloud/error_reporting/client.py index 11ffd0b0fec5..544427d5958a 100644 --- a/gcloud/error_reporting/client.py +++ b/gcloud/error_reporting/client.py @@ -171,11 +171,10 @@ def _send_error_report(self, message, if http_context: http_context_dict = http_context.__dict__ # strip out None values - # once py26 support is dropped this can use dict comprehension - payload['context']['httpContext'] = dict( - (k, v) for (k, v) in six.iteritems(http_context_dict) - if v is not None - ) + payload['context']['httpContext'] = { + key: value for key, value in six.iteritems(http_context_dict) + if value is not None + } if user: payload['context']['user'] = user From 4f5a55ef72efe59fe4c4e3dcc7d8cf0d031408b9 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Thu, 4 Aug 2016 13:57:14 -0400 Subject: [PATCH 5/6] Mention Python 3.5 support as required for feature work. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/2051#discussion_r73561601 --- CONTRIBUTING.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index a6378a48791f..d02a5665e95c 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -81,8 +81,8 @@ In order to add a feature to ``gcloud-python``: - The feature must be documented in both the API and narrative documentation (in ``docs/``). -- The feature must work fully on the following CPython versions: 2.7 - and 3.4 on both UNIX and Windows. +- The feature must work fully on the following CPython versions: 2.7, + 3.4, and 3.5 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should From 28c6fdd2924bc461463aec9dcd6d2e9fe857ffa6 Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Thu, 4 Aug 2016 13:58:27 -0400 Subject: [PATCH 6/6] Typo fix. Addresses: https://github.com/GoogleCloudPlatform/gcloud-python/pull/2051#discussion_r73561734 --- CONTRIBUTING.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index d02a5665e95c..a472a6cc37f4 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -376,7 +376,7 @@ and lack of continuous integration `support`_. .. _decreased usage: https://caremad.io/2013/10/a-look-at-pypi-downloads/ .. _support: http://blog.travis-ci.com/2013-11-18-upcoming-build-environment-updates/ -We haved `dropped 2.6`_ as a supported version as well since Python 2.6 is no +We have `dropped 2.6`_ as a supported version as well since Python 2.6 is no longer supported by the core development team. We also explicitly decided to support Python 3 beginning with version