diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 000000000..6ad83346e
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,17 @@
+# See https://pre-commit.com for more information
+# See https://pre-commit.com/hooks.html for more hooks
+repos:
+- repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v3.3.0
+ hooks:
+ - id: trailing-whitespace
+ - id: end-of-file-fixer
+ - id: check-yaml
+- repo: https://github.com/psf/black
+ rev: 19.10b0
+ hooks:
+ - id: black
+- repo: https://gitlab.com/pycqa/flake8
+ rev: 3.8.4
+ hooks:
+ - id: flake8
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index b3d1f6029..039f43681 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,44 +1,95 @@
-# Contributor Code of Conduct
+# Code of Conduct
-As contributors and maintainers of this project,
-and in the interest of fostering an open and welcoming community,
-we pledge to respect all people who contribute through reporting issues,
-posting feature requests, updating documentation,
-submitting pull requests or patches, and other activities.
+## Our Pledge
-We are committed to making participation in this project
-a harassment-free experience for everyone,
-regardless of level of experience, gender, gender identity and expression,
-sexual orientation, disability, personal appearance,
-body size, race, ethnicity, age, religion, or nationality.
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, gender identity and expression, level of
+experience, education, socio-economic status, nationality, personal appearance,
+race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
-* The use of sexualized language or imagery
-* Personal attacks
-* Trolling or insulting/derogatory comments
-* Public or private harassment
-* Publishing other's private information,
-such as physical or electronic
-addresses, without explicit permission
-* Other unethical or unprofessional conduct.
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject
-comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct.
-By adopting this Code of Conduct,
-project maintainers commit themselves to fairly and consistently
-applying these principles to every aspect of managing this project.
-Project maintainers who do not follow or enforce the Code of Conduct
-may be permanently removed from the project team.
-
-This code of conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community.
-
-Instances of abusive, harassing, or otherwise unacceptable behavior
-may be reported by opening an issue
-or contacting one or more of the project maintainers.
-
-This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0,
-available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, or to ban temporarily or permanently any
+contributor for other behaviors that they deem inappropriate, threatening,
+offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+This Code of Conduct also applies outside the project spaces when the Project
+Steward has a reasonable belief that an individual's behavior may have a
+negative impact on the project or its community.
+
+## Conflict Resolution
+
+We do not believe that all conflict is bad; healthy debate and disagreement
+often yield positive results. However, it is never okay to be disrespectful or
+to engage in behavior that violates the project’s code of conduct.
+
+If you see someone violating the code of conduct, you are encouraged to address
+the behavior directly with those involved. Many issues can be resolved quickly
+and easily, and this gives people more control over the outcome of their
+dispute. If you are unable to resolve the matter for any reason, or if the
+behavior is threatening or harassing, report it. We are dedicated to providing
+an environment where participants feel welcome and safe.
+
+
+Reports should be directed to *googleapis-stewards@google.com*, the
+Project Steward(s) for *Google Cloud Client Libraries*. It is the Project Steward’s duty to
+receive and address reported violations of the code of conduct. They will then
+work with a committee consisting of representatives from the Open Source
+Programs Office and the Google Open Source Strategy team. If for any reason you
+are uncomfortable reaching out to the Project Steward, please email
+opensource@google.com.
+
+We will investigate every complaint, but you may not receive a direct response.
+We will use our discretion in determining when and how to follow up on reported
+incidents, which may range from not taking action to permanent expulsion from
+the project and project-sponsored spaces. We will notify the accused of the
+report and provide them an opportunity to discuss it before any action is taken.
+The identity of the reporter will be omitted from the details of the report
+supplied to the accused. In potentially harmful situations, such as ongoing
+harassment or threats to anyone's safety, we may take action without notice.
+
+## Attribution
+
+This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
+available at
+https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
\ No newline at end of file
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 7eb8028d5..db4cced2a 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -80,25 +80,6 @@ We use `nox `__ to instrument our tests.
.. nox: https://pypi.org/project/nox/
-Note on Editable Installs / Develop Mode
-========================================
-
-- As mentioned previously, using ``setuptools`` in `develop mode`_
- or a ``pip`` `editable install`_ is not possible with this
- library. This is because this library uses `namespace packages`_.
- For context see `Issue #2316`_ and the relevant `PyPA issue`_.
-
- Since ``editable`` / ``develop`` mode can't be used, packages
- need to be installed directly. Hence your changes to the source
- tree don't get incorporated into the **already installed**
- package.
-
-.. _namespace packages: https://www.python.org/dev/peps/pep-0420/
-.. _Issue #2316: https://github.com/GoogleCloudPlatform/google-cloud-python/issues/2316
-.. _PyPA issue: https://github.com/pypa/packaging-problems/issues/12
-.. _develop mode: https://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode
-.. _editable install: https://pip.pypa.io/en/stable/reference/pip_install/#editable-installs
-
*****************************************
I'm getting weird errors... Can you help?
*****************************************
@@ -130,6 +111,16 @@ Coding Style
should point to the official ``googleapis`` checkout and the
the branch should be the main branch on that remote (``master``).
+- This repository contains configuration for the
+ `pre-commit `__ tool, which automates checking
+ our linters during a commit. If you have it installed on your ``$PATH``,
+ you can enable enforcing those checks via:
+
+.. code-block:: bash
+
+ $ pre-commit install
+ pre-commit installed at .git/hooks/pre-commit
+
Exceptions to PEP8:
- Many unit tests use a helper method, ``_call_fut`` ("FUT" is short for
diff --git a/docs/conf.py b/docs/conf.py
index 48cf73642..f81d29798 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -345,10 +345,11 @@
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
- "python": ("http://python.readthedocs.org/en/latest/", None),
- "google-auth": ("https://google-auth.readthedocs.io/en/stable", None),
+ "python": ("https://python.readthedocs.org/en/latest/", None),
+ "google-auth": ("https://googleapis.dev/python/google-auth/latest/", None),
"google.api_core": ("https://googleapis.dev/python/google-api-core/latest/", None,),
- "grpc": ("https://grpc.io/grpc/python/", None),
+ "grpc": ("https://grpc.github.io/grpc/python/", None),
+ "proto-plus": ("https://proto-plus-python.readthedocs.io/en/latest/", None),
}
diff --git a/google/pubsub_v1/__init__.py b/google/pubsub_v1/__init__.py
index 5e7a6cc72..7ecad97ea 100644
--- a/google/pubsub_v1/__init__.py
+++ b/google/pubsub_v1/__init__.py
@@ -90,6 +90,7 @@
"ModifyPushConfigRequest",
"PublishRequest",
"PublishResponse",
+ "PublisherClient",
"PubsubMessage",
"PullRequest",
"PullResponse",
@@ -101,11 +102,10 @@
"Snapshot",
"StreamingPullRequest",
"StreamingPullResponse",
- "SubscriberClient",
"Subscription",
"Topic",
"UpdateSnapshotRequest",
"UpdateSubscriptionRequest",
"UpdateTopicRequest",
- "PublisherClient",
+ "SubscriberClient",
)
diff --git a/noxfile.py b/noxfile.py
index 6a59685cd..913f271d5 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -28,7 +28,7 @@
DEFAULT_PYTHON_VERSION = "3.8"
SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"]
-UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8"]
+UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"]
@nox.session(python=DEFAULT_PYTHON_VERSION)
@@ -72,16 +72,17 @@ def default(session):
# Install all test dependencies, then install this package in-place.
session.install("asyncmock", "pytest-asyncio")
- session.install("mock", "pytest", "pytest-cov")
+ session.install(
+ "mock", "pytest", "pytest-cov",
+ )
session.install("-e", ".")
# Run py.test against the unit tests.
session.run(
"py.test",
"--quiet",
- "--cov=google.cloud.pubsub",
- "--cov=google.cloud",
- "--cov=tests.unit",
+ "--cov=google/cloud",
+ "--cov=tests/unit",
"--cov-append",
"--cov-config=.coveragerc",
"--cov-report=",
diff --git a/samples/snippets/noxfile.py b/samples/snippets/noxfile.py
index f3a90583a..bca0522ec 100644
--- a/samples/snippets/noxfile.py
+++ b/samples/snippets/noxfile.py
@@ -17,6 +17,7 @@
import os
from pathlib import Path
import sys
+from typing import Callable, Dict, List, Optional
import nox
@@ -37,22 +38,28 @@
TEST_CONFIG = {
# You can opt out from the test for specific Python versions.
- "ignored_versions": ["2.7"],
+ 'ignored_versions': ["2.7"],
+
+ # Old samples are opted out of enforcing Python type hints
+ # All new samples should feature them
+ 'enforce_type_hints': False,
+
# An envvar key for determining the project id to use. Change it
# to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a
# build specific Cloud project. You can also use your own string
# to use your own Cloud project.
- "gcloud_project_env": "GOOGLE_CLOUD_PROJECT",
+ 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT',
# 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT',
+
# A dictionary you want to inject into your test. Don't put any
# secrets here. These values will override predefined values.
- "envs": {},
+ 'envs': {},
}
try:
# Ensure we can import noxfile_config in the project's directory.
- sys.path.append(".")
+ sys.path.append('.')
from noxfile_config import TEST_CONFIG_OVERRIDE
except ImportError as e:
print("No user noxfile_config found: detail: {}".format(e))
@@ -62,17 +69,17 @@
TEST_CONFIG.update(TEST_CONFIG_OVERRIDE)
-def get_pytest_env_vars():
+def get_pytest_env_vars() -> Dict[str, str]:
"""Returns a dict for pytest invocation."""
ret = {}
# Override the GCLOUD_PROJECT and the alias.
- env_key = TEST_CONFIG["gcloud_project_env"]
+ env_key = TEST_CONFIG['gcloud_project_env']
# This should error out if not set.
- ret["GOOGLE_CLOUD_PROJECT"] = os.environ[env_key]
+ ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key]
# Apply user supplied envs.
- ret.update(TEST_CONFIG["envs"])
+ ret.update(TEST_CONFIG['envs'])
return ret
@@ -81,7 +88,7 @@ def get_pytest_env_vars():
ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"]
# Any default versions that should be ignored.
-IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"]
+IGNORED_VERSIONS = TEST_CONFIG['ignored_versions']
TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS])
@@ -91,7 +98,7 @@ def get_pytest_env_vars():
#
-def _determine_local_import_names(start_dir):
+def _determine_local_import_names(start_dir: str) -> List[str]:
"""Determines all import names that should be considered "local".
This is used when running the linter to insure that import order is
@@ -129,17 +136,30 @@ def _determine_local_import_names(start_dir):
@nox.session
-def lint(session):
- session.install("flake8", "flake8-import-order")
+def lint(session: nox.sessions.Session) -> None:
+ if not TEST_CONFIG['enforce_type_hints']:
+ session.install("flake8", "flake8-import-order")
+ else:
+ session.install("flake8", "flake8-import-order", "flake8-annotations")
local_names = _determine_local_import_names(".")
args = FLAKE8_COMMON_ARGS + [
"--application-import-names",
",".join(local_names),
- ".",
+ "."
]
session.run("flake8", *args)
+#
+# Black
+#
+
+
+@nox.session
+def blacken(session: nox.sessions.Session) -> None:
+ session.install("black")
+ python_files = [path for path in os.listdir(".") if path.endswith(".py")]
+ session.run("black", *python_files)
#
# Sample Tests
@@ -149,7 +169,7 @@ def lint(session):
PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"]
-def _session_tests(session, post_install=None):
+def _session_tests(session: nox.sessions.Session, post_install: Callable = None) -> None:
"""Runs py.test for a particular project."""
if os.path.exists("requirements.txt"):
session.install("-r", "requirements.txt")
@@ -175,14 +195,14 @@ def _session_tests(session, post_install=None):
@nox.session(python=ALL_VERSIONS)
-def py(session):
+def py(session: nox.sessions.Session) -> None:
"""Runs py.test for a sample using the specified version of Python."""
if session.python in TESTED_VERSIONS:
_session_tests(session)
else:
- session.skip(
- "SKIPPED: {} tests are disabled for this sample.".format(session.python)
- )
+ session.skip("SKIPPED: {} tests are disabled for this sample.".format(
+ session.python
+ ))
#
@@ -190,7 +210,7 @@ def py(session):
#
-def _get_repo_root():
+def _get_repo_root() -> Optional[str]:
""" Returns the root folder of the project. """
# Get root of this repository. Assume we don't have directories nested deeper than 10 items.
p = Path(os.getcwd())
@@ -213,7 +233,7 @@ def _get_repo_root():
@nox.session
@nox.parametrize("path", GENERATED_READMES)
-def readmegen(session, path):
+def readmegen(session: nox.sessions.Session, path: str) -> None:
"""(Re-)generates the readme for a sample."""
session.install("jinja2", "pyyaml")
dir_ = os.path.dirname(path)
diff --git a/scripts/fixup_pubsub_v1_keywords.py b/scripts/fixup_pubsub_v1_keywords.py
index 1c9ec6f8c..c00db1ebc 100644
--- a/scripts/fixup_pubsub_v1_keywords.py
+++ b/scripts/fixup_pubsub_v1_keywords.py
@@ -1,3 +1,4 @@
+#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 Google LLC
@@ -20,11 +21,12 @@
import libcst as cst
import pathlib
import sys
-from typing import Any, Callable, Dict, List, Sequence, Tuple
+from typing import (Any, Callable, Dict, List, Sequence, Tuple)
def partition(
- predicate: Callable[[Any], bool], iterator: Sequence[Any]
+ predicate: Callable[[Any], bool],
+ iterator: Sequence[Any]
) -> Tuple[List[Any], List[Any]]:
"""A stable, out-of-place partition."""
results = ([], [])
@@ -37,127 +39,39 @@ def partition(
class pubsubCallTransformer(cst.CSTTransformer):
- CTRL_PARAMS: Tuple[str] = ("retry", "timeout", "metadata")
+ CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata')
METHOD_TO_PARAMS: Dict[str, Tuple[str]] = {
- "acknowledge": (
- "subscription",
- "ack_ids",
- ),
- "create_snapshot": (
- "name",
- "subscription",
- "labels",
- ),
- "create_subscription": (
- "name",
- "topic",
- "push_config",
- "ack_deadline_seconds",
- "retain_acked_messages",
- "message_retention_duration",
- "labels",
- "enable_message_ordering",
- "expiration_policy",
- "filter",
- "dead_letter_policy",
- "retry_policy",
- "detached",
- ),
- "create_topic": (
- "name",
- "labels",
- "message_storage_policy",
- "kms_key_name",
- ),
- "delete_snapshot": ("snapshot",),
- "delete_subscription": ("subscription",),
- "delete_topic": ("topic",),
- "detach_subscription": ("subscription",),
- "get_snapshot": ("snapshot",),
- "get_subscription": ("subscription",),
- "get_topic": ("topic",),
- "list_snapshots": (
- "project",
- "page_size",
- "page_token",
- ),
- "list_subscriptions": (
- "project",
- "page_size",
- "page_token",
- ),
- "list_topics": (
- "project",
- "page_size",
- "page_token",
- ),
- "list_topic_snapshots": (
- "topic",
- "page_size",
- "page_token",
- ),
- "list_topic_subscriptions": (
- "topic",
- "page_size",
- "page_token",
- ),
- "modify_ack_deadline": (
- "subscription",
- "ack_ids",
- "ack_deadline_seconds",
- ),
- "modify_push_config": (
- "subscription",
- "push_config",
- ),
- "pull": (
- "subscription",
- "max_messages",
- "return_immediately",
- ),
- "seek": (
- "subscription",
- "time",
- "snapshot",
- ),
- "streaming_pull": (
- "subscription",
- "stream_ack_deadline_seconds",
- "ack_ids",
- "modify_deadline_seconds",
- "modify_deadline_ack_ids",
- "client_id",
- "max_outstanding_messages",
- "max_outstanding_bytes",
- ),
- "update_snapshot": (
- "snapshot",
- "update_mask",
- ),
- "update_subscription": (
- "subscription",
- "update_mask",
- ),
- "update_topic": (
- "topic",
- "update_mask",
- ),
- "get_iam_policy": (
- "resource",
- "options",
- ),
- "set_iam_policy": (
- "resource",
- "policy",
- ),
- "test_iam_permissions": (
- "resource",
- "permissions",
- ),
- }
+ 'acknowledge': ('subscription', 'ack_ids', ),
+ 'create_snapshot': ('name', 'subscription', 'labels', ),
+ 'create_subscription': ('name', 'topic', 'push_config', 'ack_deadline_seconds', 'retain_acked_messages', 'message_retention_duration', 'labels', 'enable_message_ordering', 'expiration_policy', 'filter', 'dead_letter_policy', 'retry_policy', 'detached', ),
+ 'create_topic': ('name', 'labels', 'message_storage_policy', 'kms_key_name', ),
+ 'delete_snapshot': ('snapshot', ),
+ 'delete_subscription': ('subscription', ),
+ 'delete_topic': ('topic', ),
+ 'detach_subscription': ('subscription', ),
+ 'get_snapshot': ('snapshot', ),
+ 'get_subscription': ('subscription', ),
+ 'get_topic': ('topic', ),
+ 'list_snapshots': ('project', 'page_size', 'page_token', ),
+ 'list_subscriptions': ('project', 'page_size', 'page_token', ),
+ 'list_topics': ('project', 'page_size', 'page_token', ),
+ 'list_topic_snapshots': ('topic', 'page_size', 'page_token', ),
+ 'list_topic_subscriptions': ('topic', 'page_size', 'page_token', ),
+ 'modify_ack_deadline': ('subscription', 'ack_ids', 'ack_deadline_seconds', ),
+ 'modify_push_config': ('subscription', 'push_config', ),
+ 'publish': ('topic', 'messages', ),
+ 'pull': ('subscription', 'max_messages', 'return_immediately', ),
+ 'seek': ('subscription', 'time', 'snapshot', ),
+ 'streaming_pull': ('subscription', 'stream_ack_deadline_seconds', 'ack_ids', 'modify_deadline_seconds', 'modify_deadline_ack_ids', 'client_id', 'max_outstanding_messages', 'max_outstanding_bytes', ),
+ 'update_snapshot': ('snapshot', 'update_mask', ),
+ 'update_subscription': ('subscription', 'update_mask', ),
+ 'update_topic': ('topic', 'update_mask', ),
+
+ 'get_iam_policy': ('resource', 'options', ),
+ 'set_iam_policy': ('resource', 'policy', ),
+ 'test_iam_permissions': ('resource', 'permissions', ),
- def __init__(self, use_keywords=False):
- self._use_keywords = use_keywords
+ }
def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode:
try:
@@ -175,80 +89,35 @@ def leave_Call(self, original: cst.Call, updated: cst.Call) -> cst.CSTNode:
return updated
kwargs, ctrl_kwargs = partition(
- lambda a: not a.keyword.value in self.CTRL_PARAMS, kwargs
+ lambda a: not a.keyword.value in self.CTRL_PARAMS,
+ kwargs
)
- args, ctrl_args = args[: len(kword_params)], args[len(kword_params) :]
- ctrl_kwargs.extend(
- cst.Arg(
- value=a.value,
- keyword=cst.Name(value=ctrl),
- equal=cst.AssignEqual(
- whitespace_before=cst.SimpleWhitespace(""),
- whitespace_after=cst.SimpleWhitespace(""),
- ),
- )
- for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS)
- )
+ args, ctrl_args = args[:len(kword_params)], args[len(kword_params):]
+ ctrl_kwargs.extend(cst.Arg(value=a.value, keyword=cst.Name(value=ctrl))
+ for a, ctrl in zip(ctrl_args, self.CTRL_PARAMS))
- if self._use_keywords:
- new_kwargs = [
- cst.Arg(
- value=arg.value,
- keyword=cst.Name(value=name),
- equal=cst.AssignEqual(
- whitespace_before=cst.SimpleWhitespace(""),
- whitespace_after=cst.SimpleWhitespace(""),
- ),
+ request_arg = cst.Arg(
+ value=cst.Dict([
+ cst.DictElement(
+ cst.SimpleString("'{}'".format(name)),
+ cst.Element(value=arg.value)
)
- for name, arg in zip(kword_params, args + kwargs)
- ]
- new_kwargs.extend(
- [
- cst.Arg(
- value=arg.value,
- keyword=cst.Name(value=arg.keyword.value),
- equal=cst.AssignEqual(
- whitespace_before=cst.SimpleWhitespace(""),
- whitespace_after=cst.SimpleWhitespace(""),
- ),
- )
- for arg in ctrl_kwargs
- ]
- )
- return updated.with_changes(args=new_kwargs)
- else:
- request_arg = cst.Arg(
- value=cst.Dict(
- [
- cst.DictElement(
- cst.SimpleString('"{}"'.format(name)),
- cst.Element(value=arg.value),
- )
- for name, arg in zip(kword_params, args + kwargs)
- ]
- + [
- cst.DictElement(
- cst.SimpleString('"{}"'.format(arg.keyword.value)),
- cst.Element(value=arg.value),
- )
- for arg in ctrl_kwargs
- ]
- ),
- keyword=cst.Name("request"),
- equal=cst.AssignEqual(
- whitespace_before=cst.SimpleWhitespace(""),
- whitespace_after=cst.SimpleWhitespace(""),
- ),
- )
+ # Note: the args + kwargs looks silly, but keep in mind that
+ # the control parameters had to be stripped out, and that
+ # those could have been passed positionally or by keyword.
+ for name, arg in zip(kword_params, args + kwargs)]),
+ keyword=cst.Name("request")
+ )
- return updated.with_changes(args=[request_arg])
+ return updated.with_changes(
+ args=[request_arg] + ctrl_kwargs
+ )
def fix_files(
in_dir: pathlib.Path,
out_dir: pathlib.Path,
- use_keywords: bool = False,
*,
transformer=pubsubCallTransformer(),
):
@@ -261,12 +130,11 @@ def fix_files(
pyfile_gen = (
pathlib.Path(os.path.join(root, f))
for root, _, files in os.walk(in_dir)
- for f in files
- if os.path.splitext(f)[1] == ".py"
+ for f in files if os.path.splitext(f)[1] == ".py"
)
for fpath in pyfile_gen:
- with open(fpath, "r") as f:
+ with open(fpath, 'r') as f:
src = f.read()
# Parse the code and insert method call fixes.
@@ -278,11 +146,11 @@ def fix_files(
updated_path.parent.mkdir(parents=True, exist_ok=True)
# Generate the updated source file at the corresponding path.
- with open(updated_path, "w") as f:
+ with open(updated_path, 'w') as f:
f.write(updated.code)
-if __name__ == "__main__":
+if __name__ == '__main__':
parser = argparse.ArgumentParser(
description="""Fix up source that uses the pubsub client library.
@@ -297,34 +165,24 @@ def fix_files(
These all constitute false negatives. The tool will also detect false
positives when an API method shares a name with another method.
-"""
- )
+""")
parser.add_argument(
- "-d",
- "--input-directory",
+ '-d',
+ '--input-directory',
required=True,
- dest="input_dir",
- help="the input directory to walk for python files to fix up",
+ dest='input_dir',
+ help='the input directory to walk for python files to fix up',
)
parser.add_argument(
- "-o",
- "--output-directory",
+ '-o',
+ '--output-directory',
required=True,
- dest="output_dir",
- help="the directory to output files fixed via un-flattening",
- )
- parser.add_argument(
- "-k",
- "--use-keywords",
- required=False,
- action="store_true",
- dest="use_keywords",
- help="Use keyword arguments instead of constructing a request",
+ dest='output_dir',
+ help='the directory to output files fixed via un-flattening',
)
args = parser.parse_args()
input_dir = pathlib.Path(args.input_dir)
output_dir = pathlib.Path(args.output_dir)
- use_keywords = args.use_keywords
if not input_dir.is_dir():
print(
f"input directory '{input_dir}' does not exist or is not a directory",
@@ -346,5 +204,4 @@ def fix_files(
)
sys.exit(-1)
- transformer = pubsubCallTransformer(use_keywords=use_keywords)
- fix_files(input_dir, output_dir, use_keywords, transformer=transformer)
+ fix_files(input_dir, output_dir)
diff --git a/scripts/readme-gen/templates/README.tmpl.rst b/scripts/readme-gen/templates/README.tmpl.rst
index df252dd6e..4fd239765 100644
--- a/scripts/readme-gen/templates/README.tmpl.rst
+++ b/scripts/readme-gen/templates/README.tmpl.rst
@@ -6,7 +6,7 @@
===============================================================================
.. image:: https://gstatic.com/cloudssh/images/open-btn.png
- :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/python-pubsub&page=editor&open_in_editor={{folder}}/README.rst
+ :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor={{folder}}/README.rst
This directory contains samples for {{product.name}}. {{product.description}}
@@ -46,7 +46,7 @@ Samples
{% if not sample.hide_cloudshell_button %}
.. image:: https://gstatic.com/cloudssh/images/open-btn.png
- :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com//googleapis/python-pubsub&page=editor&open_in_editor={{folder}}/{{sample.file}},{{folder}}/README.rst
+ :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor={{folder}}/{{sample.file}},{{folder}}/README.rst
{% endif %}
diff --git a/scripts/readme-gen/templates/install_deps.tmpl.rst b/scripts/readme-gen/templates/install_deps.tmpl.rst
index 7a47efe21..a0406dba8 100644
--- a/scripts/readme-gen/templates/install_deps.tmpl.rst
+++ b/scripts/readme-gen/templates/install_deps.tmpl.rst
@@ -5,14 +5,14 @@ Install Dependencies
.. code-block:: bash
- $ git clone https://github.com/googleapis/python-pubsub.git
+ $ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
#. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions.
.. _Python Development Environment Setup Guide:
https://cloud.google.com/python/setup
-#. Create a virtualenv. Samples are compatible with Python 3.6+.
+#. Create a virtualenv. Samples are compatible with Python 2.7 and 3.4+.
.. code-block:: bash
diff --git a/synth.metadata b/synth.metadata
index 347608c98..88336808d 100644
--- a/synth.metadata
+++ b/synth.metadata
@@ -4,28 +4,36 @@
"git": {
"name": ".",
"remote": "https://github.com/googleapis/python-pubsub.git",
- "sha": "0bf5d593573afea43bba7de90d2bb40ee0fc101e"
+ "sha": "f3f4e5add32128bf238b2fbab3bcf0f5b23269d3"
+ }
+ },
+ {
+ "git": {
+ "name": "googleapis",
+ "remote": "https://github.com/googleapis/googleapis.git",
+ "sha": "53eb2512a55caabcbad1898225080a2a3dfcb6aa",
+ "internalRef": "346818879"
}
},
{
"git": {
"name": "synthtool",
"remote": "https://github.com/googleapis/synthtool.git",
- "sha": "901ddd44e9ef7887ee681b9183bbdea99437fdcc"
+ "sha": "18c5dbdb4ac8cf75d4d8174e7b4558f48e76f8a1"
}
},
{
"git": {
"name": "synthtool",
"remote": "https://github.com/googleapis/synthtool.git",
- "sha": "901ddd44e9ef7887ee681b9183bbdea99437fdcc"
+ "sha": "18c5dbdb4ac8cf75d4d8174e7b4558f48e76f8a1"
}
},
{
"git": {
"name": "synthtool",
"remote": "https://github.com/googleapis/synthtool.git",
- "sha": "901ddd44e9ef7887ee681b9183bbdea99437fdcc"
+ "sha": "18c5dbdb4ac8cf75d4d8174e7b4558f48e76f8a1"
}
}
],
@@ -39,5 +47,103 @@
"generator": "bazel"
}
}
+ ],
+ "generatedFiles": [
+ ".flake8",
+ ".github/CONTRIBUTING.md",
+ ".github/ISSUE_TEMPLATE/bug_report.md",
+ ".github/ISSUE_TEMPLATE/feature_request.md",
+ ".github/ISSUE_TEMPLATE/support_request.md",
+ ".github/PULL_REQUEST_TEMPLATE.md",
+ ".github/release-please.yml",
+ ".github/snippet-bot.yml",
+ ".gitignore",
+ ".kokoro/build.sh",
+ ".kokoro/continuous/common.cfg",
+ ".kokoro/continuous/continuous.cfg",
+ ".kokoro/docker/docs/Dockerfile",
+ ".kokoro/docker/docs/fetch_gpg_keys.sh",
+ ".kokoro/docs/common.cfg",
+ ".kokoro/docs/docs-presubmit.cfg",
+ ".kokoro/docs/docs.cfg",
+ ".kokoro/populate-secrets.sh",
+ ".kokoro/presubmit/common.cfg",
+ ".kokoro/presubmit/presubmit.cfg",
+ ".kokoro/publish-docs.sh",
+ ".kokoro/release.sh",
+ ".kokoro/release/common.cfg",
+ ".kokoro/release/release.cfg",
+ ".kokoro/samples/lint/common.cfg",
+ ".kokoro/samples/lint/continuous.cfg",
+ ".kokoro/samples/lint/periodic.cfg",
+ ".kokoro/samples/lint/presubmit.cfg",
+ ".kokoro/samples/python3.6/common.cfg",
+ ".kokoro/samples/python3.6/continuous.cfg",
+ ".kokoro/samples/python3.6/periodic.cfg",
+ ".kokoro/samples/python3.6/presubmit.cfg",
+ ".kokoro/samples/python3.7/common.cfg",
+ ".kokoro/samples/python3.7/continuous.cfg",
+ ".kokoro/samples/python3.7/periodic.cfg",
+ ".kokoro/samples/python3.7/presubmit.cfg",
+ ".kokoro/samples/python3.8/common.cfg",
+ ".kokoro/samples/python3.8/continuous.cfg",
+ ".kokoro/samples/python3.8/periodic.cfg",
+ ".kokoro/samples/python3.8/presubmit.cfg",
+ ".kokoro/test-samples.sh",
+ ".kokoro/trampoline.sh",
+ ".kokoro/trampoline_v2.sh",
+ ".pre-commit-config.yaml",
+ ".trampolinerc",
+ "CODE_OF_CONDUCT.md",
+ "CONTRIBUTING.rst",
+ "LICENSE",
+ "MANIFEST.in",
+ "docs/_static/custom.css",
+ "docs/_templates/layout.html",
+ "docs/conf.py",
+ "docs/multiprocessing.rst",
+ "google/cloud/pubsub_v1/proto/pubsub.proto",
+ "google/pubsub/__init__.py",
+ "google/pubsub/py.typed",
+ "google/pubsub_v1/__init__.py",
+ "google/pubsub_v1/py.typed",
+ "google/pubsub_v1/services/__init__.py",
+ "google/pubsub_v1/services/publisher/__init__.py",
+ "google/pubsub_v1/services/publisher/async_client.py",
+ "google/pubsub_v1/services/publisher/client.py",
+ "google/pubsub_v1/services/publisher/pagers.py",
+ "google/pubsub_v1/services/publisher/transports/__init__.py",
+ "google/pubsub_v1/services/publisher/transports/base.py",
+ "google/pubsub_v1/services/publisher/transports/grpc.py",
+ "google/pubsub_v1/services/publisher/transports/grpc_asyncio.py",
+ "google/pubsub_v1/services/subscriber/__init__.py",
+ "google/pubsub_v1/services/subscriber/async_client.py",
+ "google/pubsub_v1/services/subscriber/client.py",
+ "google/pubsub_v1/services/subscriber/pagers.py",
+ "google/pubsub_v1/services/subscriber/transports/__init__.py",
+ "google/pubsub_v1/services/subscriber/transports/base.py",
+ "google/pubsub_v1/services/subscriber/transports/grpc.py",
+ "google/pubsub_v1/services/subscriber/transports/grpc_asyncio.py",
+ "google/pubsub_v1/types/__init__.py",
+ "google/pubsub_v1/types/pubsub.py",
+ "mypy.ini",
+ "noxfile.py",
+ "renovate.json",
+ "samples/AUTHORING_GUIDE.md",
+ "samples/CONTRIBUTING.md",
+ "samples/snippets/noxfile.py",
+ "scripts/decrypt-secrets.sh",
+ "scripts/fixup_pubsub_v1_keywords.py",
+ "scripts/readme-gen/readme_gen.py",
+ "scripts/readme-gen/templates/README.tmpl.rst",
+ "scripts/readme-gen/templates/auth.tmpl.rst",
+ "scripts/readme-gen/templates/auth_api_key.tmpl.rst",
+ "scripts/readme-gen/templates/install_deps.tmpl.rst",
+ "scripts/readme-gen/templates/install_portaudio.tmpl.rst",
+ "setup.cfg",
+ "testing/.gitignore",
+ "tests/unit/gapic/pubsub_v1/__init__.py",
+ "tests/unit/gapic/pubsub_v1/test_publisher.py",
+ "tests/unit/gapic/pubsub_v1/test_subscriber.py"
]
}
\ No newline at end of file