diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml
index da616c9..9ee60f7 100644
--- a/.github/.OwlBot.lock.yaml
+++ b/.github/.OwlBot.lock.yaml
@@ -1,3 +1,3 @@
docker:
image: gcr.io/repo-automation-bots/owlbot-python:latest
- digest: sha256:c66ba3c8d7bc8566f47df841f98cd0097b28fff0b1864c86f5817f4c8c3e8600
+ digest: sha256:aea14a583128771ae8aefa364e1652f3c56070168ef31beb203534222d842b8b
diff --git a/.kokoro/docker/docs/Dockerfile b/.kokoro/docker/docs/Dockerfile
index 412b0b5..4e1b1fb 100644
--- a/.kokoro/docker/docs/Dockerfile
+++ b/.kokoro/docker/docs/Dockerfile
@@ -40,6 +40,7 @@ RUN apt-get update \
libssl-dev \
libsqlite3-dev \
portaudio19-dev \
+ python3-distutils \
redis-server \
software-properties-common \
ssh \
@@ -59,40 +60,8 @@ RUN apt-get update \
&& rm -rf /var/lib/apt/lists/* \
&& rm -f /var/cache/apt/archives/*.deb
-
-COPY fetch_gpg_keys.sh /tmp
-# Install the desired versions of Python.
-RUN set -ex \
- && export GNUPGHOME="$(mktemp -d)" \
- && echo "disable-ipv6" >> "${GNUPGHOME}/dirmngr.conf" \
- && /tmp/fetch_gpg_keys.sh \
- && for PYTHON_VERSION in 3.7.8 3.8.5; do \
- wget --no-check-certificate -O python-${PYTHON_VERSION}.tar.xz "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz" \
- && wget --no-check-certificate -O python-${PYTHON_VERSION}.tar.xz.asc "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc" \
- && gpg --batch --verify python-${PYTHON_VERSION}.tar.xz.asc python-${PYTHON_VERSION}.tar.xz \
- && rm -r python-${PYTHON_VERSION}.tar.xz.asc \
- && mkdir -p /usr/src/python-${PYTHON_VERSION} \
- && tar -xJC /usr/src/python-${PYTHON_VERSION} --strip-components=1 -f python-${PYTHON_VERSION}.tar.xz \
- && rm python-${PYTHON_VERSION}.tar.xz \
- && cd /usr/src/python-${PYTHON_VERSION} \
- && ./configure \
- --enable-shared \
- # This works only on Python 2.7 and throws a warning on every other
- # version, but seems otherwise harmless.
- --enable-unicode=ucs4 \
- --with-system-ffi \
- --without-ensurepip \
- && make -j$(nproc) \
- && make install \
- && ldconfig \
- ; done \
- && rm -rf "${GNUPGHOME}" \
- && rm -rf /usr/src/python* \
- && rm -rf ~/.cache/
-
RUN wget -O /tmp/get-pip.py 'https://bootstrap.pypa.io/get-pip.py' \
- && python3.7 /tmp/get-pip.py \
&& python3.8 /tmp/get-pip.py \
&& rm /tmp/get-pip.py
-CMD ["python3.7"]
+CMD ["python3.8"]
diff --git a/.kokoro/docker/docs/fetch_gpg_keys.sh b/.kokoro/docker/docs/fetch_gpg_keys.sh
deleted file mode 100755
index d653dd8..0000000
--- a/.kokoro/docker/docs/fetch_gpg_keys.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/bash
-# Copyright 2020 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# A script to fetch gpg keys with retry.
-# Avoid jinja parsing the file.
-#
-
-function retry {
- if [[ "${#}" -le 1 ]]; then
- echo "Usage: ${0} retry_count commands.."
- exit 1
- fi
- local retries=${1}
- local command="${@:2}"
- until [[ "${retries}" -le 0 ]]; do
- $command && return 0
- if [[ $? -ne 0 ]]; then
- echo "command failed, retrying"
- ((retries--))
- fi
- done
- return 1
-}
-
-# 3.6.9, 3.7.5 (Ned Deily)
-retry 3 gpg --keyserver ha.pool.sks-keyservers.net --recv-keys \
- 0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D
-
-# 3.8.0 (Ćukasz Langa)
-retry 3 gpg --keyserver ha.pool.sks-keyservers.net --recv-keys \
- E3FF2839C048B25C084DEBE9B26995E310250568
-
-#
diff --git a/.kokoro/samples/python3.6/periodic-head.cfg b/.kokoro/samples/python3.6/periodic-head.cfg
index f9cfcd3..5a7e3f1 100644
--- a/.kokoro/samples/python3.6/periodic-head.cfg
+++ b/.kokoro/samples/python3.6/periodic-head.cfg
@@ -7,5 +7,5 @@ env_vars: {
env_vars: {
key: "TRAMPOLINE_BUILD_FILE"
- value: "github/python-pubsub/.kokoro/test-samples-against-head.sh"
+ value: "github/python-runtimeconfig/.kokoro/test-samples-against-head.sh"
}
diff --git a/.kokoro/samples/python3.7/periodic-head.cfg b/.kokoro/samples/python3.7/periodic-head.cfg
index f9cfcd3..5a7e3f1 100644
--- a/.kokoro/samples/python3.7/periodic-head.cfg
+++ b/.kokoro/samples/python3.7/periodic-head.cfg
@@ -7,5 +7,5 @@ env_vars: {
env_vars: {
key: "TRAMPOLINE_BUILD_FILE"
- value: "github/python-pubsub/.kokoro/test-samples-against-head.sh"
+ value: "github/python-runtimeconfig/.kokoro/test-samples-against-head.sh"
}
diff --git a/.kokoro/samples/python3.8/periodic-head.cfg b/.kokoro/samples/python3.8/periodic-head.cfg
index f9cfcd3..5a7e3f1 100644
--- a/.kokoro/samples/python3.8/periodic-head.cfg
+++ b/.kokoro/samples/python3.8/periodic-head.cfg
@@ -7,5 +7,5 @@ env_vars: {
env_vars: {
key: "TRAMPOLINE_BUILD_FILE"
- value: "github/python-pubsub/.kokoro/test-samples-against-head.sh"
+ value: "github/python-runtimeconfig/.kokoro/test-samples-against-head.sh"
}
diff --git a/.kokoro/samples/python3.9/common.cfg b/.kokoro/samples/python3.9/common.cfg
new file mode 100644
index 0000000..a69be15
--- /dev/null
+++ b/.kokoro/samples/python3.9/common.cfg
@@ -0,0 +1,40 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+# Build logs will be here
+action {
+ define_artifacts {
+ regex: "**/*sponge_log.xml"
+ }
+}
+
+# Specify which tests to run
+env_vars: {
+ key: "RUN_TESTS_SESSION"
+ value: "py-3.9"
+}
+
+# Declare build specific Cloud project.
+env_vars: {
+ key: "BUILD_SPECIFIC_GCLOUD_PROJECT"
+ value: "python-docs-samples-tests-py39"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-runtimeconfig/.kokoro/test-samples.sh"
+}
+
+# Configure the docker image for kokoro-trampoline.
+env_vars: {
+ key: "TRAMPOLINE_IMAGE"
+ value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker"
+}
+
+# Download secrets for samples
+gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples"
+
+# Download trampoline resources.
+gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline"
+
+# Use the trampoline script to run in docker.
+build_file: "python-runtimeconfig/.kokoro/trampoline.sh"
\ No newline at end of file
diff --git a/.kokoro/samples/python3.9/continuous.cfg b/.kokoro/samples/python3.9/continuous.cfg
new file mode 100644
index 0000000..a1c8d97
--- /dev/null
+++ b/.kokoro/samples/python3.9/continuous.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
\ No newline at end of file
diff --git a/.kokoro/samples/python3.9/periodic-head.cfg b/.kokoro/samples/python3.9/periodic-head.cfg
new file mode 100644
index 0000000..5a7e3f1
--- /dev/null
+++ b/.kokoro/samples/python3.9/periodic-head.cfg
@@ -0,0 +1,11 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-runtimeconfig/.kokoro/test-samples-against-head.sh"
+}
diff --git a/.kokoro/samples/python3.9/periodic.cfg b/.kokoro/samples/python3.9/periodic.cfg
new file mode 100644
index 0000000..50fec96
--- /dev/null
+++ b/.kokoro/samples/python3.9/periodic.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "False"
+}
\ No newline at end of file
diff --git a/.kokoro/samples/python3.9/presubmit.cfg b/.kokoro/samples/python3.9/presubmit.cfg
new file mode 100644
index 0000000..a1c8d97
--- /dev/null
+++ b/.kokoro/samples/python3.9/presubmit.cfg
@@ -0,0 +1,6 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
\ No newline at end of file
diff --git a/.kokoro/test-samples-impl.sh b/.kokoro/test-samples-impl.sh
index cf5de74..311a8d5 100755
--- a/.kokoro/test-samples-impl.sh
+++ b/.kokoro/test-samples-impl.sh
@@ -20,9 +20,9 @@ set -eo pipefail
# Enables `**` to include files nested inside sub-folders
shopt -s globstar
-# Exit early if samples directory doesn't exist
-if [ ! -d "./samples" ]; then
- echo "No tests run. `./samples` not found"
+# Exit early if samples don't exist
+if ! find samples -name 'requirements.txt' | grep -q .; then
+ echo "No tests run. './samples/**/requirements.txt' not found"
exit 0
fi
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 4f00c7c..62eb5a7 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -16,7 +16,7 @@
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v3.4.0
+ rev: v4.0.1
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d6bcf2b..75173fa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,14 @@
[1]: https://pypi.org/project/google-cloud-runtimeconfig/#history
+### [0.32.3](https://www.github.com/googleapis/python-runtimeconfig/compare/v0.32.2...v0.32.3) (2021-07-23)
+
+
+### Bug Fixes
+
+* require python 3.6 ([#63](https://www.github.com/googleapis/python-runtimeconfig/issues/63)) ([b1780a7](https://www.github.com/googleapis/python-runtimeconfig/commit/b1780a752a4f4d7b7fa2e1050117a070d9ea0997))
+
+
### [0.32.2](https://www.github.com/googleapis/python-runtimeconfig/compare/v0.32.1...v0.32.2) (2021-05-28)
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index ed30c58..9b2b20e 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -68,15 +68,12 @@ Using ``nox``
We use `nox `__ to instrument our tests.
- To test your changes, run unit tests with ``nox``::
+ $ nox -s unit
- $ nox -s unit-2.7
- $ nox -s unit-3.8
- $ ...
+- To run a single unit test::
-- Args to pytest can be passed through the nox command separated by a `--`. For
- example, to run a single test::
+ $ nox -s unit-3.9 -- -k
- $ nox -s unit-3.8 -- -k
.. note::
@@ -143,8 +140,7 @@ Running System Tests
- To run system tests, you can execute::
# Run all system tests
- $ nox -s system-3.8
- $ nox -s system-2.7
+ $ nox -s system
# Run a single system test
$ nox -s system-3.8 -- -k
@@ -152,9 +148,8 @@ Running System Tests
.. note::
- System tests are only configured to run under Python 2.7 and
- Python 3.8. For expediency, we do not run them in older versions
- of Python 3.
+ 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
auth settings and change some configuration in your project to
@@ -182,6 +177,30 @@ Build the docs via:
$ nox -s docs
+*************************
+Samples and code snippets
+*************************
+
+Code samples and snippets live in the `samples/` catalogue. Feel free to
+provide more examples, but make sure to write tests for those examples.
+Each folder containing example code requires its own `noxfile.py` script
+which automates testing. If you decide to create a new folder, you can
+base it on the `samples/snippets` folder (providing `noxfile.py` and
+the requirements files).
+
+The tests will run against a real Google Cloud Project, so you should
+configure them just like the System Tests.
+
+- To run sample tests, you can execute::
+
+ # Run all tests in a folder
+ $ cd samples/snippets
+ $ nox -s py-3.8
+
+ # Run a single sample test
+ $ cd samples/snippets
+ $ nox -s py-3.8 -- -k
+
********************************************
Note About ``README`` as it pertains to PyPI
********************************************
@@ -218,8 +237,8 @@ Supported versions can be found in our ``noxfile.py`` `config`_.
.. _config: https://github.com/googleapis/python-runtimeconfig/blob/master/noxfile.py
-We also explicitly decided to support Python 3 beginning with version
-3.6. Reasons for this include:
+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
- Taking the lead of `prominent`_ open-source `projects`_
diff --git a/README.rst b/README.rst
index 1ddb857..5632026 100644
--- a/README.rst
+++ b/README.rst
@@ -52,12 +52,7 @@ dependencies.
Supported Python Versions
^^^^^^^^^^^^^^^^^^^^^^^^^
-Python >= 3.5
-
-Deprecated Python Versions
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-Python == 2.7. Python 2.7 support will be removed on January 1, 2020.
-
+Python >= 3.6
Mac/Linux
^^^^^^^^^
diff --git a/docs/conf.py b/docs/conf.py
index 1986e89..93a4786 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -80,9 +80,9 @@
master_doc = "index"
# General information about the project.
-project = u"google-cloud-runtimeconfig"
-copyright = u"2019, Google"
-author = u"Google APIs"
+project = "google-cloud-runtimeconfig"
+copyright = "2019, Google"
+author = "Google APIs"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -281,7 +281,7 @@
(
master_doc,
"google-cloud-runtimeconfig.tex",
- u"google-cloud-runtimeconfig Documentation",
+ "google-cloud-runtimeconfig Documentation",
author,
"manual",
)
@@ -316,7 +316,7 @@
(
master_doc,
"google-cloud-runtimeconfig",
- u"google-cloud-runtimeconfig Documentation",
+ "google-cloud-runtimeconfig Documentation",
[author],
1,
)
@@ -335,7 +335,7 @@
(
master_doc,
"google-cloud-runtimeconfig",
- u"google-cloud-runtimeconfig Documentation",
+ "google-cloud-runtimeconfig Documentation",
author,
"google-cloud-runtimeconfig",
"google-cloud-runtimeconfig Library",
diff --git a/noxfile.py b/noxfile.py
index 7fe285d..d896e7f 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -28,8 +28,8 @@
BLACK_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"]
DEFAULT_PYTHON_VERSION = "3.8"
-SYSTEM_TEST_PYTHON_VERSIONS = ["2.7", "3.8"]
-UNIT_TEST_PYTHON_VERSIONS = ["2.7", "3.6", "3.7", "3.8", "3.9"]
+SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"]
+UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"]
CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute()
@@ -84,6 +84,8 @@ def default(session):
constraints_path = str(
CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
)
+ session.install("asyncmock", "pytest-asyncio", "-c", constraints_path)
+
session.install("mock", "pytest", "pytest-cov", "-c", constraints_path)
session.install("-e", ".", "-c", constraints_path)
@@ -167,7 +169,7 @@ def cover(session):
test runs (not system test runs), and then erases coverage data.
"""
session.install("coverage", "pytest-cov")
- session.run("coverage", "report", "--show-missing", "--fail-under=97")
+ session.run("coverage", "report", "--show-missing", "--fail-under=100")
session.run("coverage", "erase")
diff --git a/owlbot.py b/owlbot.py
index 60a18bd..8983c1c 100644
--- a/owlbot.py
+++ b/owlbot.py
@@ -24,7 +24,7 @@
# ----------------------------------------------------------------------------
# Add templated files
# ----------------------------------------------------------------------------
-templated_files = common.py_library(cov_level=97)
+templated_files = common.py_library(microgenerator=True)
# this is an http library, not grpc
s.move(templated_files, excludes=["docs/multiprocessing.rst"])
diff --git a/setup.py b/setup.py
index 001e13e..5480de8 100644
--- a/setup.py
+++ b/setup.py
@@ -22,13 +22,13 @@
name = "google-cloud-runtimeconfig"
description = "Google Cloud RuntimeConfig API client library"
-version = "0.32.2"
+version = "0.32.3"
# Should be one of:
# 'Development Status :: 3 - Alpha'
# 'Development Status :: 4 - Beta'
# 'Development Status :: 5 - Production/Stable'
release_status = "Development Status :: 4 - Beta"
-dependencies = ["google-cloud-core >= 1.3.0, < 2.0dev"]
+dependencies = ["google-cloud-core >= 1.3.0, < 3.0dev"]
extras = {}
@@ -66,12 +66,11 @@
"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.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
"Operating System :: OS Independent",
"Topic :: Internet",
],
@@ -80,7 +79,7 @@
namespace_packages=namespaces,
install_requires=dependencies,
extras_require=extras,
- python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*",
+ python_requires=">=3.6",
include_package_data=True,
zip_safe=False,
)
diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py
index 858866e..a0fef69 100644
--- a/tests/unit/test_client.py
+++ b/tests/unit/test_client.py
@@ -37,11 +37,11 @@ def test_ctor_wo_client_info(self):
from google.cloud._http import ClientInfo
from google.cloud.runtimeconfig._http import Connection
- PROJECT = "PROJECT"
+ project = "PROJECT"
http = object()
creds = _make_credentials()
- client = self._make_one(project=PROJECT, credentials=creds, _http=http)
+ client = self._make_one(project=project, credentials=creds, _http=http)
self.assertIsInstance(client._connection, Connection)
self.assertIs(client._credentials, creds)
self.assertIs(client._http_internal, http)
@@ -51,13 +51,13 @@ def test_ctor_w_client_info(self):
from google.cloud._http import ClientInfo
from google.cloud.runtimeconfig._http import Connection
- PROJECT = "PROJECT"
+ project = "PROJECT"
http = object()
creds = _make_credentials()
client_info = ClientInfo()
client = self._make_one(
- project=PROJECT, credentials=creds, _http=http, client_info=client_info
+ project=project, credentials=creds, _http=http, client_info=client_info
)
self.assertIsInstance(client._connection, Connection)
self.assertIs(client._credentials, creds)
@@ -67,44 +67,65 @@ def test_ctor_w_client_info(self):
def test_ctor_w_empty_client_options(self):
from google.api_core.client_options import ClientOptions
+ project = "PROJECT"
http = object()
+ creds = _make_credentials()
client_options = ClientOptions()
- client = self._make_one(_http=http, client_options=client_options)
+ client = self._make_one(
+ project=project,
+ credentials=creds,
+ _http=http,
+ client_options=client_options,
+ )
self.assertEqual(
client._connection.API_BASE_URL, client._connection.DEFAULT_API_ENDPOINT
)
- def test_constructor_w_client_options_object(self):
+ def test_ctor_w_client_options_object(self):
from google.api_core.client_options import ClientOptions
+ project = "PROJECT"
http = object()
+ creds = _make_credentials()
client_options = ClientOptions(
api_endpoint="https://foo-runtimeconfig.googleapis.com"
)
- client = self._make_one(_http=http, client_options=client_options)
+ client = self._make_one(
+ project=project,
+ credentials=creds,
+ _http=http,
+ client_options=client_options,
+ )
self.assertEqual(
client._connection.API_BASE_URL, "https://foo-runtimeconfig.googleapis.com"
)
- def test_constructor_w_client_options_dict(self):
+ def test_ctor_w_client_options_dict(self):
+ project = "PROJECT"
http = object()
+ creds = _make_credentials()
client_options = {"api_endpoint": "https://foo-runtimeconfig.googleapis.com"}
- client = self._make_one(_http=http, client_options=client_options)
+ client = self._make_one(
+ project=project,
+ credentials=creds,
+ _http=http,
+ client_options=client_options,
+ )
self.assertEqual(
client._connection.API_BASE_URL, "https://foo-runtimeconfig.googleapis.com"
)
def test_config(self):
- PROJECT = "PROJECT"
+ project = "PROJECT"
CONFIG_NAME = "config_name"
creds = _make_credentials()
- client = self._make_one(project=PROJECT, credentials=creds)
+ client = self._make_one(project=project, credentials=creds)
new_config = client.config(CONFIG_NAME)
self.assertEqual(new_config.name, CONFIG_NAME)
self.assertIs(new_config._client, client)
- self.assertEqual(new_config.project, PROJECT)
+ self.assertEqual(new_config.project, project)
self.assertEqual(
- new_config.full_name, "projects/%s/configs/%s" % (PROJECT, CONFIG_NAME)
+ new_config.full_name, "projects/%s/configs/%s" % (project, CONFIG_NAME)
)
self.assertFalse(new_config.description)