Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-google-api-core for 
openSUSE:Factory checked in at 2024-10-02 21:33:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-google-api-core (Old)
 and      /work/SRC/openSUSE:Factory/.python-google-api-core.new.19354 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-google-api-core"

Wed Oct  2 21:33:40 2024 rev:35 rq:1205028 version:2.20.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-google-api-core/python-google-api-core.changes
    2024-09-04 13:23:38.823313686 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-google-api-core.new.19354/python-google-api-core.changes
 2024-10-02 21:34:03.156048106 +0200
@@ -1,0 +2,15 @@
+Wed Oct  2 04:03:30 UTC 2024 - Steve Kowalik <steven.kowa...@suse.com>
+
+- Remove unneeded BuildRequires.
+- Refreshed patches:
+  * python-google-api-core-no-mock.patch
+
+-------------------------------------------------------------------
+Thu Sep 26 13:32:08 UTC 2024 - John Paul Adrian Glaubitz 
<adrian.glaub...@suse.com>
+
+- Update to 2.20.0
+  * Add async unsupported paramater exception (#694)
+  * Add support for asynchronous rest streaming (#686)
+  * Add support for creating exceptions from an asynchronous response (#688)
+
+-------------------------------------------------------------------

Old:
----
  google_api_core-2.19.2.tar.gz

New:
----
  google_api_core-2.20.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-google-api-core.spec ++++++
--- /var/tmp/diff_new_pack.Ybg4ZR/_old  2024-10-02 21:34:03.796074714 +0200
+++ /var/tmp/diff_new_pack.Ybg4ZR/_new  2024-10-02 21:34:03.796074714 +0200
@@ -26,23 +26,17 @@
 %endif
 %{?sle15_python_module_pythons}
 Name:           python-google-api-core
-Version:        2.19.2
+Version:        2.20.0
 Release:        0
 Summary:        Google API client core library
 License:        Apache-2.0
 URL:            https://github.com/googleapis/python-api-core
 Source:         
https://files.pythonhosted.org/packages/source/g/google_api_core/google_api_core-%{version}.tar.gz
-# https://github.com/googleapis/python-api-core/issues/377
+# PATCH-FIX-UPSTREAM Based on gh#googleapis/python-api-core#713
 Patch0:         python-google-api-core-no-mock.patch
-BuildRequires:  %{python_module google-auth >= 2.14.1}
+# Needed for python_sitelib/google
 BuildRequires:  %{python_module googleapis-common-protos >= 1.53.0}
-BuildRequires:  %{python_module grpcio >= 1.33.2}
-BuildRequires:  %{python_module grpcio-status >= 1.33.2}
 BuildRequires:  %{python_module pip}
-BuildRequires:  %{python_module proto-plus >= 1.22.3 with %python-proto-plus < 
2.0.0dev0}
-BuildRequires:  %{python_module protobuf >= 3.19.5 with %python-protobuf < 
5.0.0.dev0}
-BuildRequires:  %{python_module pytz}
-BuildRequires:  %{python_module requests >= 2.18.0}
 BuildRequires:  %{python_module setuptools >= 40.3.0}
 BuildRequires:  %{python_module wheel}
 %if 0%{?sle_version} >= 150400
@@ -50,7 +44,7 @@
 %endif
 # START TESTING SECTION
 %if %{with test}
-BuildRequires:  %{python_module google-api-core >= %{version}}
+BuildRequires:  %{python_module google-api-core = %{version}}
 BuildRequires:  %{python_module proto-plus}
 BuildRequires:  %{python_module pytest-asyncio}
 BuildRequires:  %{python_module pytest}
@@ -60,11 +54,9 @@
 BuildRequires:  python-rpm-macros
 Requires:       python-google-auth >= 2.14.1
 Requires:       python-googleapis-common-protos >= 1.53.0
-Requires:       python-grpcio >= 1.33.2
-Requires:       python-grpcio-status >= 1.33.2
-Requires:       python-pytz
+Requires:       python-grpcio >= 1.49.1
+Requires:       python-grpcio-status >= 1.49.1
 Requires:       python-requests >= 2.18.0
-Requires:       python-setuptools >= 40.3.0
 Requires:       (python-proto-plus >= 1.22.3 with python-proto-plus < 
2.0.0dev0)
 Requires:       (python-protobuf >= 3.19.5 with python-protobuf < 5.0.0.dev0)
 BuildArch:      noarch
@@ -90,13 +82,11 @@
 %pytest
 %endif
 
-%clean
-
 %if !%{with test}
 %files %{python_files}
 %license LICENSE
 %doc README.rst
 %{python_sitelib}/google/api_core
-%{python_sitelib}/google_api_core-%{version}*-info
+%{python_sitelib}/google_api_core-%{version}.dist-info
 %endif
 

++++++ google_api_core-2.19.2.tar.gz -> google_api_core-2.20.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google_api_core-2.19.2/PKG-INFO 
new/google_api_core-2.20.0/PKG-INFO
--- old/google_api_core-2.19.2/PKG-INFO 2024-08-27 22:59:16.198442000 +0200
+++ new/google_api_core-2.20.0/PKG-INFO 2024-09-19 20:22:39.577738800 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: google-api-core
-Version: 2.19.2
+Version: 2.20.0
 Summary: Google API client core library
 Home-page: https://github.com/googleapis/python-api-core
 Author: Google LLC
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_api_core-2.19.2/google/api_core/_rest_streaming_base.py 
new/google_api_core-2.20.0/google/api_core/_rest_streaming_base.py
--- old/google_api_core-2.19.2/google/api_core/_rest_streaming_base.py  
1970-01-01 01:00:00.000000000 +0100
+++ new/google_api_core-2.20.0/google/api_core/_rest_streaming_base.py  
2024-09-19 20:20:48.000000000 +0200
@@ -0,0 +1,118 @@
+# Copyright 2024 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.
+
+"""Helpers for server-side streaming in REST."""
+
+from collections import deque
+import string
+from typing import Deque, Union
+import types
+
+import proto
+import google.protobuf.message
+from google.protobuf.json_format import Parse
+
+
+class BaseResponseIterator:
+    """Base Iterator over REST API responses. This class should not be used 
directly.
+
+    Args:
+        response_message_cls (Union[proto.Message, 
google.protobuf.message.Message]): A response
+        class expected to be returned from an API.
+
+    Raises:
+        ValueError: If `response_message_cls` is not a subclass of 
`proto.Message` or `google.protobuf.message.Message`.
+    """
+
+    def __init__(
+        self,
+        response_message_cls: Union[proto.Message, 
google.protobuf.message.Message],
+    ):
+        self._response_message_cls = response_message_cls
+        # Contains a list of JSON responses ready to be sent to user.
+        self._ready_objs: Deque[str] = deque()
+        # Current JSON response being built.
+        self._obj = ""
+        # Keeps track of the nesting level within a JSON object.
+        self._level = 0
+        # Keeps track whether HTTP response is currently sending values
+        # inside of a string value.
+        self._in_string = False
+        # Whether an escape symbol "\" was encountered.
+        self._escape_next = False
+
+        self._grab = types.MethodType(self._create_grab(), self)
+
+    def _process_chunk(self, chunk: str):
+        if self._level == 0:
+            if chunk[0] != "[":
+                raise ValueError(
+                    "Can only parse array of JSON objects, instead got %s" % 
chunk
+                )
+        for char in chunk:
+            if char == "{":
+                if self._level == 1:
+                    # Level 1 corresponds to the outermost JSON object
+                    # (i.e. the one we care about).
+                    self._obj = ""
+                if not self._in_string:
+                    self._level += 1
+                self._obj += char
+            elif char == "}":
+                self._obj += char
+                if not self._in_string:
+                    self._level -= 1
+                if not self._in_string and self._level == 1:
+                    self._ready_objs.append(self._obj)
+            elif char == '"':
+                # Helps to deal with an escaped quotes inside of a string.
+                if not self._escape_next:
+                    self._in_string = not self._in_string
+                self._obj += char
+            elif char in string.whitespace:
+                if self._in_string:
+                    self._obj += char
+            elif char == "[":
+                if self._level == 0:
+                    self._level += 1
+                else:
+                    self._obj += char
+            elif char == "]":
+                if self._level == 1:
+                    self._level -= 1
+                else:
+                    self._obj += char
+            else:
+                self._obj += char
+            self._escape_next = not self._escape_next if char == "\\" else 
False
+
+    def _create_grab(self):
+        if issubclass(self._response_message_cls, proto.Message):
+
+            def grab(this):
+                return this._response_message_cls.from_json(
+                    this._ready_objs.popleft(), ignore_unknown_fields=True
+                )
+
+            return grab
+        elif issubclass(self._response_message_cls, 
google.protobuf.message.Message):
+
+            def grab(this):
+                return Parse(this._ready_objs.popleft(), 
this._response_message_cls())
+
+            return grab
+        else:
+            raise ValueError(
+                "Response message class must be a subclass of proto.Message or 
google.protobuf.message.Message."
+            )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google_api_core-2.19.2/google/api_core/exceptions.py 
new/google_api_core-2.20.0/google/api_core/exceptions.py
--- old/google_api_core-2.19.2/google/api_core/exceptions.py    2024-08-27 
22:57:23.000000000 +0200
+++ new/google_api_core-2.20.0/google/api_core/exceptions.py    2024-09-19 
20:20:48.000000000 +0200
@@ -22,7 +22,7 @@
 from __future__ import unicode_literals
 
 import http.client
-from typing import Dict
+from typing import Optional, Dict
 from typing import Union
 import warnings
 
@@ -442,6 +442,12 @@
     grpc_status_code = grpc.StatusCode.DEADLINE_EXCEEDED if grpc is not None 
else None
 
 
+class AsyncRestUnsupportedParameterError(NotImplementedError):
+    """Raised when an unsupported parameter is configured against async rest 
transport."""
+
+    pass
+
+
 def exception_class_for_http_status(status_code):
     """Return the exception class for a specific HTTP status code.
 
@@ -476,22 +482,37 @@
     return error
 
 
-def from_http_response(response):
-    """Create a :class:`GoogleAPICallError` from a :class:`requests.Response`.
+def _format_rest_error_message(error, method, url):
+    method = method.upper() if method else None
+    message = "{method} {url}: {error}".format(
+        method=method,
+        url=url,
+        error=error,
+    )
+    return message
+
+
+# NOTE: We're moving away from `from_http_status` because it expects an 
aiohttp response compared
+# to `format_http_response_error` which expects a more abstract response from 
google.auth and is
+# compatible with both sync and async response types.
+# TODO(https://github.com/googleapis/python-api-core/issues/691): Add type 
hint for response.
+def format_http_response_error(
+    response, method: str, url: str, payload: Optional[Dict] = None
+):
+    """Create a :class:`GoogleAPICallError` from a google auth rest response.
 
     Args:
-        response (requests.Response): The HTTP response.
+        response Union[google.auth.transport.Response, 
google.auth.aio.transport.Response]: The HTTP response.
+        method Optional(str): The HTTP request method.
+        url Optional(str): The HTTP request url.
+        payload Optional(dict): The HTTP response payload. If not passed in, 
it is read from response for a response type of google.auth.transport.Response.
 
     Returns:
         GoogleAPICallError: An instance of the appropriate subclass of
             :class:`GoogleAPICallError`, with the message and errors populated
             from the response.
     """
-    try:
-        payload = response.json()
-    except ValueError:
-        payload = {"error": {"message": response.text or "unknown error"}}
-
+    payload = {} if not payload else payload
     error_message = payload.get("error", {}).get("message", "unknown error")
     errors = payload.get("error", {}).get("errors", ())
     # In JSON, details are already formatted in developer-friendly way.
@@ -504,12 +525,7 @@
         )
     )
     error_info = error_info[0] if error_info else None
-
-    message = "{method} {url}: {error}".format(
-        method=response.request.method,
-        url=response.request.url,
-        error=error_message,
-    )
+    message = _format_rest_error_message(error_message, method, url)
 
     exception = from_http_status(
         response.status_code,
@@ -522,6 +538,26 @@
     return exception
 
 
+def from_http_response(response):
+    """Create a :class:`GoogleAPICallError` from a :class:`requests.Response`.
+
+    Args:
+        response (requests.Response): The HTTP response.
+
+    Returns:
+        GoogleAPICallError: An instance of the appropriate subclass of
+            :class:`GoogleAPICallError`, with the message and errors populated
+            from the response.
+    """
+    try:
+        payload = response.json()
+    except ValueError:
+        payload = {"error": {"message": response.text or "unknown error"}}
+    return format_http_response_error(
+        response, response.request.method, response.request.url, payload
+    )
+
+
 def exception_class_for_grpc_status(status_code):
     """Return the exception class for a specific :class:`grpc.StatusCode`.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_api_core-2.19.2/google/api_core/gapic_v1/method_async.py 
new/google_api_core-2.20.0/google/api_core/gapic_v1/method_async.py
--- old/google_api_core-2.19.2/google/api_core/gapic_v1/method_async.py 
2024-08-27 22:57:23.000000000 +0200
+++ new/google_api_core-2.20.0/google/api_core/gapic_v1/method_async.py 
2024-09-19 20:20:48.000000000 +0200
@@ -25,6 +25,8 @@
 from google.api_core.gapic_v1.method import DEFAULT  # noqa: F401
 from google.api_core.gapic_v1.method import USE_DEFAULT_METADATA  # noqa: F401
 
+_DEFAULT_ASYNC_TRANSPORT_KIND = "grpc_asyncio"
+
 
 def wrap_method(
     func,
@@ -32,6 +34,7 @@
     default_timeout=None,
     default_compression=None,
     client_info=client_info.DEFAULT_CLIENT_INFO,
+    kind=_DEFAULT_ASYNC_TRANSPORT_KIND,
 ):
     """Wrap an async RPC method with common behavior.
 
@@ -40,7 +43,8 @@
             and ``compression`` arguments and applies the common error mapping,
             retry, timeout, metadata, and compression behavior to the 
low-level RPC method.
     """
-    func = grpc_helpers_async.wrap_errors(func)
+    if kind == _DEFAULT_ASYNC_TRANSPORT_KIND:
+        func = grpc_helpers_async.wrap_errors(func)
 
     metadata = [client_info.to_grpc_metadata()] if client_info is not None 
else None
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_api_core-2.19.2/google/api_core/rest_streaming.py 
new/google_api_core-2.20.0/google/api_core/rest_streaming.py
--- old/google_api_core-2.19.2/google/api_core/rest_streaming.py        
2024-08-27 22:57:23.000000000 +0200
+++ new/google_api_core-2.20.0/google/api_core/rest_streaming.py        
2024-09-19 20:20:48.000000000 +0200
@@ -14,17 +14,15 @@
 
 """Helpers for server-side streaming in REST."""
 
-from collections import deque
-import string
-from typing import Deque, Union
+from typing import Union
 
 import proto
 import requests
 import google.protobuf.message
-from google.protobuf.json_format import Parse
+from google.api_core._rest_streaming_base import BaseResponseIterator
 
 
-class ResponseIterator:
+class ResponseIterator(BaseResponseIterator):
     """Iterator over REST API responses.
 
     Args:
@@ -33,7 +31,8 @@
         class expected to be returned from an API.
 
     Raises:
-        ValueError: If `response_message_cls` is not a subclass of 
`proto.Message` or `google.protobuf.message.Message`.
+        ValueError:
+            - If `response_message_cls` is not a subclass of `proto.Message` 
or `google.protobuf.message.Message`.
     """
 
     def __init__(
@@ -42,68 +41,16 @@
         response_message_cls: Union[proto.Message, 
google.protobuf.message.Message],
     ):
         self._response = response
-        self._response_message_cls = response_message_cls
         # Inner iterator over HTTP response's content.
         self._response_itr = self._response.iter_content(decode_unicode=True)
-        # Contains a list of JSON responses ready to be sent to user.
-        self._ready_objs: Deque[str] = deque()
-        # Current JSON response being built.
-        self._obj = ""
-        # Keeps track of the nesting level within a JSON object.
-        self._level = 0
-        # Keeps track whether HTTP response is currently sending values
-        # inside of a string value.
-        self._in_string = False
-        # Whether an escape symbol "\" was encountered.
-        self._escape_next = False
+        super(ResponseIterator, self).__init__(
+            response_message_cls=response_message_cls
+        )
 
     def cancel(self):
         """Cancel existing streaming operation."""
         self._response.close()
 
-    def _process_chunk(self, chunk: str):
-        if self._level == 0:
-            if chunk[0] != "[":
-                raise ValueError(
-                    "Can only parse array of JSON objects, instead got %s" % 
chunk
-                )
-        for char in chunk:
-            if char == "{":
-                if self._level == 1:
-                    # Level 1 corresponds to the outermost JSON object
-                    # (i.e. the one we care about).
-                    self._obj = ""
-                if not self._in_string:
-                    self._level += 1
-                self._obj += char
-            elif char == "}":
-                self._obj += char
-                if not self._in_string:
-                    self._level -= 1
-                if not self._in_string and self._level == 1:
-                    self._ready_objs.append(self._obj)
-            elif char == '"':
-                # Helps to deal with an escaped quotes inside of a string.
-                if not self._escape_next:
-                    self._in_string = not self._in_string
-                self._obj += char
-            elif char in string.whitespace:
-                if self._in_string:
-                    self._obj += char
-            elif char == "[":
-                if self._level == 0:
-                    self._level += 1
-                else:
-                    self._obj += char
-            elif char == "]":
-                if self._level == 1:
-                    self._level -= 1
-                else:
-                    self._obj += char
-            else:
-                self._obj += char
-            self._escape_next = not self._escape_next if char == "\\" else 
False
-
     def __next__(self):
         while not self._ready_objs:
             try:
@@ -115,18 +62,5 @@
                 raise e
         return self._grab()
 
-    def _grab(self):
-        # Add extra quotes to make json.loads happy.
-        if issubclass(self._response_message_cls, proto.Message):
-            return self._response_message_cls.from_json(
-                self._ready_objs.popleft(), ignore_unknown_fields=True
-            )
-        elif issubclass(self._response_message_cls, 
google.protobuf.message.Message):
-            return Parse(self._ready_objs.popleft(), 
self._response_message_cls())
-        else:
-            raise ValueError(
-                "Response message class must be a subclass of proto.Message or 
google.protobuf.message.Message."
-            )
-
     def __iter__(self):
         return self
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_api_core-2.19.2/google/api_core/rest_streaming_async.py 
new/google_api_core-2.20.0/google/api_core/rest_streaming_async.py
--- old/google_api_core-2.19.2/google/api_core/rest_streaming_async.py  
1970-01-01 01:00:00.000000000 +0100
+++ new/google_api_core-2.20.0/google/api_core/rest_streaming_async.py  
2024-09-19 20:20:48.000000000 +0200
@@ -0,0 +1,83 @@
+# Copyright 2024 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.
+
+"""Helpers for asynchronous server-side streaming in REST."""
+
+from typing import Union
+
+import proto
+
+try:
+    import google.auth.aio.transport
+except ImportError as e:  # pragma: NO COVER
+    raise ImportError(
+        "google-auth>=2.35.0 is required to use asynchronous rest streaming."
+    ) from e
+
+import google.protobuf.message
+from google.api_core._rest_streaming_base import BaseResponseIterator
+
+
+class AsyncResponseIterator(BaseResponseIterator):
+    """Asynchronous Iterator over REST API responses.
+
+    Args:
+        response (google.auth.aio.transport.Response): An API response object.
+        response_message_cls (Union[proto.Message, 
google.protobuf.message.Message]): A response
+        class expected to be returned from an API.
+
+    Raises:
+        ValueError:
+            - If `response_message_cls` is not a subclass of `proto.Message` 
or `google.protobuf.message.Message`.
+    """
+
+    def __init__(
+        self,
+        response: google.auth.aio.transport.Response,
+        response_message_cls: Union[proto.Message, 
google.protobuf.message.Message],
+    ):
+        self._response = response
+        self._chunk_size = 1024
+        self._response_itr = self._response.content().__aiter__()
+        super(AsyncResponseIterator, self).__init__(
+            response_message_cls=response_message_cls
+        )
+
+    async def __aenter__(self):
+        return self
+
+    async def cancel(self):
+        """Cancel existing streaming operation."""
+        await self._response.close()
+
+    async def __anext__(self):
+        while not self._ready_objs:
+            try:
+                chunk = await self._response_itr.__anext__()
+                chunk = chunk.decode("utf-8")
+                self._process_chunk(chunk)
+            except StopAsyncIteration as e:
+                if self._level > 0:
+                    raise ValueError("i Unfinished stream: %s" % self._obj)
+                raise e
+            except ValueError as e:
+                raise e
+        return self._grab()
+
+    def __aiter__(self):
+        return self
+
+    async def __aexit__(self, exc_type, exc, tb):
+        """Cancel existing async streaming operation."""
+        await self._response.close()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google_api_core-2.19.2/google/api_core/version.py 
new/google_api_core-2.20.0/google/api_core/version.py
--- old/google_api_core-2.19.2/google/api_core/version.py       2024-08-27 
22:57:23.000000000 +0200
+++ new/google_api_core-2.20.0/google/api_core/version.py       2024-09-19 
20:20:48.000000000 +0200
@@ -12,4 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-__version__ = "2.19.2"
+__version__ = "2.20.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_api_core-2.19.2/google_api_core.egg-info/PKG-INFO 
new/google_api_core-2.20.0/google_api_core.egg-info/PKG-INFO
--- old/google_api_core-2.19.2/google_api_core.egg-info/PKG-INFO        
2024-08-27 22:59:16.000000000 +0200
+++ new/google_api_core-2.20.0/google_api_core.egg-info/PKG-INFO        
2024-09-19 20:22:39.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: google-api-core
-Version: 2.19.2
+Version: 2.20.0
 Summary: Google API client core library
 Home-page: https://github.com/googleapis/python-api-core
 Author: Google LLC
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_api_core-2.19.2/google_api_core.egg-info/SOURCES.txt 
new/google_api_core-2.20.0/google_api_core.egg-info/SOURCES.txt
--- old/google_api_core-2.19.2/google_api_core.egg-info/SOURCES.txt     
2024-08-27 22:59:16.000000000 +0200
+++ new/google_api_core-2.20.0/google_api_core.egg-info/SOURCES.txt     
2024-09-19 20:22:39.000000000 +0200
@@ -4,6 +4,7 @@
 setup.cfg
 setup.py
 google/api_core/__init__.py
+google/api_core/_rest_streaming_base.py
 google/api_core/bidi.py
 google/api_core/client_info.py
 google/api_core/client_options.py
@@ -23,6 +24,7 @@
 google/api_core/py.typed
 google/api_core/rest_helpers.py
 google/api_core/rest_streaming.py
+google/api_core/rest_streaming_async.py
 google/api_core/retry_async.py
 google/api_core/timeout.py
 google/api_core/universe.py
@@ -62,10 +64,12 @@
 google_api_core.egg-info/requires.txt
 google_api_core.egg-info/top_level.txt
 tests/__init__.py
+tests/helpers.py
 tests/asyncio/__init__.py
 tests/asyncio/test_grpc_helpers_async.py
 tests/asyncio/test_operation_async.py
 tests/asyncio/test_page_iterator_async.py
+tests/asyncio/test_rest_streaming_async.py
 tests/asyncio/future/__init__.py
 tests/asyncio/future/test_async_future.py
 tests/asyncio/gapic/test_config_async.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_api_core-2.19.2/tests/asyncio/gapic/test_method_async.py 
new/google_api_core-2.20.0/tests/asyncio/gapic/test_method_async.py
--- old/google_api_core-2.19.2/tests/asyncio/gapic/test_method_async.py 
2024-08-27 22:57:23.000000000 +0200
+++ new/google_api_core-2.20.0/tests/asyncio/gapic/test_method_async.py 
2024-09-19 20:20:48.000000000 +0200
@@ -252,3 +252,14 @@
 
     assert result == 42
     method.assert_called_once_with(timeout=22, metadata=mock.ANY)
+
+
+@pytest.mark.asyncio
+async def test_wrap_method_without_wrap_errors():
+    fake_call = mock.AsyncMock()
+
+    wrapped_method = gapic_v1.method_async.wrap_method(fake_call, kind="rest")
+    with mock.patch("google.api_core.grpc_helpers_async.wrap_errors") as 
method:
+        await wrapped_method()
+
+        method.assert_not_called()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_api_core-2.19.2/tests/asyncio/test_rest_streaming_async.py 
new/google_api_core-2.20.0/tests/asyncio/test_rest_streaming_async.py
--- old/google_api_core-2.19.2/tests/asyncio/test_rest_streaming_async.py       
1970-01-01 01:00:00.000000000 +0100
+++ new/google_api_core-2.20.0/tests/asyncio/test_rest_streaming_async.py       
2024-09-19 20:20:48.000000000 +0200
@@ -0,0 +1,378 @@
+# Copyright 2024 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.
+
+# TODO: set random.seed explicitly in each test function.
+# See related issue: https://github.com/googleapis/python-api-core/issues/689.
+
+import pytest  # noqa: I202
+import mock
+
+import datetime
+import logging
+import random
+import time
+from typing import List, AsyncIterator
+
+import proto
+
+try:
+    from google.auth.aio.transport import Response
+
+    AUTH_AIO_INSTALLED = True
+except ImportError:
+    AUTH_AIO_INSTALLED = False
+
+if not AUTH_AIO_INSTALLED:  # pragma: NO COVER
+    pytest.skip(
+        "google-auth>=2.35.0 is required to use asynchronous rest streaming.",
+        allow_module_level=True,
+    )
+
+from google.api_core import rest_streaming_async
+from google.api import http_pb2
+from google.api import httpbody_pb2
+
+
+from ..helpers import Composer, Song, EchoResponse, parse_responses
+
+
+__protobuf__ = proto.module(package=__name__)
+SEED = int(time.time())
+logging.info(f"Starting async rest streaming tests with random seed: {SEED}")
+random.seed(SEED)
+
+
+async def mock_async_gen(data, chunk_size=1):
+    for i in range(0, len(data)):  # pragma: NO COVER
+        chunk = data[i : i + chunk_size]
+        yield chunk.encode("utf-8")
+
+
+class ResponseMock(Response):
+    class _ResponseItr(AsyncIterator[bytes]):
+        def __init__(self, _response_bytes: bytes, random_split=False):
+            self._responses_bytes = _response_bytes
+            self._idx = 0
+            self._random_split = random_split
+
+        def __aiter__(self):
+            return self
+
+        async def __anext__(self):
+            if self._idx >= len(self._responses_bytes):
+                raise StopAsyncIteration
+            if self._random_split:
+                n = random.randint(1, len(self._responses_bytes[self._idx :]))
+            else:
+                n = 1
+            x = self._responses_bytes[self._idx : self._idx + n]
+            self._idx += n
+            return x
+
+    def __init__(
+        self,
+        responses: List[proto.Message],
+        response_cls,
+        random_split=False,
+    ):
+        self._responses = responses
+        self._random_split = random_split
+        self._response_message_cls = response_cls
+
+    def _parse_responses(self):
+        return parse_responses(self._response_message_cls, self._responses)
+
+    @property
+    async def headers(self):
+        raise NotImplementedError()
+
+    @property
+    async def status_code(self):
+        raise NotImplementedError()
+
+    async def close(self):
+        raise NotImplementedError()
+
+    async def content(self, chunk_size=None):
+        itr = self._ResponseItr(
+            self._parse_responses(), random_split=self._random_split
+        )
+        async for chunk in itr:
+            yield chunk
+
+    async def read(self):
+        raise NotImplementedError()
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize(
+    "random_split,resp_message_is_proto_plus",
+    [(False, True), (False, False)],
+)
+async def test_next_simple(random_split, resp_message_is_proto_plus):
+    if resp_message_is_proto_plus:
+        response_type = EchoResponse
+        responses = [EchoResponse(content="hello world"), 
EchoResponse(content="yes")]
+    else:
+        response_type = httpbody_pb2.HttpBody
+        responses = [
+            httpbody_pb2.HttpBody(content_type="hello world"),
+            httpbody_pb2.HttpBody(content_type="yes"),
+        ]
+
+    resp = ResponseMock(
+        responses=responses, random_split=random_split, 
response_cls=response_type
+    )
+    itr = rest_streaming_async.AsyncResponseIterator(resp, response_type)
+    idx = 0
+    async for response in itr:
+        assert response == responses[idx]
+        idx += 1
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize(
+    "random_split,resp_message_is_proto_plus",
+    [
+        (True, True),
+        (False, True),
+        (True, False),
+        (False, False),
+    ],
+)
+async def test_next_nested(random_split, resp_message_is_proto_plus):
+    if resp_message_is_proto_plus:
+        response_type = Song
+        responses = [
+            Song(title="some song", composer=Composer(given_name="some name")),
+            Song(title="another song", date_added=datetime.datetime(2021, 12, 
17)),
+        ]
+    else:
+        # Although `http_pb2.HttpRule`` is used in the response, any response 
message
+        # can be used which meets this criteria for the test of having a 
nested field.
+        response_type = http_pb2.HttpRule
+        responses = [
+            http_pb2.HttpRule(
+                selector="some selector",
+                custom=http_pb2.CustomHttpPattern(kind="some kind"),
+            ),
+            http_pb2.HttpRule(
+                selector="another selector",
+                custom=http_pb2.CustomHttpPattern(path="some path"),
+            ),
+        ]
+    resp = ResponseMock(
+        responses=responses, random_split=random_split, 
response_cls=response_type
+    )
+    itr = rest_streaming_async.AsyncResponseIterator(resp, response_type)
+    idx = 0
+    async for response in itr:
+        assert response == responses[idx]
+        idx += 1
+    assert idx == len(responses)
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize(
+    "random_split,resp_message_is_proto_plus",
+    [
+        (True, True),
+        (False, True),
+        (True, False),
+        (False, False),
+    ],
+)
+async def test_next_stress(random_split, resp_message_is_proto_plus):
+    n = 50
+    if resp_message_is_proto_plus:
+        response_type = Song
+        responses = [
+            Song(title="title_%d" % i, composer=Composer(given_name="name_%d" 
% i))
+            for i in range(n)
+        ]
+    else:
+        response_type = http_pb2.HttpRule
+        responses = [
+            http_pb2.HttpRule(
+                selector="selector_%d" % i,
+                custom=http_pb2.CustomHttpPattern(path="path_%d" % i),
+            )
+            for i in range(n)
+        ]
+    resp = ResponseMock(
+        responses=responses, random_split=random_split, 
response_cls=response_type
+    )
+    itr = rest_streaming_async.AsyncResponseIterator(resp, response_type)
+    idx = 0
+    async for response in itr:
+        assert response == responses[idx]
+        idx += 1
+    assert idx == n
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize(
+    "random_split,resp_message_is_proto_plus",
+    [
+        (True, True),
+        (False, True),
+        (True, False),
+        (False, False),
+    ],
+)
+async def test_next_escaped_characters_in_string(
+    random_split, resp_message_is_proto_plus
+):
+    if resp_message_is_proto_plus:
+        response_type = Song
+        composer_with_relateds = Composer()
+        relateds = ["Artist A", "Artist B"]
+        composer_with_relateds.relateds = relateds
+
+        responses = [
+            Song(
+                title='ti"tle\nfoo\tbar{}', 
composer=Composer(given_name="name\n\n\n")
+            ),
+            Song(
+                title='{"this is weird": "totally"}',
+                composer=Composer(given_name="\\{}\\"),
+            ),
+            Song(title='\\{"key": ["value",]}\\', 
composer=composer_with_relateds),
+        ]
+    else:
+        response_type = http_pb2.Http
+        responses = [
+            http_pb2.Http(
+                rules=[
+                    http_pb2.HttpRule(
+                        selector='ti"tle\nfoo\tbar{}',
+                        custom=http_pb2.CustomHttpPattern(kind="name\n\n\n"),
+                    )
+                ]
+            ),
+            http_pb2.Http(
+                rules=[
+                    http_pb2.HttpRule(
+                        selector='{"this is weird": "totally"}',
+                        custom=http_pb2.CustomHttpPattern(kind="\\{}\\"),
+                    )
+                ]
+            ),
+            http_pb2.Http(
+                rules=[
+                    http_pb2.HttpRule(
+                        selector='\\{"key": ["value",]}\\',
+                        custom=http_pb2.CustomHttpPattern(kind="\\{}\\"),
+                    )
+                ]
+            ),
+        ]
+    resp = ResponseMock(
+        responses=responses, random_split=random_split, 
response_cls=response_type
+    )
+    itr = rest_streaming_async.AsyncResponseIterator(resp, response_type)
+    idx = 0
+    async for response in itr:
+        assert response == responses[idx]
+        idx += 1
+    assert idx == len(responses)
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize("response_type", [EchoResponse, 
httpbody_pb2.HttpBody])
+async def test_next_not_array(response_type):
+
+    data = '{"hello": 0}'
+    with mock.patch.object(
+        ResponseMock, "content", return_value=mock_async_gen(data)
+    ) as mock_method:
+        resp = ResponseMock(responses=[], response_cls=response_type)
+        itr = rest_streaming_async.AsyncResponseIterator(resp, response_type)
+        with pytest.raises(ValueError):
+            await itr.__anext__()
+        mock_method.assert_called_once()
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize("response_type", [EchoResponse, 
httpbody_pb2.HttpBody])
+async def test_cancel(response_type):
+    with mock.patch.object(
+        ResponseMock, "close", new_callable=mock.AsyncMock
+    ) as mock_method:
+        resp = ResponseMock(responses=[], response_cls=response_type)
+        itr = rest_streaming_async.AsyncResponseIterator(resp, response_type)
+        await itr.cancel()
+        mock_method.assert_called_once()
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize("response_type", [EchoResponse, 
httpbody_pb2.HttpBody])
+async def test_iterator_as_context_manager(response_type):
+    with mock.patch.object(
+        ResponseMock, "close", new_callable=mock.AsyncMock
+    ) as mock_method:
+        resp = ResponseMock(responses=[], response_cls=response_type)
+        async with rest_streaming_async.AsyncResponseIterator(resp, 
response_type):
+            pass
+        mock_method.assert_called_once()
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize(
+    "response_type,return_value",
+    [
+        (EchoResponse, bytes('[{"content": "hello"}, {', "utf-8")),
+        (httpbody_pb2.HttpBody, bytes('[{"content_type": "hello"}, {', 
"utf-8")),
+    ],
+)
+async def test_check_buffer(response_type, return_value):
+    with mock.patch.object(
+        ResponseMock,
+        "_parse_responses",
+        return_value=return_value,
+    ):
+        resp = ResponseMock(responses=[], response_cls=response_type)
+        itr = rest_streaming_async.AsyncResponseIterator(resp, response_type)
+        with pytest.raises(ValueError):
+            await itr.__anext__()
+            await itr.__anext__()
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize("response_type", [EchoResponse, 
httpbody_pb2.HttpBody])
+async def test_next_html(response_type):
+
+    data = "<!DOCTYPE html><html></html>"
+    with mock.patch.object(
+        ResponseMock, "content", return_value=mock_async_gen(data)
+    ) as mock_method:
+        resp = ResponseMock(responses=[], response_cls=response_type)
+
+        itr = rest_streaming_async.AsyncResponseIterator(resp, response_type)
+        with pytest.raises(ValueError):
+            await itr.__anext__()
+        mock_method.assert_called_once()
+
+
+@pytest.mark.asyncio
+async def test_invalid_response_class():
+    class SomeClass:
+        pass
+
+    resp = ResponseMock(responses=[], response_cls=SomeClass)
+    with pytest.raises(
+        ValueError,
+        match="Response message class must be a subclass of proto.Message or 
google.protobuf.message.Message",
+    ):
+        rest_streaming_async.AsyncResponseIterator(resp, SomeClass)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google_api_core-2.19.2/tests/helpers.py 
new/google_api_core-2.20.0/tests/helpers.py
--- old/google_api_core-2.19.2/tests/helpers.py 1970-01-01 01:00:00.000000000 
+0100
+++ new/google_api_core-2.20.0/tests/helpers.py 2024-09-19 20:20:48.000000000 
+0200
@@ -0,0 +1,71 @@
+# Copyright 2024 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.
+
+"""Helpers for tests"""
+
+import logging
+from typing import List
+
+import proto
+
+from google.protobuf import duration_pb2
+from google.protobuf import timestamp_pb2
+from google.protobuf.json_format import MessageToJson
+
+
+class Genre(proto.Enum):
+    GENRE_UNSPECIFIED = 0
+    CLASSICAL = 1
+    JAZZ = 2
+    ROCK = 3
+
+
+class Composer(proto.Message):
+    given_name = proto.Field(proto.STRING, number=1)
+    family_name = proto.Field(proto.STRING, number=2)
+    relateds = proto.RepeatedField(proto.STRING, number=3)
+    indices = proto.MapField(proto.STRING, proto.STRING, number=4)
+
+
+class Song(proto.Message):
+    composer = proto.Field(Composer, number=1)
+    title = proto.Field(proto.STRING, number=2)
+    lyrics = proto.Field(proto.STRING, number=3)
+    year = proto.Field(proto.INT32, number=4)
+    genre = proto.Field(Genre, number=5)
+    is_five_mins_longer = proto.Field(proto.BOOL, number=6)
+    score = proto.Field(proto.DOUBLE, number=7)
+    likes = proto.Field(proto.INT64, number=8)
+    duration = proto.Field(duration_pb2.Duration, number=9)
+    date_added = proto.Field(timestamp_pb2.Timestamp, number=10)
+
+
+class EchoResponse(proto.Message):
+    content = proto.Field(proto.STRING, number=1)
+
+
+def parse_responses(response_message_cls, all_responses: List[proto.Message]) 
-> bytes:
+    # json.dumps returns a string surrounded with quotes that need to be 
stripped
+    # in order to be an actual JSON.
+    json_responses = [
+        (
+            response_message_cls.to_json(response).strip('"')
+            if issubclass(response_message_cls, proto.Message)
+            else MessageToJson(response).strip('"')
+        )
+        for response in all_responses
+    ]
+    logging.info(f"Sending JSON stream: {json_responses}")
+    ret_val = "[{}]".format(",".join(json_responses))
+    return bytes(ret_val, "utf-8")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_api_core-2.19.2/tests/unit/test_rest_streaming.py 
new/google_api_core-2.20.0/tests/unit/test_rest_streaming.py
--- old/google_api_core-2.19.2/tests/unit/test_rest_streaming.py        
2024-08-27 22:57:23.000000000 +0200
+++ new/google_api_core-2.20.0/tests/unit/test_rest_streaming.py        
2024-09-19 20:20:48.000000000 +0200
@@ -26,48 +26,16 @@
 from google.api_core import rest_streaming
 from google.api import http_pb2
 from google.api import httpbody_pb2
-from google.protobuf import duration_pb2
-from google.protobuf import timestamp_pb2
-from google.protobuf.json_format import MessageToJson
+
+from ..helpers import Composer, Song, EchoResponse, parse_responses
 
 
 __protobuf__ = proto.module(package=__name__)
 SEED = int(time.time())
-logging.info(f"Starting rest streaming tests with random seed: {SEED}")
+logging.info(f"Starting sync rest streaming tests with random seed: {SEED}")
 random.seed(SEED)
 
 
-class Genre(proto.Enum):
-    GENRE_UNSPECIFIED = 0
-    CLASSICAL = 1
-    JAZZ = 2
-    ROCK = 3
-
-
-class Composer(proto.Message):
-    given_name = proto.Field(proto.STRING, number=1)
-    family_name = proto.Field(proto.STRING, number=2)
-    relateds = proto.RepeatedField(proto.STRING, number=3)
-    indices = proto.MapField(proto.STRING, proto.STRING, number=4)
-
-
-class Song(proto.Message):
-    composer = proto.Field(Composer, number=1)
-    title = proto.Field(proto.STRING, number=2)
-    lyrics = proto.Field(proto.STRING, number=3)
-    year = proto.Field(proto.INT32, number=4)
-    genre = proto.Field(Genre, number=5)
-    is_five_mins_longer = proto.Field(proto.BOOL, number=6)
-    score = proto.Field(proto.DOUBLE, number=7)
-    likes = proto.Field(proto.INT64, number=8)
-    duration = proto.Field(duration_pb2.Duration, number=9)
-    date_added = proto.Field(timestamp_pb2.Timestamp, number=10)
-
-
-class EchoResponse(proto.Message):
-    content = proto.Field(proto.STRING, number=1)
-
-
 class ResponseMock(requests.Response):
     class _ResponseItr:
         def __init__(self, _response_bytes: bytes, random_split=False):
@@ -97,27 +65,15 @@
         self._random_split = random_split
         self._response_message_cls = response_cls
 
-    def _parse_responses(self, responses: List[proto.Message]) -> bytes:
-        # json.dumps returns a string surrounded with quotes that need to be 
stripped
-        # in order to be an actual JSON.
-        json_responses = [
-            (
-                self._response_message_cls.to_json(r).strip('"')
-                if issubclass(self._response_message_cls, proto.Message)
-                else MessageToJson(r).strip('"')
-            )
-            for r in responses
-        ]
-        logging.info(f"Sending JSON stream: {json_responses}")
-        ret_val = "[{}]".format(",".join(json_responses))
-        return bytes(ret_val, "utf-8")
+    def _parse_responses(self):
+        return parse_responses(self._response_message_cls, self._responses)
 
     def close(self):
         raise NotImplementedError()
 
     def iter_content(self, *args, **kwargs):
         return self._ResponseItr(
-            self._parse_responses(self._responses),
+            self._parse_responses(),
             random_split=self._random_split,
         )
 
@@ -333,9 +289,8 @@
         pass
 
     resp = ResponseMock(responses=[], response_cls=SomeClass)
-    response_iterator = rest_streaming.ResponseIterator(resp, SomeClass)
     with pytest.raises(
         ValueError,
         match="Response message class must be a subclass of proto.Message or 
google.protobuf.message.Message",
     ):
-        response_iterator._grab()
+        rest_streaming.ResponseIterator(resp, SomeClass)

++++++ python-google-api-core-no-mock.patch ++++++
--- /var/tmp/diff_new_pack.Ybg4ZR/_old  2024-10-02 21:34:03.916079703 +0200
+++ /var/tmp/diff_new_pack.Ybg4ZR/_new  2024-10-02 21:34:03.920079869 +0200
@@ -1,102 +1,183 @@
-diff -Nru 
google-api-core-2.19.0.orig/tests/asyncio/future/test_async_future.py 
google-api-core-2.19.0/tests/asyncio/future/test_async_future.py
---- google-api-core-2.19.0.orig/tests/asyncio/future/test_async_future.py      
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/asyncio/future/test_async_future.py   
2024-05-16 16:03:34.320181259 +0200
-@@ -14,7 +14,7 @@
+From 5f28e210306de47ff5a9fa3b4bf48ac6ceb13e85 Mon Sep 17 00:00:00 2001
+From: Steve Kowalik <ste...@wedontsleep.org>
+Date: Wed, 2 Oct 2024 13:50:33 +1000
+Subject: [PATCH] test: Switch to unittest.mock from mock
+
+Now that the minimum supported version of Python is 3.7, we can stop
+using the external mock requirement, and import it from unittest. I have
+also attempted to keep imports ordered.
+
+Fixes #377
+---
+ noxfile.py                                                  | 2 --
+ tests/asyncio/future/test_async_future.py                   | 2 +-
+ tests/asyncio/gapic/test_method_async.py                    | 2 +-
+ tests/asyncio/operations_v1/test_operations_async_client.py | 3 ++-
+ tests/asyncio/retry/test_retry_streaming_async.py           | 4 ++--
+ tests/asyncio/retry/test_retry_unary_async.py               | 2 +-
+ tests/asyncio/test_grpc_helpers_async.py                    | 3 ++-
+ tests/asyncio/test_operation_async.py                       | 3 ++-
+ tests/asyncio/test_page_iterator_async.py                   | 2 +-
+ tests/asyncio/test_rest_streaming_async.py                  | 6 +++---
+ tests/unit/future/test__helpers.py                          | 2 +-
+ tests/unit/future/test_polling.py                           | 2 +-
+ tests/unit/gapic/test_method.py                             | 2 +-
+ tests/unit/operations_v1/test_operations_rest_client.py     | 2 +-
+ tests/unit/retry/test_retry_base.py                         | 2 +-
+ tests/unit/retry/test_retry_streaming.py                    | 2 +-
+ tests/unit/retry/test_retry_unary.py                        | 2 +-
+ tests/unit/test_bidi.py                                     | 2 +-
+ tests/unit/test_exceptions.py                               | 2 +-
+ tests/unit/test_extended_operation.py                       | 2 +-
+ tests/unit/test_grpc_helpers.py                             | 3 ++-
+ tests/unit/test_operation.py                                | 3 ++-
+ tests/unit/test_page_iterator.py                            | 2 +-
+ tests/unit/test_path_template.py                            | 2 +-
+ tests/unit/test_timeout.py                                  | 3 +--
+ 25 files changed, 32 insertions(+), 30 deletions(-)
+
+diff --git a/tests/asyncio/future/test_async_future.py 
b/tests/asyncio/future/test_async_future.py
+index 0cfe6773..659f41cf 100644
+--- a/tests/asyncio/future/test_async_future.py
++++ b/tests/asyncio/future/test_async_future.py
+@@ -13,8 +13,8 @@
+ # limitations under the License.
  
  import asyncio
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  from google.api_core import exceptions
-diff -Nru google-api-core-2.19.0.orig/tests/asyncio/gapic/test_method_async.py 
google-api-core-2.19.0/tests/asyncio/gapic/test_method_async.py
---- google-api-core-2.19.0.orig/tests/asyncio/gapic/test_method_async.py       
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/asyncio/gapic/test_method_async.py    
2024-05-16 16:03:34.310181235 +0200
-@@ -14,7 +14,7 @@
+diff --git a/tests/asyncio/gapic/test_method_async.py 
b/tests/asyncio/gapic/test_method_async.py
+index f64157b4..026993e2 100644
+--- a/tests/asyncio/gapic/test_method_async.py
++++ b/tests/asyncio/gapic/test_method_async.py
+@@ -13,8 +13,8 @@
+ # limitations under the License.
  
  import datetime
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  try:
-diff -Nru 
google-api-core-2.19.0.orig/tests/asyncio/operations_v1/test_operations_async_client.py
 
google-api-core-2.19.0/tests/asyncio/operations_v1/test_operations_async_client.py
---- 
google-api-core-2.19.0.orig/tests/asyncio/operations_v1/test_operations_async_client.py
    2024-04-30 19:00:19.000000000 +0200
-+++ 
google-api-core-2.19.0/tests/asyncio/operations_v1/test_operations_async_client.py
 2024-05-16 16:03:34.300181212 +0200
-@@ -12,7 +12,7 @@
+diff --git a/tests/asyncio/operations_v1/test_operations_async_client.py 
b/tests/asyncio/operations_v1/test_operations_async_client.py
+index 19ac9b56..e5b20dcd 100644
+--- a/tests/asyncio/operations_v1/test_operations_async_client.py
++++ b/tests/asyncio/operations_v1/test_operations_async_client.py
+@@ -12,7 +12,8 @@
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
 -import mock
 +from unittest import mock
++
  import pytest
  
  try:
-diff -Nru 
google-api-core-2.19.0.orig/tests/asyncio/retry/test_retry_streaming_async.py 
google-api-core-2.19.0/tests/asyncio/retry/test_retry_streaming_async.py
---- 
google-api-core-2.19.0.orig/tests/asyncio/retry/test_retry_streaming_async.py   
   2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/asyncio/retry/test_retry_streaming_async.py   
2024-05-16 16:03:34.296847871 +0200
-@@ -16,7 +16,7 @@
+diff --git a/tests/asyncio/retry/test_retry_streaming_async.py 
b/tests/asyncio/retry/test_retry_streaming_async.py
+index 28ae6ff1..a54fc125 100644
+--- a/tests/asyncio/retry/test_retry_streaming_async.py
++++ b/tests/asyncio/retry/test_retry_streaming_async.py
+@@ -12,11 +12,11 @@
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+ 
++import asyncio
+ import datetime
  import re
- import asyncio
+-import asyncio
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  from google.api_core import exceptions
-diff -Nru 
google-api-core-2.19.0.orig/tests/asyncio/retry/test_retry_unary_async.py 
google-api-core-2.19.0/tests/asyncio/retry/test_retry_unary_async.py
---- google-api-core-2.19.0.orig/tests/asyncio/retry/test_retry_unary_async.py  
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/asyncio/retry/test_retry_unary_async.py       
2024-05-16 16:03:34.293514530 +0200
-@@ -15,7 +15,7 @@
+diff --git a/tests/asyncio/retry/test_retry_unary_async.py 
b/tests/asyncio/retry/test_retry_unary_async.py
+index fc2f572b..032bab75 100644
+--- a/tests/asyncio/retry/test_retry_unary_async.py
++++ b/tests/asyncio/retry/test_retry_unary_async.py
+@@ -14,8 +14,8 @@
+ 
  import datetime
  import re
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  from google.api_core import exceptions
-diff -Nru google-api-core-2.19.0.orig/tests/asyncio/test_grpc_helpers_async.py 
google-api-core-2.19.0/tests/asyncio/test_grpc_helpers_async.py
---- google-api-core-2.19.0.orig/tests/asyncio/test_grpc_helpers_async.py       
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/asyncio/test_grpc_helpers_async.py    
2024-05-16 16:03:34.286847847 +0200
-@@ -12,7 +12,7 @@
+diff --git a/tests/asyncio/test_grpc_helpers_async.py 
b/tests/asyncio/test_grpc_helpers_async.py
+index 1a408ccd..a53de083 100644
+--- a/tests/asyncio/test_grpc_helpers_async.py
++++ b/tests/asyncio/test_grpc_helpers_async.py
+@@ -12,7 +12,8 @@
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
 -import mock
 +from unittest import mock
++
  import pytest  # noqa: I202
  
  try:
-diff -Nru google-api-core-2.19.0.orig/tests/asyncio/test_operation_async.py 
google-api-core-2.19.0/tests/asyncio/test_operation_async.py
---- google-api-core-2.19.0.orig/tests/asyncio/test_operation_async.py  
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/asyncio/test_operation_async.py       
2024-05-16 16:03:34.316847918 +0200
-@@ -13,7 +13,7 @@
+diff --git a/tests/asyncio/test_operation_async.py 
b/tests/asyncio/test_operation_async.py
+index 127ba634..f7ebad8a 100644
+--- a/tests/asyncio/test_operation_async.py
++++ b/tests/asyncio/test_operation_async.py
+@@ -13,7 +13,8 @@
  # limitations under the License.
  
  
 -import mock
 +from unittest import mock
++
  import pytest
  
  try:
-diff -Nru 
google-api-core-2.19.0.orig/tests/asyncio/test_page_iterator_async.py 
google-api-core-2.19.0/tests/asyncio/test_page_iterator_async.py
---- google-api-core-2.19.0.orig/tests/asyncio/test_page_iterator_async.py      
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/asyncio/test_page_iterator_async.py   
2024-05-16 16:03:34.283514506 +0200
-@@ -14,7 +14,7 @@
+diff --git a/tests/asyncio/test_page_iterator_async.py 
b/tests/asyncio/test_page_iterator_async.py
+index 75f9e1cf..e661bd26 100644
+--- a/tests/asyncio/test_page_iterator_async.py
++++ b/tests/asyncio/test_page_iterator_async.py
+@@ -13,8 +13,8 @@
+ # limitations under the License.
  
  import inspect
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  from google.api_core import page_iterator_async
-diff -Nru google-api-core-2.19.0.orig/tests/unit/future/test__helpers.py 
google-api-core-2.19.0/tests/unit/future/test__helpers.py
---- google-api-core-2.19.0.orig/tests/unit/future/test__helpers.py     
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/future/test__helpers.py  2024-05-16 
16:03:34.433514858 +0200
+diff --git a/tests/asyncio/test_rest_streaming_async.py 
b/tests/asyncio/test_rest_streaming_async.py
+index da5b1c8d..f726cbee 100644
+--- a/tests/asyncio/test_rest_streaming_async.py
++++ b/tests/asyncio/test_rest_streaming_async.py
+@@ -15,14 +15,14 @@
+ # TODO: set random.seed explicitly in each test function.
+ # See related issue: https://github.com/googleapis/python-api-core/issues/689.
+ 
+-import pytest  # noqa: I202
+-import mock
+-
+ import datetime
+ import logging
+ import random
+ import time
+ from typing import List, AsyncIterator
++from unittest import mock
++
++import pytest  # noqa: I202
+ 
+ import proto
+ 
+diff --git a/tests/unit/future/test__helpers.py 
b/tests/unit/future/test__helpers.py
+index 98afc599..a37efdd4 100644
+--- a/tests/unit/future/test__helpers.py
++++ b/tests/unit/future/test__helpers.py
 @@ -12,7 +12,7 @@
  # See the License for the specific language governing permissions and
  # limitations under the License.
@@ -106,169 +187,197 @@
  
  from google.api_core.future import _helpers
  
-diff -Nru google-api-core-2.19.0.orig/tests/unit/future/test_polling.py 
google-api-core-2.19.0/tests/unit/future/test_polling.py
---- google-api-core-2.19.0.orig/tests/unit/future/test_polling.py      
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/future/test_polling.py   2024-05-16 
16:03:34.433514858 +0200
-@@ -16,7 +16,7 @@
+diff --git a/tests/unit/future/test_polling.py 
b/tests/unit/future/test_polling.py
+index f5d9b4f1..2f66f230 100644
+--- a/tests/unit/future/test_polling.py
++++ b/tests/unit/future/test_polling.py
+@@ -15,8 +15,8 @@
+ import concurrent.futures
  import threading
  import time
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  from google.api_core import exceptions, retry
-diff -Nru google-api-core-2.19.0.orig/tests/unit/gapic/test_method.py 
google-api-core-2.19.0/tests/unit/gapic/test_method.py
---- google-api-core-2.19.0.orig/tests/unit/gapic/test_method.py        
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/gapic/test_method.py     2024-05-16 
16:03:34.413514811 +0200
-@@ -14,7 +14,7 @@
+diff --git a/tests/unit/gapic/test_method.py b/tests/unit/gapic/test_method.py
+index d966f478..87aa6390 100644
+--- a/tests/unit/gapic/test_method.py
++++ b/tests/unit/gapic/test_method.py
+@@ -13,8 +13,8 @@
+ # limitations under the License.
  
  import datetime
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  try:
-diff -Nru 
google-api-core-2.19.0.orig/tests/unit/operations_v1/test_operations_rest_client.py
 google-api-core-2.19.0/tests/unit/operations_v1/test_operations_rest_client.py
---- 
google-api-core-2.19.0.orig/tests/unit/operations_v1/test_operations_rest_client.py
        2024-04-30 19:00:19.000000000 +0200
-+++ 
google-api-core-2.19.0/tests/unit/operations_v1/test_operations_rest_client.py  
   2024-05-16 16:03:34.393514764 +0200
-@@ -15,7 +15,7 @@
+diff --git a/tests/unit/operations_v1/test_operations_rest_client.py 
b/tests/unit/operations_v1/test_operations_rest_client.py
+index 4ab4f1f7..26f34c40 100644
+--- a/tests/unit/operations_v1/test_operations_rest_client.py
++++ b/tests/unit/operations_v1/test_operations_rest_client.py
+@@ -14,8 +14,8 @@
+ # limitations under the License.
  #
  import os
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  try:
-diff -Nru google-api-core-2.19.0.orig/tests/unit/retry/test_retry_base.py 
google-api-core-2.19.0/tests/unit/retry/test_retry_base.py
---- google-api-core-2.19.0.orig/tests/unit/retry/test_retry_base.py    
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/retry/test_retry_base.py 2024-05-16 
16:03:34.380181399 +0200
-@@ -15,7 +15,7 @@
+diff --git a/tests/unit/retry/test_retry_base.py 
b/tests/unit/retry/test_retry_base.py
+index a0c6776b..212c4293 100644
+--- a/tests/unit/retry/test_retry_base.py
++++ b/tests/unit/retry/test_retry_base.py
+@@ -14,8 +14,8 @@
+ 
  import itertools
  import re
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  import requests.exceptions
  
-diff -Nru google-api-core-2.19.0.orig/tests/unit/retry/test_retry_streaming.py 
google-api-core-2.19.0/tests/unit/retry/test_retry_streaming.py
---- google-api-core-2.19.0.orig/tests/unit/retry/test_retry_streaming.py       
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/retry/test_retry_streaming.py    
2024-05-16 16:03:34.376848059 +0200
-@@ -14,7 +14,7 @@
+diff --git a/tests/unit/retry/test_retry_streaming.py 
b/tests/unit/retry/test_retry_streaming.py
+index 01f35327..82b60b05 100644
+--- a/tests/unit/retry/test_retry_streaming.py
++++ b/tests/unit/retry/test_retry_streaming.py
+@@ -13,8 +13,8 @@
+ # limitations under the License.
  
  import re
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  from google.api_core import exceptions
-diff -Nru google-api-core-2.19.0.orig/tests/unit/retry/test_retry_unary.py 
google-api-core-2.19.0/tests/unit/retry/test_retry_unary.py
---- google-api-core-2.19.0.orig/tests/unit/retry/test_retry_unary.py   
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/retry/test_retry_unary.py        
2024-05-16 16:03:34.386848082 +0200
-@@ -15,7 +15,7 @@
+diff --git a/tests/unit/retry/test_retry_unary.py 
b/tests/unit/retry/test_retry_unary.py
+index 7dcd8dd6..b018fa96 100644
+--- a/tests/unit/retry/test_retry_unary.py
++++ b/tests/unit/retry/test_retry_unary.py
+@@ -14,8 +14,8 @@
+ 
  import datetime
  import re
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  from google.api_core import exceptions
-diff -Nru google-api-core-2.19.0.orig/tests/unit/test_bidi.py 
google-api-core-2.19.0/tests/unit/test_bidi.py
---- google-api-core-2.19.0.orig/tests/unit/test_bidi.py        2024-04-30 
19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/test_bidi.py     2024-05-16 
16:03:34.326847941 +0200
-@@ -17,7 +17,7 @@
+diff --git a/tests/unit/test_bidi.py b/tests/unit/test_bidi.py
+index 84ac9dc5..08e80afd 100644
+--- a/tests/unit/test_bidi.py
++++ b/tests/unit/test_bidi.py
+@@ -16,8 +16,8 @@
+ import logging
  import queue
  import threading
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  try:
-diff -Nru google-api-core-2.19.0.orig/tests/unit/test_exceptions.py 
google-api-core-2.19.0/tests/unit/test_exceptions.py
---- google-api-core-2.19.0.orig/tests/unit/test_exceptions.py  2024-04-30 
19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/test_exceptions.py       2024-05-16 
16:03:34.403514788 +0200
-@@ -15,7 +15,7 @@
+diff --git a/tests/unit/test_exceptions.py b/tests/unit/test_exceptions.py
+index 07a36817..e3f8f909 100644
+--- a/tests/unit/test_exceptions.py
++++ b/tests/unit/test_exceptions.py
+@@ -14,8 +14,8 @@
+ 
  import http.client
  import json
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  import requests
  
-diff -Nru google-api-core-2.19.0.orig/tests/unit/test_extended_operation.py 
google-api-core-2.19.0/tests/unit/test_extended_operation.py
---- google-api-core-2.19.0.orig/tests/unit/test_extended_operation.py  
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/test_extended_operation.py       
2024-05-16 16:03:34.353514670 +0200
-@@ -16,7 +16,7 @@
+diff --git a/tests/unit/test_extended_operation.py 
b/tests/unit/test_extended_operation.py
+index 53af5204..ab550662 100644
+--- a/tests/unit/test_extended_operation.py
++++ b/tests/unit/test_extended_operation.py
+@@ -15,8 +15,8 @@
+ import dataclasses
  import enum
  import typing
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  from google.api_core import exceptions
-diff -Nru google-api-core-2.19.0.orig/tests/unit/test_grpc_helpers.py 
google-api-core-2.19.0/tests/unit/test_grpc_helpers.py
---- google-api-core-2.19.0.orig/tests/unit/test_grpc_helpers.py        
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/test_grpc_helpers.py     2024-05-16 
16:03:34.373514717 +0200
-@@ -12,7 +12,7 @@
+diff --git a/tests/unit/test_grpc_helpers.py b/tests/unit/test_grpc_helpers.py
+index 59442d43..8de9d8c0 100644
+--- a/tests/unit/test_grpc_helpers.py
++++ b/tests/unit/test_grpc_helpers.py
+@@ -12,7 +12,8 @@
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
 -import mock
 +from unittest import mock
++
  import pytest
  
  try:
-diff -Nru google-api-core-2.19.0.orig/tests/unit/test_operation.py 
google-api-core-2.19.0/tests/unit/test_operation.py
---- google-api-core-2.19.0.orig/tests/unit/test_operation.py   2024-04-30 
19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/test_operation.py        2024-05-16 
16:03:34.340181306 +0200
-@@ -13,7 +13,7 @@
+diff --git a/tests/unit/test_operation.py b/tests/unit/test_operation.py
+index f029866c..80680720 100644
+--- a/tests/unit/test_operation.py
++++ b/tests/unit/test_operation.py
+@@ -13,7 +13,8 @@
  # limitations under the License.
  
  
 -import mock
 +from unittest import mock
++
  import pytest
  
  try:
-diff -Nru google-api-core-2.19.0.orig/tests/unit/test_page_iterator.py 
google-api-core-2.19.0/tests/unit/test_page_iterator.py
---- google-api-core-2.19.0.orig/tests/unit/test_page_iterator.py       
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/test_page_iterator.py    2024-05-16 
16:03:34.333514624 +0200
-@@ -15,7 +15,7 @@
+diff --git a/tests/unit/test_page_iterator.py 
b/tests/unit/test_page_iterator.py
+index cf43aedf..560722c5 100644
+--- a/tests/unit/test_page_iterator.py
++++ b/tests/unit/test_page_iterator.py
+@@ -14,8 +14,8 @@
+ 
  import math
  import types
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  from google.api_core import page_iterator
-diff -Nru google-api-core-2.19.0.orig/tests/unit/test_path_template.py 
google-api-core-2.19.0/tests/unit/test_path_template.py
---- google-api-core-2.19.0.orig/tests/unit/test_path_template.py       
2024-04-30 19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/test_path_template.py    2024-05-16 
16:03:34.333514624 +0200
-@@ -14,7 +14,7 @@
+diff --git a/tests/unit/test_path_template.py 
b/tests/unit/test_path_template.py
+index 808b36f3..c34dd0f3 100644
+--- a/tests/unit/test_path_template.py
++++ b/tests/unit/test_path_template.py
+@@ -13,8 +13,8 @@
+ # limitations under the License.
  
  from __future__ import unicode_literals
++from unittest import mock
  
 -import mock
-+from unittest import mock
  import pytest
  
  from google.api import auth_pb2
-diff -Nru google-api-core-2.19.0.orig/tests/unit/test_timeout.py 
google-api-core-2.19.0/tests/unit/test_timeout.py
---- google-api-core-2.19.0.orig/tests/unit/test_timeout.py     2024-04-30 
19:00:19.000000000 +0200
-+++ google-api-core-2.19.0/tests/unit/test_timeout.py  2024-05-16 
16:03:34.426848175 +0200
-@@ -15,7 +15,7 @@
+diff --git a/tests/unit/test_timeout.py b/tests/unit/test_timeout.py
+index 0bcf07f0..60a2e65d 100644
+--- a/tests/unit/test_timeout.py
++++ b/tests/unit/test_timeout.py
+@@ -14,8 +14,7 @@
+ 
  import datetime
  import itertools
- 
+-
 -import mock
 +from unittest import mock
  

Reply via email to