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 support for Python 2.7 / 3.5 #212

Merged
merged 28 commits into from Aug 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
21ac69a
fix!: drop support for Python 2.7 and 3.5
tseaver Jun 15, 2021
78caa92
chore: drop 'six' module
tseaver Jun 15, 2021
35c8216
chore: drop 'u"' prefixes for text
tseaver Jun 15, 2021
35ba7d3
chore: remove other Python 2.7 workarounds
tseaver Jun 15, 2021
61490f5
chore: drop use of 'pytz'
tseaver Jun 15, 2021
74c6179
Merge branch 'master' into 210-drop-python-2.7
tseaver Jun 16, 2021
6e21b01
tests: scrub more 2.7 / six constraints
tseaver Jun 16, 2021
fe7d454
docs: add section on unspported Python versions to README
tseaver Jun 16, 2021
d77fbb0
chore: drop workaround for Python 2.7
tseaver Jun 16, 2021
440e571
chore: remove 'general_helpers.wraps'
tseaver Jun 16, 2021
90c1bd1
chore: note URL for follow-up issue
tseaver Jun 16, 2021
026ee31
chore: remove Python 2-specific kwargs hack
tseaver Jun 16, 2021
4165633
chore: drop Python2-specific alias
tseaver Jun 16, 2021
ad7b40b
chore: drop Python2-specific aliases
tseaver Jun 16, 2021
dbc234f
chore: drop Python2-specific aliases
tseaver Jun 16, 2021
4d87012
Merge branch 'master' into 210-drop-python-2.7
tseaver Jun 30, 2021
c480784
Merge branch 'master' into 210-drop-python-2.7
tseaver Jul 7, 2021
72d175b
chore: remove 'packaging' dependency
tseaver Jul 7, 2021
01b49c4
Merge branch 'master' into 210-drop-python-2.7
tseaver Jul 14, 2021
0f6a745
🦉 Updates from OwlBot
gcf-owl-bot[bot] Jul 14, 2021
cff328f
chore: switch to microgenerator to avoid 2.7 reappearing
tseaver Jul 14, 2021
3a66b33
chore: expand range to allow 'google-auth' 2.x versions
tseaver Jul 14, 2021
690a971
Merge branch 'master' into 210-drop-python-2.7
tseaver Jul 23, 2021
dc30a49
Merge branch 'master' into 210-drop-python-2.7
tseaver Jul 27, 2021
9c9a9a5
docs: sync newest version w/ Python 2.7 support
tseaver Jul 27, 2021
01d4c8f
chore: drop comment referring to Python 2.7 / pytypes
tseaver Aug 1, 2021
895d895
chore: remove mentions of Python 2.7 from docs
tseaver Aug 1, 2021
556ff21
🦉 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
34 changes: 4 additions & 30 deletions CONTRIBUTING.rst
@@ -1,4 +1,3 @@
.. Generated by synthtool. DO NOT EDIT!
############
Contributing
############
Expand All @@ -22,7 +21,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 @@ -77,8 +76,8 @@ We use `nox <https://nox.readthedocs.io/en/latest/>`__ to instrument our tests.

.. note::

The unit tests and system tests are described in the
``noxfile.py`` files in each directory.
The unit tests tests are described in the ``noxfile.py`` files
in each directory.

.. nox: https://pypi.org/project/nox/

Expand Down Expand Up @@ -133,29 +132,6 @@ Exceptions to PEP8:
"Function-Under-Test"), which is PEP8-incompliant, but more readable.
Some also use a local variable, ``MUT`` (short for "Module-Under-Test").

********************
Running System Tests
********************

- To run system tests, you can execute::

# Run all system tests
$ nox -s system

# Run a single system test
$ nox -s system-3.8 -- -k <name of test>


.. note::

System tests are only configured to run under Python 2.7 and 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
auth settings and change some configuration in your project to
run all the tests.

- System tests will be run against an actual project. You should use local credentials from gcloud when possible. See `Best practices for application authentication <https://cloud.google.com/docs/authentication/best-practices-applications#local_development_and_testing_with_the>`__. Some tests require a service account. For those tests see `Authenticating as a service account <https://cloud.google.com/docs/authentication/production>`__.

*************
Test Coverage
Expand Down Expand Up @@ -221,13 +197,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 +213,7 @@ Supported versions can be found in our ``noxfile.py`` `config`_.
.. _config: https://github.com/googleapis/python-api-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
15 changes: 10 additions & 5 deletions README.rst
@@ -1,7 +1,7 @@
Core Library for Google Client Libraries
========================================

|pypi| |versions|
|pypi| |versions|

This library is not meant to stand-alone. Instead it defines
common helpers used by all Google API clients. For more information, see the
Expand All @@ -16,8 +16,13 @@ common helpers used by all Google API clients. For more information, see the

Supported Python Versions
-------------------------
Python >= 3.5
Python >= 3.6

Deprecated Python Versions
--------------------------
Python == 2.7. Python 2.7 support will be removed on January 1, 2020.
tseaver marked this conversation as resolved.
Show resolved Hide resolved

Unsupported Python Versions
---------------------------

Python == 2.7, Python == 3.5.

The last version of this library compatible with Python 2.7 and 3.5 is
`google-api_core==1.31.1`.
19 changes: 0 additions & 19 deletions docs/auth.rst
Expand Up @@ -103,25 +103,6 @@ After creation, you can pass it directly to a :class:`Client <google.cloud.clien

.. _google-auth-guide: https://googleapis.dev/python/google-auth/latest/user-guide.html#service-account-private-key-files


Google App Engine Standard First Generation Environment
-------------------------------------------------------

These credentials are used only in the legacy Python 2.7
`First Generation Standard Environment`_. All other App Engine
runtimes use Compute Engine credentials.

.. _First Generation Standard Environment: https://cloud.google.com/appengine/docs/standard/runtimes

To create
:class:`credentials <google.auth.app_engine.Credentials>`
just for Google App Engine:

.. code:: python

from google.auth import app_engine
credentials = app_engine.Credentials()

Google Compute Engine Environment
---------------------------------

Expand Down
10 changes: 5 additions & 5 deletions google/api_core/bidi.py
Expand Up @@ -17,11 +17,10 @@
import collections
import datetime
import logging
import queue as queue_module
import threading
import time

from six.moves import queue

from google.api_core import exceptions

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -71,7 +70,7 @@ class _RequestQueueGenerator(object):
CPU consumed by spinning is pretty minuscule.

Args:
queue (queue.Queue): The request queue.
queue (queue_module.Queue): The request queue.
period (float): The number of seconds to wait for items from the queue
before checking if the RPC is cancelled. In practice, this
determines the maximum amount of time the request consumption
Expand Down Expand Up @@ -108,7 +107,7 @@ def __iter__(self):
while True:
try:
item = self._queue.get(timeout=self._period)
except queue.Empty:
except queue_module.Empty:
if not self._is_active():
_LOGGER.debug(
"Empty queue and inactive call, exiting request " "generator."
Expand Down Expand Up @@ -247,7 +246,7 @@ def __init__(self, start_rpc, initial_request=None, metadata=None):
self._start_rpc = start_rpc
self._initial_request = initial_request
self._rpc_metadata = metadata
self._request_queue = queue.Queue()
self._request_queue = queue_module.Queue()
self._request_generator = None
self._is_active = False
self._callbacks = []
Expand Down Expand Up @@ -645,6 +644,7 @@ def _thread_main(self, ready):
# Keeping the lock throughout avoids that.
# In the future, we could use `Condition.wait_for` if we drop
# Python 2.7.
# See: https://github.com/googleapis/python-api-core/issues/211
with self._wake:
while self._paused:
_LOGGER.debug("paused, waiting for waking.")
Expand Down
2 changes: 1 addition & 1 deletion google/api_core/client_info.py
Expand Up @@ -42,7 +42,7 @@ class ClientInfo(object):

Args:
python_version (str): The Python interpreter version, for example,
``'2.7.13'``.
``'3.9.6'``.
grpc_version (Optional[str]): The gRPC library version.
api_core_version (str): The google-api-core library version.
gapic_version (Optional[str]): The sversion of gapic-generated client
Expand Down
2 changes: 1 addition & 1 deletion google/api_core/client_options.py
Expand Up @@ -101,7 +101,7 @@ def from_dict(options):
"""Construct a client options object from a mapping object.

Args:
options (six.moves.collections_abc.Mapping): A mapping object with client options.
options (collections.abc.Mapping): A mapping object with client options.
See the docstring for ClientOptions for details on valid arguments.
"""

Expand Down
20 changes: 11 additions & 9 deletions google/api_core/datetime_helpers.py
Expand Up @@ -18,12 +18,10 @@
import datetime
import re

import pytz

from google.protobuf import timestamp_pb2


_UTC_EPOCH = datetime.datetime.utcfromtimestamp(0).replace(tzinfo=pytz.utc)
_UTC_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"
# datetime.strptime cannot handle nanosecond precision: parse w/ regex
Expand Down Expand Up @@ -83,9 +81,9 @@ def to_microseconds(value):
int: Microseconds since the unix epoch.
"""
if not value.tzinfo:
value = value.replace(tzinfo=pytz.utc)
value = value.replace(tzinfo=datetime.timezone.utc)
# Regardless of what timezone is on the value, convert it to UTC.
value = value.astimezone(pytz.utc)
value = value.astimezone(datetime.timezone.utc)
# Convert the datetime to a microsecond timestamp.
return int(calendar.timegm(value.timetuple()) * 1e6) + value.microsecond

Expand Down Expand Up @@ -156,7 +154,7 @@ def from_rfc3339(value):
nanos = int(fraction) * (10 ** scale)
micros = nanos // 1000

return bare_seconds.replace(microsecond=micros, tzinfo=pytz.utc)
return bare_seconds.replace(microsecond=micros, tzinfo=datetime.timezone.utc)


from_rfc3339_nanos = from_rfc3339 # from_rfc3339_nanos method was deprecated.
Expand Down Expand Up @@ -256,7 +254,7 @@ def from_rfc3339(cls, stamp):
bare.minute,
bare.second,
nanosecond=nanos,
tzinfo=pytz.UTC,
tzinfo=datetime.timezone.utc,
)

def timestamp_pb(self):
Expand All @@ -265,7 +263,11 @@ def timestamp_pb(self):
Returns:
(:class:`~google.protobuf.timestamp_pb2.Timestamp`): Timestamp message
"""
inst = self if self.tzinfo is not None else self.replace(tzinfo=pytz.UTC)
inst = (
self
if self.tzinfo is not None
else self.replace(tzinfo=datetime.timezone.utc)
)
delta = inst - _UTC_EPOCH
seconds = int(delta.total_seconds())
nanos = self._nanosecond or self.microsecond * 1000
Expand All @@ -292,5 +294,5 @@ def from_timestamp_pb(cls, stamp):
bare.minute,
bare.second,
nanosecond=stamp.nanos,
tzinfo=pytz.UTC,
tzinfo=datetime.timezone.utc,
)