Skip to content

Commit

Permalink
fix!: drop python 2.7 support (#103)
Browse files Browse the repository at this point in the history
Drop 'mock' shim

Drop 'six'

Drop explicit 'u"' prefix

Drop 'pytz'

Expand ranges to allow 2.x versions of 'google-auth' / `google-api-core`.

Release-As: 2.0.0b1

Closes #102
  • Loading branch information
tseaver committed Aug 2, 2021
1 parent cef8fba commit 181d706
Show file tree
Hide file tree
Showing 19 changed files with 114 additions and 264 deletions.
8 changes: 3 additions & 5 deletions CONTRIBUTING.rst
Expand Up @@ -22,7 +22,7 @@ In order to add a feature:
documentation.

- The feature must work fully on the following CPython versions:
2.7, 3.6, 3.7, 3.8 and 3.9 on both UNIX and Windows.
3.6, 3.7, 3.8 and 3.9 on both UNIX and Windows.

- The feature must not add unnecessary dependencies (where
"unnecessary" is of course subjective, but new dependencies should
Expand Down Expand Up @@ -148,7 +148,7 @@ Running System Tests

.. note::

System tests are only configured to run under Python 2.7 and 3.8.
System tests are only configured to run under Python 3.8.
For expediency, we do not run them in older versions of Python 3.

This alone will not run the tests. You'll need to change some local
Expand Down Expand Up @@ -221,13 +221,11 @@ Supported Python Versions

We support:

- `Python 2.7`_
- `Python 3.6`_
- `Python 3.7`_
- `Python 3.8`_
- `Python 3.9`_

.. _Python 2.7: https://docs.python.org/2.7/
.. _Python 3.6: https://docs.python.org/3.6/
.. _Python 3.7: https://docs.python.org/3.7/
.. _Python 3.8: https://docs.python.org/3.8/
Expand All @@ -239,7 +237,7 @@ Supported versions can be found in our ``noxfile.py`` `config`_.
.. _config: https://github.com/googleapis/python-cloud-core/blob/master/noxfile.py


We also explicitly decided to support Python 3 beginning with version 2.7.
We also explicitly decided to support Python 3 beginning with version 3.6.
Reasons for this include:

- Encouraging use of newest versions of Python 3
Expand Down
7 changes: 4 additions & 3 deletions README.rst
Expand Up @@ -34,6 +34,7 @@ Supported Python Versions
-------------------------
Python >= 3.6

Deprecated Python Versions
--------------------------
Python == 2.7. Python 2.7 support will be removed on January 1, 2020.
Unsupported Python Versions
---------------------------
Python == 2.7: the last version of this library which supported Python 2.7
is ``google.cloud.core 1.7.2``.
66 changes: 10 additions & 56 deletions google/cloud/_helpers.py
Expand Up @@ -21,13 +21,11 @@

import calendar
import datetime
import http.client
import os
import re
from threading import local as Local

import six
from six.moves import http_client

import google.auth
import google.auth.transport.requests
from google.protobuf import duration_pb2
Expand All @@ -41,6 +39,9 @@


_NOW = datetime.datetime.utcnow # To be replaced by tests.
UTC = datetime.timezone.utc # Singleton instance to be used throughout.
_EPOCH = datetime.datetime(1970, 1, 1, tzinfo=datetime.timezone.utc)

_RFC3339_MICROS = "%Y-%m-%dT%H:%M:%S.%fZ"
_RFC3339_NO_FRACTION = "%Y-%m-%dT%H:%M:%S"
_TIMEONLY_W_MICROS = "%H:%M:%S.%f"
Expand Down Expand Up @@ -111,41 +112,6 @@ def top(self):
return self._stack[-1]


class _UTC(datetime.tzinfo):
"""Basic UTC implementation.
Implementing a small surface area to avoid depending on ``pytz``.
"""

_dst = datetime.timedelta(0)
_tzname = "UTC"
_utcoffset = _dst

def dst(self, dt): # pylint: disable=unused-argument
"""Daylight savings time offset."""
return self._dst

def fromutc(self, dt):
"""Convert a timestamp from (naive) UTC to this timezone."""
if dt.tzinfo is None:
return dt.replace(tzinfo=self)
return super(_UTC, self).fromutc(dt)

def tzname(self, dt): # pylint: disable=unused-argument
"""Get the name of this timezone."""
return self._tzname

def utcoffset(self, dt): # pylint: disable=unused-argument
"""UTC offset of this timezone."""
return self._utcoffset

def __repr__(self):
return "<%s>" % (self._tzname,)

def __str__(self):
return self._tzname


def _ensure_tuple_or_list(arg_name, tuple_or_list):
"""Ensures an input is a tuple or list.
Expand Down Expand Up @@ -344,9 +310,6 @@ def _datetime_to_rfc3339(value, ignore_zone=True):
def _to_bytes(value, encoding="ascii"):
"""Converts a string value to bytes, if necessary.
Unfortunately, ``six.b`` is insufficient for this task since in
Python2 it does not modify ``unicode`` objects.
:type value: str / bytes or unicode
:param value: The string/bytes value to be converted.
Expand All @@ -363,8 +326,8 @@ def _to_bytes(value, encoding="ascii"):
in if it started out as bytes.
:raises TypeError: if the value could not be converted to bytes.
"""
result = value.encode(encoding) if isinstance(value, six.text_type) else value
if isinstance(result, six.binary_type):
result = value.encode(encoding) if isinstance(value, str) else value
if isinstance(result, bytes):
return result
else:
raise TypeError("%r could not be converted to bytes" % (value,))
Expand All @@ -382,8 +345,8 @@ def _bytes_to_unicode(value):
:raises ValueError: if the value could not be converted to unicode.
"""
result = value.decode("utf-8") if isinstance(value, six.binary_type) else value
if isinstance(result, six.text_type):
result = value.decode("utf-8") if isinstance(value, bytes) else value
if isinstance(result, str):
return result
else:
raise ValueError("%r could not be converted to unicode" % (value,))
Expand Down Expand Up @@ -559,7 +522,7 @@ def make_secure_channel(credentials, user_agent, host, extra_options=()):
:rtype: :class:`grpc._channel.Channel`
:returns: gRPC secure channel with credentials attached.
"""
target = "%s:%d" % (host, http_client.HTTPS_PORT)
target = "%s:%d" % (host, http.client.HTTPS_PORT)
http_request = google.auth.transport.requests.Request()

user_agent_option = ("grpc.primary_user_agent", user_agent)
Expand Down Expand Up @@ -621,16 +584,7 @@ def make_insecure_stub(stub_class, host, port=None):
if port is None:
target = host
else:
# NOTE: This assumes port != http_client.HTTPS_PORT:
# NOTE: This assumes port != http.client.HTTPS_PORT:
target = "%s:%d" % (host, port)
channel = grpc.insecure_channel(target)
return stub_class(channel)


try:
from pytz import UTC # pylint: disable=unused-import,wrong-import-order
except ImportError: # pragma: NO COVER
UTC = _UTC() # Singleton instance to be used throughout.

# Need to define _EPOCH at the end of module since it relies on UTC.
_EPOCH = datetime.datetime.utcfromtimestamp(0).replace(tzinfo=UTC)
11 changes: 3 additions & 8 deletions google/cloud/_http.py
Expand Up @@ -15,18 +15,13 @@
"""Shared implementation of connections to API servers."""

import collections

try:
import collections.abc as collections_abc
except ImportError: # Python2
import collections as collections_abc
import collections.abc
import json
import os
import platform
from urllib.parse import urlencode
import warnings

from six.moves.urllib.parse import urlencode

from google.api_core.client_info import ClientInfo
from google.cloud import exceptions
from google.cloud import version
Expand Down Expand Up @@ -263,7 +258,7 @@ def build_api_url(

query_params = query_params or {}

if isinstance(query_params, collections_abc.Mapping):
if isinstance(query_params, collections.abc.Mapping):
query_params = query_params.copy()
else:
query_params_dict = collections.defaultdict(list)
Expand Down
8 changes: 2 additions & 6 deletions google/cloud/_testing.py
Expand Up @@ -117,10 +117,6 @@ def __init__(self, *pages, **kwargs):
self._pages = iter(pages)
self.page_token = kwargs.get("page_token")

def next(self):
def __next__(self):
"""Iterate to the next page."""
import six

return six.next(self._pages)

__next__ = next
return next(self._pages)
6 changes: 2 additions & 4 deletions google/cloud/client.py
Expand Up @@ -19,8 +19,6 @@
import os
from pickle import PicklingError

import six

import google.api_core.client_options
import google.api_core.exceptions
import google.auth
Expand Down Expand Up @@ -271,10 +269,10 @@ def __init__(self, project=None, credentials=None):
"determined from the environment."
)

if isinstance(project, six.binary_type):
if isinstance(project, bytes):
project = project.decode("utf-8")

if not isinstance(project, six.string_types):
if not isinstance(project, str):
raise ValueError("Project must be a string.")

self.project = project
Expand Down
2 changes: 1 addition & 1 deletion google/cloud/version.py
Expand Up @@ -12,4 +12,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.

__version__ = "1.7.2"
__version__ = "2.0.0b1"
6 changes: 2 additions & 4 deletions noxfile.py
Expand Up @@ -60,9 +60,7 @@ def default(session):
)

# Install all test dependencies, then install local packages in-place.
session.install(
"mock", "pytest", "pytest-cov", "grpcio >= 1.0.2", "-c", constraints_path
)
session.install("pytest", "pytest-cov", "grpcio >= 1.0.2", "-c", constraints_path)
session.install("-e", ".", "-c", constraints_path)

# Run py.test against the unit tests.
Expand All @@ -80,7 +78,7 @@ def default(session):
)


@nox.session(python=["2.7", "3.6", "3.7", "3.8", "3.9"])
@nox.session(python=["3.6", "3.7", "3.8", "3.9"])
def unit(session):
"""Default unit test session."""
default(session)
Expand Down
4 changes: 1 addition & 3 deletions owlbot.py
Expand Up @@ -14,8 +14,6 @@

"""This script is used to synthesize generated parts of this library."""

import re

import synthtool as s
from synthtool import gcp

Expand All @@ -24,7 +22,7 @@
# ----------------------------------------------------------------------------
# Add templated files
# ----------------------------------------------------------------------------
templated_files = common.py_library(cov_level=100)
templated_files = common.py_library(microgenerator=True, cov_level=100)
s.move(
templated_files,
excludes=[
Expand Down
11 changes: 3 additions & 8 deletions setup.py
Expand Up @@ -28,11 +28,8 @@
# 'Development Status :: 5 - Production/Stable'
release_status = "Development Status :: 5 - Production/Stable"
dependencies = [
"google-api-core >= 1.21.0, < 2.0.0dev",
"google-auth >= 1.24.0, < 2.0dev",
# Support six==1.12.0 due to App Engine standard runtime.
# https://github.com/googleapis/python-cloud-core/issues/45
"six >=1.12.0",
"google-api-core >= 1.21.0, < 3.0.0dev",
"google-auth >= 1.24.0, < 3.0dev",
]
extras = {"grpc": "grpcio >= 1.8.2, < 2.0dev"}

Expand Down Expand Up @@ -76,8 +73,6 @@
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
Expand All @@ -91,7 +86,7 @@
namespace_packages=namespaces,
install_requires=dependencies,
extras_require=extras,
python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*",
python_requires=">=3.6",
include_package_data=True,
zip_safe=False,
)
3 changes: 0 additions & 3 deletions testing/constraints-2.7.txt

This file was deleted.

2 changes: 0 additions & 2 deletions testing/constraints-3.5.txt

This file was deleted.

3 changes: 1 addition & 2 deletions testing/constraints-3.6.txt
Expand Up @@ -6,5 +6,4 @@
# e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev",
# Then this file should have foo==1.14.0
google-api-core==1.21.0
six==1.12.0
grpcio==1.8.2
grpcio==1.8.2

0 comments on commit 181d706

Please sign in to comment.