google-api-core 2.34.0__tar.gz → 2.35.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {google_api_core-2.34.0/google_api_core.egg-info → google_api_core-2.35.0}/PKG-INFO +1 -1
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/_python_package_support.py +27 -3
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/path_template.py +45 -2
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/version.py +1 -1
- {google_api_core-2.34.0 → google_api_core-2.35.0/google_api_core.egg-info}/PKG-INFO +1 -1
- {google_api_core-2.34.0 → google_api_core-2.35.0}/pyproject.toml +2 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/test_grpc_helpers_async.py +9 -3
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_grpc_helpers.py +8 -2
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_path_template.py +294 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_python_package_support.py +51 -3
- {google_api_core-2.34.0 → google_api_core-2.35.0}/LICENSE +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/MANIFEST.in +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/README.rst +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/_feature_gating_helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/_python_version_support.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/_rest_streaming_base.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/bidi.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/bidi_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/bidi_base.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/client_info.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/client_logging.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/client_options.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/datetime_helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/exceptions.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/extended_operation.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/future/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/future/_helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/future/async_future.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/future/base.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/future/polling.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/gapic_v1/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/gapic_v1/client_info.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/gapic_v1/config.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/gapic_v1/config_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/gapic_v1/method.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/gapic_v1/method_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/gapic_v1/requests.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/gapic_v1/routing_header.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/general_helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/grpc_helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/grpc_helpers_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/iam.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operation.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operation_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/abstract_operations_base_client.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/abstract_operations_client.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/operations_async_client.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/operations_client.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/operations_client_config.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/operations_rest_client_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/pagers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/pagers_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/pagers_base.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/transports/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/transports/base.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/transports/rest.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/transports/rest_asyncio.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/page_iterator.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/page_iterator_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/protobuf_helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/py.typed +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/rest_helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/rest_streaming.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/rest_streaming_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/retry/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/retry/retry_base.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/retry/retry_streaming.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/retry/retry_streaming_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/retry/retry_unary.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/retry/retry_unary_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/retry_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/timeout.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/universe.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/version_header.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google_api_core.egg-info/SOURCES.txt +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google_api_core.egg-info/dependency_links.txt +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google_api_core.egg-info/requires.txt +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/google_api_core.egg-info/top_level.txt +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/setup.cfg +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/setup.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/future/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/future/test_async_future.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/gapic/test_config_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/gapic/test_method_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/operations_v1/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/operations_v1/test_operations_async_client.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/retry/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/retry/test_retry_streaming_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/retry/test_retry_unary_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/test_bidi_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/test_operation_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/test_page_iterator_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/test_rest_streaming_async.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/conftest.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/future/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/future/test__helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/future/test_polling.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/gapic/test_client_info.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/gapic/test_config.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/gapic/test_method.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/gapic/test_requests.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/gapic/test_routing_header.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/operations_v1/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/operations_v1/test_operations_client.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/operations_v1/test_operations_rest_client.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/retry/__init__.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/retry/test_retry_base.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/retry/test_retry_imports.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/retry/test_retry_streaming.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/retry/test_retry_unary.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_bidi.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_client_info.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_client_logging.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_client_options.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_datetime_helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_exceptions.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_extended_operation.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_feature_gating_helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_iam.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_operation.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_packaging.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_page_iterator.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_protobuf_helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_python_version_support.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_rest_helpers.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_rest_streaming.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_timeout.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_universe.py +0 -0
- {google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/test_version_header.py +0 -0
{google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/_python_package_support.py
RENAMED
|
@@ -30,14 +30,37 @@ ParsedVersion = Tuple[int, ...]
|
|
|
30
30
|
# about deprecated and unsupported versions.
|
|
31
31
|
DependencyConstraint = namedtuple(
|
|
32
32
|
"DependencyConstraint",
|
|
33
|
-
[
|
|
33
|
+
[
|
|
34
|
+
"package_name",
|
|
35
|
+
"minimum_fully_supported_version",
|
|
36
|
+
"recommended_version",
|
|
37
|
+
"message_template",
|
|
38
|
+
],
|
|
39
|
+
defaults=(None, None),
|
|
34
40
|
)
|
|
41
|
+
|
|
42
|
+
PQC_GRPC_WARNING_TEMPLATE = (
|
|
43
|
+
"Package {consumer_package} depends on {dependency_package}, currently installed at version {version_used_string}. "
|
|
44
|
+
"grpcio < 1.83.0 does not support Post-Quantum Cryptography (PQC). "
|
|
45
|
+
"Support for non-PQC environments is deprecated. In October 2026, "
|
|
46
|
+
"Google Cloud Python packages will raise their minimum requirements "
|
|
47
|
+
"(including google-api-core, grpcio, and grpcio-status) to enforce grpcio >= 1.83.0. "
|
|
48
|
+
"For more details on Google Cloud's post-quantum security migration, visit: "
|
|
49
|
+
"https://cloud.google.com/security/resources/post-quantum-cryptography"
|
|
50
|
+
)
|
|
51
|
+
|
|
35
52
|
_PACKAGE_DEPENDENCY_WARNINGS = [
|
|
36
53
|
DependencyConstraint(
|
|
37
54
|
"google.protobuf",
|
|
38
55
|
minimum_fully_supported_version="6.33.5",
|
|
39
56
|
recommended_version="6.x",
|
|
40
|
-
)
|
|
57
|
+
),
|
|
58
|
+
DependencyConstraint(
|
|
59
|
+
"grpcio",
|
|
60
|
+
minimum_fully_supported_version="1.83.0",
|
|
61
|
+
recommended_version="1.83.x",
|
|
62
|
+
message_template=PQC_GRPC_WARNING_TEMPLATE,
|
|
63
|
+
),
|
|
41
64
|
]
|
|
42
65
|
|
|
43
66
|
|
|
@@ -162,7 +185,7 @@ def warn_deprecation_for_versions_less_than(
|
|
|
162
185
|
) = _get_distribution_and_import_packages(consumer_import_package)
|
|
163
186
|
|
|
164
187
|
recommendation = (
|
|
165
|
-
" (we recommend {recommended_version})" if recommended_version else ""
|
|
188
|
+
f" (we recommend {recommended_version})" if recommended_version else ""
|
|
166
189
|
)
|
|
167
190
|
message_template = message_template or _flatten_message(
|
|
168
191
|
"""
|
|
@@ -222,4 +245,5 @@ def check_dependency_versions(
|
|
|
222
245
|
package_info.package_name,
|
|
223
246
|
package_info.minimum_fully_supported_version,
|
|
224
247
|
recommended_version=package_info.recommended_version,
|
|
248
|
+
message_template=package_info.message_template,
|
|
225
249
|
)
|
|
@@ -28,6 +28,7 @@ from __future__ import unicode_literals
|
|
|
28
28
|
import copy
|
|
29
29
|
import functools
|
|
30
30
|
import re
|
|
31
|
+
import urllib.parse
|
|
31
32
|
from collections import deque
|
|
32
33
|
|
|
33
34
|
# Regular expression for extracting variable parts from a path template.
|
|
@@ -62,6 +63,41 @@ _SINGLE_SEGMENT_PATTERN = r"([^/]+)"
|
|
|
62
63
|
_MULTI_SEGMENT_PATTERN = r"(.+)"
|
|
63
64
|
|
|
64
65
|
|
|
66
|
+
def _extract_and_validate_wildcards(
|
|
67
|
+
val: str, template_str: str | None, property_name: str = "property"
|
|
68
|
+
) -> None:
|
|
69
|
+
"""Extract and validate wildcard variables against path traversal.
|
|
70
|
+
|
|
71
|
+
Ensures that values matched against single-segment wildcards ('*') are
|
|
72
|
+
not '.' or '..', and values matched against multi-segment wildcards ('**')
|
|
73
|
+
do not contain '.' or '..' segments.
|
|
74
|
+
|
|
75
|
+
If the value does not match the sub-template structure, validation is
|
|
76
|
+
deferred to allow subsequent bindings to be evaluated.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
val (str): The raw string value to validate.
|
|
80
|
+
template_str (str | None): The template string of the variable (e.g.
|
|
81
|
+
'projects/*/locations/*').
|
|
82
|
+
property_name (str): The name of the property being validated, for use
|
|
83
|
+
in error messages.
|
|
84
|
+
|
|
85
|
+
Raises:
|
|
86
|
+
ValueError: If a wildcard value contains invalid dot segments.
|
|
87
|
+
"""
|
|
88
|
+
tmpl = template_str or "*"
|
|
89
|
+
m = re.fullmatch(_generate_pattern_for_template(tmpl), val)
|
|
90
|
+
if m is not None:
|
|
91
|
+
groups = m.groups()
|
|
92
|
+
for g in groups:
|
|
93
|
+
if "." in g and any(seg in (".", "..") for seg in g.split("/")):
|
|
94
|
+
if "**" in tmpl or "/" in tmpl:
|
|
95
|
+
raise ValueError(
|
|
96
|
+
f"Value for {property_name} must not contain segments that are exactly . or .. ."
|
|
97
|
+
)
|
|
98
|
+
raise ValueError(f"Invalid value {g} for {property_name}.")
|
|
99
|
+
|
|
100
|
+
|
|
65
101
|
def _expand_variable_match(positional_vars, named_vars, match):
|
|
66
102
|
"""Expand a matched variable with its value.
|
|
67
103
|
|
|
@@ -81,9 +117,13 @@ def _expand_variable_match(positional_vars, named_vars, match):
|
|
|
81
117
|
"""
|
|
82
118
|
positional = match.group("positional")
|
|
83
119
|
name = match.group("name")
|
|
120
|
+
template = match.group("template")
|
|
121
|
+
|
|
84
122
|
if name is not None:
|
|
85
123
|
try:
|
|
86
|
-
|
|
124
|
+
val = str(named_vars[name])
|
|
125
|
+
_extract_and_validate_wildcards(val, template, name)
|
|
126
|
+
return urllib.parse.quote(val, safe="/")
|
|
87
127
|
except KeyError:
|
|
88
128
|
raise ValueError(
|
|
89
129
|
"Named variable '{}' not specified and needed by template "
|
|
@@ -91,7 +131,9 @@ def _expand_variable_match(positional_vars, named_vars, match):
|
|
|
91
131
|
)
|
|
92
132
|
elif positional is not None:
|
|
93
133
|
try:
|
|
94
|
-
|
|
134
|
+
val = str(positional_vars.pop(0))
|
|
135
|
+
_extract_and_validate_wildcards(val, positional, "positional variable")
|
|
136
|
+
return urllib.parse.quote(val, safe="/")
|
|
95
137
|
except IndexError:
|
|
96
138
|
raise ValueError(
|
|
97
139
|
"Positional variable not specified and needed by template "
|
|
@@ -159,6 +201,7 @@ def _replace_variable_with_pattern(match):
|
|
|
159
201
|
raise ValueError("Unknown template expression {}".format(match.group(0)))
|
|
160
202
|
|
|
161
203
|
|
|
204
|
+
@functools.lru_cache(maxsize=256)
|
|
162
205
|
def _generate_pattern_for_template(tmpl):
|
|
163
206
|
"""Generate a pattern that can validate a path template.
|
|
164
207
|
|
|
@@ -85,6 +85,8 @@ filterwarnings = [
|
|
|
85
85
|
"error",
|
|
86
86
|
# Prevent Python version warnings from interfering with tests
|
|
87
87
|
"ignore:.* Python version .*:FutureWarning",
|
|
88
|
+
# TODO: Remove once b/544782314 is resolved (when grpcio >= 1.83.0 is enforced)
|
|
89
|
+
"ignore:.*does not support Post-Quantum Cryptography.*:FutureWarning",
|
|
88
90
|
# Remove once https://github.com/pytest-dev/pytest-cov/issues/621 is fixed
|
|
89
91
|
"ignore:.*The --rsyncdir command line argument and rsyncdirs config variable are deprecated:DeprecationWarning",
|
|
90
92
|
# Remove once https://github.com/protocolbuffers/protobuf/issues/12186 is fixed
|
|
@@ -421,9 +421,15 @@ def test_create_channel_implicit_with_default_host(
|
|
|
421
421
|
assert channel is grpc_secure_channel.return_value
|
|
422
422
|
|
|
423
423
|
google_auth_default.assert_called_once_with(scopes=None, default_scopes=None)
|
|
424
|
-
auth_metadata_plugin.
|
|
425
|
-
|
|
426
|
-
|
|
424
|
+
assert auth_metadata_plugin.call_count == 1
|
|
425
|
+
assert auth_metadata_plugin.call_args.args == (
|
|
426
|
+
mock.sentinel.credentials,
|
|
427
|
+
mock.sentinel.Request,
|
|
428
|
+
)
|
|
429
|
+
assert auth_metadata_plugin.call_args.kwargs["default_host"] == default_host
|
|
430
|
+
# google-auth >= 2.56.3 supports suppress_metrics_header; older versions omit it during fallback
|
|
431
|
+
if "suppress_metrics_header" in auth_metadata_plugin.call_args.kwargs:
|
|
432
|
+
assert auth_metadata_plugin.call_args.kwargs["suppress_metrics_header"] is True
|
|
427
433
|
grpc_secure_channel.assert_called_once_with(
|
|
428
434
|
expected_target, composite_creds, compression=None
|
|
429
435
|
)
|
|
@@ -453,9 +453,15 @@ def test_create_channel_implicit_with_default_host(
|
|
|
453
453
|
assert channel is grpc_secure_channel.return_value
|
|
454
454
|
|
|
455
455
|
google_auth_default.assert_called_once_with(scopes=None, default_scopes=None)
|
|
456
|
-
auth_metadata_plugin.
|
|
457
|
-
|
|
456
|
+
assert auth_metadata_plugin.call_count == 1
|
|
457
|
+
assert auth_metadata_plugin.call_args.args == (
|
|
458
|
+
mock.sentinel.credentials,
|
|
459
|
+
mock.sentinel.Request,
|
|
458
460
|
)
|
|
461
|
+
assert auth_metadata_plugin.call_args.kwargs["default_host"] == default_host
|
|
462
|
+
# google-auth >= 2.56.3 supports suppress_metrics_header; older versions omit it during fallback
|
|
463
|
+
if "suppress_metrics_header" in auth_metadata_plugin.call_args.kwargs:
|
|
464
|
+
assert auth_metadata_plugin.call_args.kwargs["suppress_metrics_header"] is True
|
|
459
465
|
|
|
460
466
|
grpc_secure_channel.assert_called_once_with(
|
|
461
467
|
expected_target, composite_creds, compression=None
|
|
@@ -64,6 +64,29 @@ from google.api_core import path_template
|
|
|
64
64
|
{"name": "parent/child/object"},
|
|
65
65
|
"/v1/a/parent/child/object",
|
|
66
66
|
],
|
|
67
|
+
# Encoding / Metacharacters in positional and named params
|
|
68
|
+
["/v1/*", ["..?$httpMethod=DELETE#"], {}, "/v1/..%3F%24httpMethod%3DDELETE%23"],
|
|
69
|
+
["/v1/**", ["path/sub/with/?and#"], {}, "/v1/path/sub/with/%3Fand%23"],
|
|
70
|
+
[
|
|
71
|
+
"/v1/{name}",
|
|
72
|
+
[],
|
|
73
|
+
{"name": "..?$httpMethod=DELETE#"},
|
|
74
|
+
"/v1/..%3F%24httpMethod%3DDELETE%23",
|
|
75
|
+
],
|
|
76
|
+
[
|
|
77
|
+
"/v1/{name=**}",
|
|
78
|
+
[],
|
|
79
|
+
{"name": "path/sub/with/?and#"},
|
|
80
|
+
"/v1/path/sub/with/%3Fand%23",
|
|
81
|
+
],
|
|
82
|
+
[
|
|
83
|
+
"/v3/{session=projects/*/locations/*/agents/*/sessions/*}:detectIntent",
|
|
84
|
+
[],
|
|
85
|
+
{
|
|
86
|
+
"session": "projects/cx/locations/global/agents/a1/sessions/..?$httpMethod=DELETE#"
|
|
87
|
+
},
|
|
88
|
+
"/v3/projects/cx/locations/global/agents/a1/sessions/..%3F%24httpMethod%3DDELETE%23:detectIntent",
|
|
89
|
+
],
|
|
67
90
|
],
|
|
68
91
|
)
|
|
69
92
|
def test_expand_success(tmpl, args, kwargs, expected_result):
|
|
@@ -651,3 +674,274 @@ def helper_test_transcode(http_options_list, expected_result_list):
|
|
|
651
674
|
if expected_result_list[2]:
|
|
652
675
|
expected_result["body"] = expected_result_list[2]
|
|
653
676
|
return (http_options, expected_result)
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
@pytest.mark.parametrize(
|
|
680
|
+
"tmpl, args, kwargs, expected_err_match",
|
|
681
|
+
[
|
|
682
|
+
# Positional * with . or ..
|
|
683
|
+
[
|
|
684
|
+
"/v1/*",
|
|
685
|
+
["."],
|
|
686
|
+
{},
|
|
687
|
+
r"^Invalid value \. for positional variable\.$",
|
|
688
|
+
],
|
|
689
|
+
[
|
|
690
|
+
"/v1/*",
|
|
691
|
+
[".."],
|
|
692
|
+
{},
|
|
693
|
+
r"^Invalid value \.\. for positional variable\.$",
|
|
694
|
+
],
|
|
695
|
+
# Named matching * with . or ..
|
|
696
|
+
[
|
|
697
|
+
"/compute/v1/projects/{project}/regions/{region}/addresses",
|
|
698
|
+
[],
|
|
699
|
+
{"project": "my-project", "region": ".."},
|
|
700
|
+
r"^Invalid value \.\. for region\.$",
|
|
701
|
+
],
|
|
702
|
+
[
|
|
703
|
+
"/compute/v1/projects/{project}/regions/{region}/addresses",
|
|
704
|
+
[],
|
|
705
|
+
{"project": "my-project", "region": "."},
|
|
706
|
+
r"^Invalid value \. for region\.$",
|
|
707
|
+
],
|
|
708
|
+
# Sub-template named matching * with . or ..
|
|
709
|
+
[
|
|
710
|
+
"/v2/{parent=projects/*/locations/*}/content:inspect",
|
|
711
|
+
[],
|
|
712
|
+
{"parent": "projects/my-project/locations/.."},
|
|
713
|
+
r"^Value for parent must not contain segments that are exactly \. or \.\. \.$",
|
|
714
|
+
],
|
|
715
|
+
[
|
|
716
|
+
"/v2/{parent=projects/*/locations/*}/content:inspect",
|
|
717
|
+
[],
|
|
718
|
+
{"parent": "projects/my-project/locations/."},
|
|
719
|
+
r"^Value for parent must not contain segments that are exactly \. or \.\. \.$",
|
|
720
|
+
],
|
|
721
|
+
[
|
|
722
|
+
"/v2/{parent=projects/*/locations/*}/content:inspect",
|
|
723
|
+
[],
|
|
724
|
+
{"parent": "projects/../locations/us-central1"},
|
|
725
|
+
r"^Value for parent must not contain segments that are exactly \. or \.\. \.$",
|
|
726
|
+
],
|
|
727
|
+
[
|
|
728
|
+
"/v2/{parent=projects/*/locations/*}/content:inspect",
|
|
729
|
+
[],
|
|
730
|
+
{"parent": "projects/./locations/us-central1"},
|
|
731
|
+
r"^Value for parent must not contain segments that are exactly \. or \.\. \.$",
|
|
732
|
+
],
|
|
733
|
+
],
|
|
734
|
+
)
|
|
735
|
+
def test_path_traversal_dots_validation_star(tmpl, args, kwargs, expected_err_match):
|
|
736
|
+
with pytest.raises(ValueError, match=expected_err_match):
|
|
737
|
+
path_template.expand(tmpl, *args, **kwargs)
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
@pytest.mark.parametrize(
|
|
741
|
+
"name_val, expected_path",
|
|
742
|
+
[
|
|
743
|
+
(
|
|
744
|
+
"projects/my-project/monitoredResourceDescriptors/instance/my-instance",
|
|
745
|
+
"/v3/projects/my-project/monitoredResourceDescriptors/instance/my-instance",
|
|
746
|
+
),
|
|
747
|
+
(
|
|
748
|
+
"projects/my-project/monitoredResourceDescriptors/a/b/c/d/e",
|
|
749
|
+
"/v3/projects/my-project/monitoredResourceDescriptors/a/b/c/d/e",
|
|
750
|
+
),
|
|
751
|
+
(
|
|
752
|
+
"projects/my-project/monitoredResourceDescriptors/instance...foo/bar",
|
|
753
|
+
"/v3/projects/my-project/monitoredResourceDescriptors/instance...foo/bar",
|
|
754
|
+
),
|
|
755
|
+
(
|
|
756
|
+
"projects/my-project/monitoredResourceDescriptors/...",
|
|
757
|
+
"/v3/projects/my-project/monitoredResourceDescriptors/...",
|
|
758
|
+
),
|
|
759
|
+
],
|
|
760
|
+
)
|
|
761
|
+
def test_path_traversal_dots_validation_double_star_valid(name_val, expected_path):
|
|
762
|
+
assert (
|
|
763
|
+
path_template.expand(
|
|
764
|
+
"/v3/{name=projects/*/monitoredResourceDescriptors/**}",
|
|
765
|
+
name=name_val,
|
|
766
|
+
)
|
|
767
|
+
== expected_path
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
@pytest.mark.parametrize(
|
|
772
|
+
"name_val",
|
|
773
|
+
[
|
|
774
|
+
"projects/my-project/monitoredResourceDescriptors/instance/my-instance/..",
|
|
775
|
+
"projects/my-project/monitoredResourceDescriptors/instance/my-instance/.",
|
|
776
|
+
"projects/my-project/monitoredResourceDescriptors/instance/my-instance/../..",
|
|
777
|
+
"projects/my-project/monitoredResourceDescriptors/instance/../my-instance/..",
|
|
778
|
+
"projects/my-project/monitoredResourceDescriptors/instance/../..",
|
|
779
|
+
"projects/my-project/monitoredResourceDescriptors/a/b/../../../c/d/e/..",
|
|
780
|
+
"projects/my-project/monitoredResourceDescriptors/a/b/c/d/e/../../../..",
|
|
781
|
+
"projects/my-project/monitoredResourceDescriptors/instance//..",
|
|
782
|
+
],
|
|
783
|
+
)
|
|
784
|
+
def test_path_traversal_dots_validation_double_star_invalid(name_val):
|
|
785
|
+
with pytest.raises(
|
|
786
|
+
ValueError,
|
|
787
|
+
match=r"^Value for name must not contain segments that are exactly \. or \.\. \.$",
|
|
788
|
+
):
|
|
789
|
+
path_template.expand(
|
|
790
|
+
"/v3/{name=projects/*/monitoredResourceDescriptors/**}",
|
|
791
|
+
name=name_val,
|
|
792
|
+
)
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
@pytest.mark.parametrize(
|
|
796
|
+
"tmpl, kwargs, expected_result",
|
|
797
|
+
[
|
|
798
|
+
["/v1/{name}", {"name": "abc-._~"}, "/v1/abc-._~"],
|
|
799
|
+
["/v1/{name=**}", {"name": "abc-._~/"}, "/v1/abc-._~/"],
|
|
800
|
+
["/v1/{name}", {"name": "a/b"}, "/v1/a/b"],
|
|
801
|
+
["/v1/{name}", {"name": "a$b?c=d#e f"}, "/v1/a%24b%3Fc%3Dd%23e%20f"],
|
|
802
|
+
],
|
|
803
|
+
)
|
|
804
|
+
def test_percent_encoding_unreserved_characters(tmpl, kwargs, expected_result):
|
|
805
|
+
result = path_template.expand(tmpl, **kwargs)
|
|
806
|
+
assert result == expected_result
|
|
807
|
+
# For single-segment with '/', validate should fail because '/' is preserved
|
|
808
|
+
if "/" in kwargs.get("name", "") and tmpl == "/v1/{name}":
|
|
809
|
+
assert not path_template.validate(tmpl, result)
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
@pytest.mark.parametrize(
|
|
813
|
+
"tmpl, args, kwargs, expected_err_match",
|
|
814
|
+
[
|
|
815
|
+
(
|
|
816
|
+
"/v1/**",
|
|
817
|
+
[".."],
|
|
818
|
+
{},
|
|
819
|
+
r"^Value for positional variable must not contain segments that are exactly \. or \.\. \.$",
|
|
820
|
+
),
|
|
821
|
+
(
|
|
822
|
+
"/v1/**",
|
|
823
|
+
["a/./b"],
|
|
824
|
+
{},
|
|
825
|
+
r"^Value for positional variable must not contain segments that are exactly \. or \.\. \.$",
|
|
826
|
+
),
|
|
827
|
+
(
|
|
828
|
+
"/v1/{name=**}",
|
|
829
|
+
[],
|
|
830
|
+
{"name": ".."},
|
|
831
|
+
r"^Value for name must not contain segments that are exactly \. or \.\. \.$",
|
|
832
|
+
),
|
|
833
|
+
(
|
|
834
|
+
"/v1/{name=**}",
|
|
835
|
+
[],
|
|
836
|
+
{"name": "a/../b"},
|
|
837
|
+
r"^Value for name must not contain segments that are exactly \. or \.\. \.$",
|
|
838
|
+
),
|
|
839
|
+
],
|
|
840
|
+
)
|
|
841
|
+
def test_path_traversal_dots_validation_bare_double_star(
|
|
842
|
+
tmpl, args, kwargs, expected_err_match
|
|
843
|
+
):
|
|
844
|
+
with pytest.raises(ValueError, match=expected_err_match):
|
|
845
|
+
path_template.expand(tmpl, *args, **kwargs)
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
@pytest.mark.parametrize(
|
|
849
|
+
"name_val, expected_err_match",
|
|
850
|
+
[
|
|
851
|
+
(
|
|
852
|
+
"projects/../locations/us-central1/buckets/my-bucket",
|
|
853
|
+
r"^Value for name must not contain segments that are exactly \. or \.\. \.$",
|
|
854
|
+
),
|
|
855
|
+
(
|
|
856
|
+
"projects/my-project/locations/./buckets/my-bucket",
|
|
857
|
+
r"^Value for name must not contain segments that are exactly \. or \.\. \.$",
|
|
858
|
+
),
|
|
859
|
+
(
|
|
860
|
+
"projects/my-project/locations/us-central1/buckets/foo/../bar",
|
|
861
|
+
r"^Value for name must not contain segments that are exactly \. or \.\. \.$",
|
|
862
|
+
),
|
|
863
|
+
(
|
|
864
|
+
"projects/my-project/locations/us-central1/buckets/.",
|
|
865
|
+
r"^Value for name must not contain segments that are exactly \. or \.\. \.$",
|
|
866
|
+
),
|
|
867
|
+
(
|
|
868
|
+
"projects/my-project/locations/us-central1/buckets/..",
|
|
869
|
+
r"^Value for name must not contain segments that are exactly \. or \.\. \.$",
|
|
870
|
+
),
|
|
871
|
+
],
|
|
872
|
+
)
|
|
873
|
+
def test_path_traversal_mixed_subtemplate(name_val, expected_err_match):
|
|
874
|
+
tmpl = "/v1/{name=projects/*/locations/*/buckets/**}"
|
|
875
|
+
with pytest.raises(ValueError, match=expected_err_match):
|
|
876
|
+
path_template.expand(tmpl, name=name_val)
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
@pytest.mark.parametrize(
|
|
880
|
+
"tmpl, args, kwargs, expected_err_match",
|
|
881
|
+
[
|
|
882
|
+
(
|
|
883
|
+
"/v1/*/**",
|
|
884
|
+
[".", "a/b"],
|
|
885
|
+
{},
|
|
886
|
+
r"^Invalid value \. for positional variable\.$",
|
|
887
|
+
),
|
|
888
|
+
(
|
|
889
|
+
"/v1/*/**",
|
|
890
|
+
["..", "a/b"],
|
|
891
|
+
{},
|
|
892
|
+
r"^Invalid value \.\. for positional variable\.$",
|
|
893
|
+
),
|
|
894
|
+
(
|
|
895
|
+
"/v1/*/**",
|
|
896
|
+
["a", "b/../c"],
|
|
897
|
+
{},
|
|
898
|
+
r"^Value for positional variable must not contain segments that are exactly \. or \.\. \.$",
|
|
899
|
+
),
|
|
900
|
+
(
|
|
901
|
+
"/v1/*/**",
|
|
902
|
+
["a", "b/./c"],
|
|
903
|
+
{},
|
|
904
|
+
r"^Value for positional variable must not contain segments that are exactly \. or \.\. \.$",
|
|
905
|
+
),
|
|
906
|
+
],
|
|
907
|
+
)
|
|
908
|
+
def test_path_traversal_multiple_positional_wildcards(
|
|
909
|
+
tmpl, args, kwargs, expected_err_match
|
|
910
|
+
):
|
|
911
|
+
with pytest.raises(ValueError, match=expected_err_match):
|
|
912
|
+
path_template.expand(tmpl, *args, **kwargs)
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
@pytest.mark.parametrize(
|
|
916
|
+
"tmpl, kwargs, expected_result",
|
|
917
|
+
[
|
|
918
|
+
("/v1/{name}", {"name": ".hidden"}, "/v1/.hidden"),
|
|
919
|
+
("/v1/{name}", {"name": "..hidden"}, "/v1/..hidden"),
|
|
920
|
+
("/v1/{name}", {"name": "file.txt"}, "/v1/file.txt"),
|
|
921
|
+
("/v1/{name=**}", {"name": "a/.hidden/b"}, "/v1/a/.hidden/b"),
|
|
922
|
+
("/v1/{name=**}", {"name": "a/..hidden/b"}, "/v1/a/..hidden/b"),
|
|
923
|
+
("/v1/{name=**}", {"name": "a/file.tar.gz/b"}, "/v1/a/file.tar.gz/b"),
|
|
924
|
+
],
|
|
925
|
+
)
|
|
926
|
+
def test_valid_dot_containing_names(tmpl, kwargs, expected_result):
|
|
927
|
+
assert path_template.expand(tmpl, **kwargs) == expected_result
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
def test_transcode_routing_with_path_traversal_fallback():
|
|
931
|
+
http_options = [
|
|
932
|
+
{"method": "get", "uri": "/v1/{name=projects/*/locations/*}"},
|
|
933
|
+
{"method": "get", "uri": "/v1/{name=projects/*}"},
|
|
934
|
+
]
|
|
935
|
+
|
|
936
|
+
# Non-matching subtemplate structure falls through to secondary binding
|
|
937
|
+
result = path_template.transcode(http_options, None, name="projects/my-project")
|
|
938
|
+
assert result["uri"] == "/v1/projects/my-project"
|
|
939
|
+
|
|
940
|
+
# Structurally matching subtemplate with invalid dot segment raises immediately
|
|
941
|
+
with pytest.raises(
|
|
942
|
+
ValueError,
|
|
943
|
+
match=r"^Value for name must not contain segments that are exactly \. or \.\. \.$",
|
|
944
|
+
):
|
|
945
|
+
path_template.transcode(
|
|
946
|
+
http_options, None, name="projects/my-project/locations/."
|
|
947
|
+
)
|
|
@@ -18,6 +18,7 @@ from unittest.mock import patch
|
|
|
18
18
|
import pytest
|
|
19
19
|
|
|
20
20
|
from google.api_core._python_package_support import (
|
|
21
|
+
PQC_GRPC_WARNING_TEMPLATE,
|
|
21
22
|
DependencyConstraint,
|
|
22
23
|
DependencyVersion,
|
|
23
24
|
check_dependency_versions,
|
|
@@ -37,7 +38,6 @@ def test_get_dependency_version(mocker, version_string_to_test):
|
|
|
37
38
|
parse_version_to_tuple(version_string_to_test), version_string_to_test
|
|
38
39
|
)
|
|
39
40
|
assert get_dependency_version("some-package") == expected
|
|
40
|
-
|
|
41
41
|
mock_importlib.assert_called_once_with("some-package")
|
|
42
42
|
|
|
43
43
|
# Test package not found
|
|
@@ -112,6 +112,22 @@ def test_warn_deprecation_for_versions_less_than(mock_get_version, mock_get_pack
|
|
|
112
112
|
in str(record[0].message)
|
|
113
113
|
)
|
|
114
114
|
|
|
115
|
+
# Case 6: Recommended version is properly formatted.
|
|
116
|
+
mock_get_packages.reset_mock()
|
|
117
|
+
mock_get_packages.side_effect = [
|
|
118
|
+
("dep-package (dep.package)", "dep-package"),
|
|
119
|
+
("my-package (my.package)", "my-package"),
|
|
120
|
+
]
|
|
121
|
+
mock_get_version.return_value = DependencyVersion(
|
|
122
|
+
parse_version_to_tuple("1.0.0"), "1.0.0"
|
|
123
|
+
)
|
|
124
|
+
with pytest.warns(FutureWarning) as record:
|
|
125
|
+
warn_deprecation_for_versions_less_than(
|
|
126
|
+
"my.package", "dep.package", "2.0.0", recommended_version="3.0.0"
|
|
127
|
+
)
|
|
128
|
+
assert len(record) == 1
|
|
129
|
+
assert "version 2.0.0 or higher (we recommend 3.0.0)." in str(record[0].message)
|
|
130
|
+
|
|
115
131
|
|
|
116
132
|
@patch(
|
|
117
133
|
"google.api_core._python_package_support.warn_deprecation_for_versions_less_than"
|
|
@@ -125,8 +141,40 @@ def test_check_dependency_versions_with_custom_warnings(mock_warn):
|
|
|
125
141
|
|
|
126
142
|
assert mock_warn.call_count == 2
|
|
127
143
|
mock_warn.assert_any_call(
|
|
128
|
-
"my-consumer",
|
|
144
|
+
"my-consumer",
|
|
145
|
+
"pkg1",
|
|
146
|
+
"1.0.0",
|
|
147
|
+
recommended_version="2.0.0",
|
|
148
|
+
message_template=None,
|
|
149
|
+
)
|
|
150
|
+
mock_warn.assert_any_call(
|
|
151
|
+
"my-consumer",
|
|
152
|
+
"pkg2",
|
|
153
|
+
"2.0.0",
|
|
154
|
+
recommended_version="3.0.0",
|
|
155
|
+
message_template=None,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@patch(
|
|
160
|
+
"google.api_core._python_package_support.warn_deprecation_for_versions_less_than"
|
|
161
|
+
)
|
|
162
|
+
def test_check_dependency_versions_default(mock_warn):
|
|
163
|
+
"""Test check_dependency_versions with default package dependency warnings."""
|
|
164
|
+
check_dependency_versions("my-consumer")
|
|
165
|
+
|
|
166
|
+
assert mock_warn.call_count == 2
|
|
167
|
+
mock_warn.assert_any_call(
|
|
168
|
+
"my-consumer",
|
|
169
|
+
"google.protobuf",
|
|
170
|
+
"6.33.5",
|
|
171
|
+
recommended_version="6.x",
|
|
172
|
+
message_template=None,
|
|
129
173
|
)
|
|
130
174
|
mock_warn.assert_any_call(
|
|
131
|
-
"my-consumer",
|
|
175
|
+
"my-consumer",
|
|
176
|
+
"grpcio",
|
|
177
|
+
"1.83.0",
|
|
178
|
+
recommended_version="1.83.x",
|
|
179
|
+
message_template=PQC_GRPC_WARNING_TEMPLATE,
|
|
132
180
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/_feature_gating_helpers.py
RENAMED
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/_python_version_support.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/gapic_v1/routing_header.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/operations_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/pagers_async.py
RENAMED
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/pagers_base.py
RENAMED
|
File without changes
|
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/transports/base.py
RENAMED
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/operations_v1/transports/rest.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/retry/retry_streaming_async.py
RENAMED
|
File without changes
|
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/google/api_core/retry/retry_unary_async.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/google_api_core.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/retry/test_retry_streaming_async.py
RENAMED
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/retry/test_retry_unary_async.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/tests/asyncio/test_rest_streaming_async.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{google_api_core-2.34.0 → google_api_core-2.35.0}/tests/unit/operations_v1/test_operations_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|