Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix!: drop python 2.7 support #103

Merged
merged 26 commits into from Aug 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
fa43f54
fix!: drop support for Python 2.7
tseaver Jun 15, 2021
0dd50f0
fix: drop 'mock' shim
tseaver Jun 15, 2021
a5afb76
fix: drop 'six'
tseaver Jun 15, 2021
18ecab3
fix: drop explicit 'u"' prefix
tseaver Jun 15, 2021
ac1c294
fix: drop 'pytz'
tseaver Jun 15, 2021
83e0bdc
chore: drop installing 'mock' for unittests
tseaver Jun 16, 2021
e399f51
chore: drop Python2-specific alias
tseaver Jun 16, 2021
d1c724b
docs: note unsupported Python versions
tseaver Jun 18, 2021
91262c0
docs: drop references to tests under Python 2.7
tseaver Jun 18, 2021
85775cc
chore: exclude 'CONTRIBUTING.rst' from sync
tseaver Jun 18, 2021
5fb81ae
chore: revert excluding 'CONTRIBUTING.rst' from sync
tseaver Jun 18, 2021
fa4dc90
🦉 Updates from OwlBot
gcf-owl-bot[bot] Jun 18, 2021
5d468ea
chore: bump to latest owlbot image hash
tseaver Jun 18, 2021
edc214f
Merge branch '102-drop-python-2.7' of github.com:googleapis/python-cl…
tseaver Jun 18, 2021
fa1e188
🦉 Updates from OwlBot
gcf-owl-bot[bot] Jun 18, 2021
4b7f24b
Merge branch 'master' into 102-drop-python-2.7
tseaver Jul 14, 2021
e3170d9
chore: switch to microgenerator to avoid 2.7 reappearing
tseaver Jul 14, 2021
dd48c52
Merge branch '102-drop-python-2.7' of github.com:googleapis/python-cl…
tseaver Jul 14, 2021
0e36873
🦉 Updates from OwlBot
gcf-owl-bot[bot] Jul 14, 2021
277100b
chore: expand range to allow 2.x versions of 'google-auth'
tseaver Jul 14, 2021
1ae02ee
Merge branch 'master' into 102-drop-python-2.7
tseaver Jul 23, 2021
1919c3d
Merge branch 'master' into 102-drop-python-2.7
tseaver Jul 27, 2021
48d6e7d
Merge branch 'master' into 102-drop-python-2.7
tseaver Jul 27, 2021
df37b8f
Merge branch 'master' into 102-drop-python-2.7
tseaver Jul 27, 2021
a4b39d0
chore: remove mentions of Python 2.7 from docs
tseaver Aug 1, 2021
8811785
🦉 Updates from OwlBot
gcf-owl-bot[bot] Aug 1, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.
parthea marked this conversation as resolved.
Show resolved Hide resolved

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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same process question - should this be beta or an RC?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I said in googleapis/python-api-core#212, I think a beta is sensible for a semver-major breaking change. I'll let @crwilcox and @busunkim96 chime in on that.

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