Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-google-resumable-media for 
openSUSE:Factory checked in at 2024-01-04 16:00:10
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-google-resumable-media (Old)
 and      /work/SRC/openSUSE:Factory/.python-google-resumable-media.new.28375 
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-google-resumable-media"

Thu Jan  4 16:00:10 2024 rev:19 rq:1136785 version:2.7.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-google-resumable-media/python-google-resumable-media.changes
      2023-09-13 20:47:56.765311458 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-google-resumable-media.new.28375/python-google-resumable-media.changes
   2024-01-04 16:01:49.874236945 +0100
@@ -1,0 +2,11 @@
+Thu Jan  4 11:00:19 UTC 2024 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- Update to 2.7.0
+  * Add support for Python 3.12 (#407)
+  * Support brotli encoding (#403)
+- Skip online tests
+  * test_brotli
+  * test_constructor
+  * test_decompress
+
+-------------------------------------------------------------------

Old:
----
  google-resumable-media-2.6.0.tar.gz

New:
----
  google-resumable-media-2.7.0.tar.gz

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

Other differences:
------------------
++++++ python-google-resumable-media.spec ++++++
--- /var/tmp/diff_new_pack.kBLzm0/_old  2024-01-04 16:01:50.314253020 +0100
+++ /var/tmp/diff_new_pack.kBLzm0/_new  2024-01-04 16:01:50.314253020 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-google-resumable-media
 #
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-google-resumable-media
-Version:        2.6.0
+Version:        2.7.0
 Release:        0
 Summary:        Utilities for Google Media Downloads and Resumable Uploads
 License:        Apache-2.0
@@ -56,7 +56,11 @@
 
 %check
 export PYTEST_ADDOPTS="--import-mode=importlib"
-%pytest tests/unit
+# skip online tests
+donttest="test_brotli"
+donttest="$donttest or test_constructor"
+donttest="$donttest or test_decompress"
+%pytest tests/unit -k "not ($donttest)"
 
 %files %{python_files}
 %license LICENSE

++++++ google-resumable-media-2.6.0.tar.gz -> 
google-resumable-media-2.7.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-resumable-media-2.6.0/PKG-INFO 
new/google-resumable-media-2.7.0/PKG-INFO
--- old/google-resumable-media-2.6.0/PKG-INFO   2023-09-06 20:12:17.037366400 
+0200
+++ new/google-resumable-media-2.7.0/PKG-INFO   2023-12-12 20:03:28.395511000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: google-resumable-media
-Version: 2.6.0
+Version: 2.7.0
 Summary: Utilities for Google Media Downloads and Resumable Uploads
 Home-page: https://github.com/googleapis/google-resumable-media-python
 Author: Google Cloud Platform
@@ -16,11 +16,17 @@
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
 Classifier: Topic :: Internet
 Requires-Python: >= 3.7
+License-File: LICENSE
+Requires-Dist: google-crc32c<2.0dev,>=1.0
 Provides-Extra: requests
+Requires-Dist: requests<3.0.0dev,>=2.18.0; extra == "requests"
 Provides-Extra: aiohttp
-License-File: LICENSE
+Requires-Dist: aiohttp<4.0.0dev,>=3.6.2; extra == "aiohttp"
+Requires-Dist: google-auth<2.0dev,>=1.22.0; extra == "aiohttp"
 
 ``google-resumable-media``
 ==========================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-resumable-media-2.6.0/google/resumable_media/requests/download.py 
new/google-resumable-media-2.7.0/google/resumable_media/requests/download.py
--- 
old/google-resumable-media-2.6.0/google/resumable_media/requests/download.py    
    2023-09-06 20:09:24.000000000 +0200
+++ 
new/google-resumable-media-2.7.0/google/resumable_media/requests/download.py    
    2023-12-12 20:00:23.000000000 +0100
@@ -584,7 +584,7 @@
     This is so that we can intercept the compressed bytes before they are
     decoded.
 
-    Only patches if the content encoding is ``gzip``.
+    Only patches if the content encoding is ``gzip`` or ``br``.
 
     Args:
         response_raw (urllib3.response.HTTPResponse): The raw response for
@@ -598,12 +598,16 @@
         caller will no longer need to hash to decoded bytes.
     """
     encoding = response_raw.headers.get("content-encoding", "").lower()
-    if encoding != "gzip":
+    if encoding == "gzip":
+        response_raw._decoder = _GzipDecoder(checksum)
+        return _helpers._DoNothingHash()
+    # Only activate if brotli is installed
+    elif encoding == "br" and _BrotliDecoder:  # type: ignore
+        response_raw._decoder = _BrotliDecoder(checksum)
+        return _helpers._DoNothingHash()
+    else:
         return checksum
 
-    response_raw._decoder = _GzipDecoder(checksum)
-    return _helpers._DoNothingHash()
-
 
 class _GzipDecoder(urllib3.response.GzipDecoder):
     """Custom subclass of ``urllib3`` decoder for ``gzip``-ed bytes.
@@ -617,7 +621,7 @@
     """
 
     def __init__(self, checksum):
-        super(_GzipDecoder, self).__init__()
+        super().__init__()
         self._checksum = checksum
 
     def decompress(self, data):
@@ -630,4 +634,46 @@
             bytes: The decompressed bytes from ``data``.
         """
         self._checksum.update(data)
-        return super(_GzipDecoder, self).decompress(data)
+        return super().decompress(data)
+
+
+# urllib3.response.BrotliDecoder might not exist depending on whether brotli is
+# installed.
+if hasattr(urllib3.response, "BrotliDecoder"):
+
+    class _BrotliDecoder:
+        """Handler for ``brotli`` encoded bytes.
+
+        Allows a checksum function to see the compressed bytes before they are
+        decoded. This way the checksum of the compressed value can be computed.
+
+        Because BrotliDecoder's decompress method is dynamically created in
+        urllib3, a subclass is not practical. Instead, this class creates a
+        captive urllib3.requests.BrotliDecoder instance and acts as a proxy.
+
+        Args:
+            checksum (object):
+                A checksum which will be updated with compressed bytes.
+        """
+
+        def __init__(self, checksum):
+            self._decoder = urllib3.response.BrotliDecoder()
+            self._checksum = checksum
+
+        def decompress(self, data):
+            """Decompress the bytes.
+
+            Args:
+                data (bytes): The compressed bytes to be decompressed.
+
+            Returns:
+                bytes: The decompressed bytes from ``data``.
+            """
+            self._checksum.update(data)
+            return self._decoder.decompress(data)
+
+        def flush(self):
+            return self._decoder.flush()
+
+else:  # pragma: NO COVER
+    _BrotliDecoder = None  # type: ignore # pragma: NO COVER
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-resumable-media-2.6.0/google_resumable_media.egg-info/PKG-INFO 
new/google-resumable-media-2.7.0/google_resumable_media.egg-info/PKG-INFO
--- old/google-resumable-media-2.6.0/google_resumable_media.egg-info/PKG-INFO   
2023-09-06 20:12:16.000000000 +0200
+++ new/google-resumable-media-2.7.0/google_resumable_media.egg-info/PKG-INFO   
2023-12-12 20:03:28.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: google-resumable-media
-Version: 2.6.0
+Version: 2.7.0
 Summary: Utilities for Google Media Downloads and Resumable Uploads
 Home-page: https://github.com/googleapis/google-resumable-media-python
 Author: Google Cloud Platform
@@ -16,11 +16,17 @@
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
 Classifier: Topic :: Internet
 Requires-Python: >= 3.7
+License-File: LICENSE
+Requires-Dist: google-crc32c<2.0dev,>=1.0
 Provides-Extra: requests
+Requires-Dist: requests<3.0.0dev,>=2.18.0; extra == "requests"
 Provides-Extra: aiohttp
-License-File: LICENSE
+Requires-Dist: aiohttp<4.0.0dev,>=3.6.2; extra == "aiohttp"
+Requires-Dist: google-auth<2.0dev,>=1.22.0; extra == "aiohttp"
 
 ``google-resumable-media``
 ==========================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-resumable-media-2.6.0/google_resumable_media.egg-info/SOURCES.txt 
new/google-resumable-media-2.7.0/google_resumable_media.egg-info/SOURCES.txt
--- 
old/google-resumable-media-2.6.0/google_resumable_media.egg-info/SOURCES.txt    
    2023-09-06 20:12:16.000000000 +0200
+++ 
new/google-resumable-media-2.7.0/google_resumable_media.egg-info/SOURCES.txt    
    2023-12-12 20:03:28.000000000 +0100
@@ -27,6 +27,8 @@
 google_resumable_media.egg-info/requires.txt
 google_resumable_media.egg-info/top_level.txt
 tests/__init__.py
+tests/data/brotli.txt
+tests/data/brotli.txt.br
 tests/data/favicon.ico
 tests/data/file.txt
 tests/data/gzipped.txt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-resumable-media-2.6.0/setup.py 
new/google-resumable-media-2.7.0/setup.py
--- old/google-resumable-media-2.6.0/setup.py   2023-09-06 20:09:24.000000000 
+0200
+++ new/google-resumable-media-2.7.0/setup.py   2023-12-12 20:00:23.000000000 
+0100
@@ -35,7 +35,7 @@
 
 setuptools.setup(
     name='google-resumable-media',
-    version = "2.6.0",
+    version = "2.7.0",
     description='Utilities for Google Media Downloads and Resumable Uploads',
     author='Google Cloud Platform',
     author_email='[email protected]',
@@ -62,6 +62,8 @@
         'Programming Language :: Python :: 3.8',
         'Programming Language :: Python :: 3.9',
         'Programming Language :: Python :: 3.10',
+        'Programming Language :: Python :: 3.11',
+        'Programming Language :: Python :: 3.12',
         'Topic :: Internet',
     ],
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-resumable-media-2.6.0/tests/data/brotli.txt 
new/google-resumable-media-2.7.0/tests/data/brotli.txt
--- old/google-resumable-media-2.6.0/tests/data/brotli.txt      1970-01-01 
01:00:00.000000000 +0100
+++ new/google-resumable-media-2.7.0/tests/data/brotli.txt      2023-12-12 
20:00:23.000000000 +0100
@@ -0,0 +1,64 @@
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
+abcdefghijklmnopqrstuvwxyz0123456789
Binary files old/google-resumable-media-2.6.0/tests/data/brotli.txt.br and 
new/google-resumable-media-2.7.0/tests/data/brotli.txt.br differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-resumable-media-2.6.0/tests/system/requests/test_download.py 
new/google-resumable-media-2.7.0/tests/system/requests/test_download.py
--- old/google-resumable-media-2.6.0/tests/system/requests/test_download.py     
2023-09-06 20:09:24.000000000 +0200
+++ new/google-resumable-media-2.7.0/tests/system/requests/test_download.py     
2023-12-12 20:00:23.000000000 +0100
@@ -121,6 +121,15 @@
         "slices": (),
         "metadata": {"contentEncoding": "gzip"},
     },
+    {
+        "path": get_path("brotli.txt.br"),
+        "uncompressed": get_path("brotli.txt"),
+        "content_type": PLAIN_TEXT,
+        "md5": "MffJw7pTSX/7CVWFFPgwQA==",
+        "crc32c": "GGK0OQ==",
+        "slices": (),
+        "metadata": {"contentEncoding": "br"},
+    },
 )
 
 
@@ -298,7 +307,7 @@
         self, add_files, authorized_transport
     ):
         # Retrieve the gzip compressed file
-        info = ALL_FILES[-1]
+        info = ALL_FILES[-2]
         actual_contents = self._get_contents(info)
         blob_name = get_blob_name(info)
 
@@ -313,6 +322,27 @@
         assert response.headers.get("X-Goog-Stored-Content-Length") is not None
         assert stream.getvalue() == actual_contents
         check_tombstoned(download, authorized_transport)
+
+    @pytest.mark.parametrize("checksum", ["md5", "crc32c"])
+    def test_download_brotli_w_stored_content_headers(
+        self, add_files, authorized_transport, checksum
+    ):
+        # Retrieve the br compressed file
+        info = ALL_FILES[-1]
+        actual_contents = self._get_contents(info)
+        blob_name = get_blob_name(info)
+
+        # Create the actual download object.
+        media_url = utils.DOWNLOAD_URL_TEMPLATE.format(blob_name=blob_name)
+        stream = io.BytesIO()
+        download = self._make_one(media_url, stream=stream, checksum=checksum)
+        # Consume the resource.
+        response = download.consume(authorized_transport)
+        assert response.status_code == http.client.OK
+        assert response.headers.get(_helpers._STORED_CONTENT_ENCODING_HEADER) 
== "br"
+        assert response.headers.get("X-Goog-Stored-Content-Length") is not None
+        assert stream.getvalue() == actual_contents
+        check_tombstoned(download, authorized_transport)
 
     def test_extra_headers(self, authorized_transport, secret_file):
         blob_name, data, headers = secret_file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-resumable-media-2.6.0/tests/unit/requests/test_download.py 
new/google-resumable-media-2.7.0/tests/unit/requests/test_download.py
--- old/google-resumable-media-2.6.0/tests/unit/requests/test_download.py       
2023-09-06 20:09:24.000000000 +0200
+++ new/google-resumable-media-2.7.0/tests/unit/requests/test_download.py       
2023-12-12 20:00:23.000000000 +0100
@@ -1110,6 +1110,18 @@
         assert isinstance(response_raw._decoder, download_mod._GzipDecoder)
         assert response_raw._decoder._checksum is mock.sentinel.md5_hash
 
+    def test_brotli(self):
+        headers = {"content-encoding": "br"}
+        response_raw = mock.Mock(headers=headers, spec=["headers", "_decoder"])
+        md5_hash = download_mod._add_decoder(response_raw, 
mock.sentinel.md5_hash)
+
+        assert md5_hash is not mock.sentinel.md5_hash
+        assert isinstance(md5_hash, _helpers._DoNothingHash)
+        assert isinstance(response_raw._decoder, download_mod._BrotliDecoder)
+        assert response_raw._decoder._checksum is mock.sentinel.md5_hash
+        # Go ahead and exercise the flush method, added only for completion
+        response_raw._decoder.flush()
+
 
 class Test_GzipDecoder(object):
     def test_constructor(self):
@@ -1124,6 +1136,22 @@
         result = decoder.decompress(data)
 
         assert result == b""
+        md5_hash.update.assert_called_once_with(data)
+
+
+class Test_BrotliDecoder(object):
+    def test_constructor(self):
+        decoder = download_mod._BrotliDecoder(mock.sentinel.md5_hash)
+        assert decoder._checksum is mock.sentinel.md5_hash
+
+    def test_decompress(self):
+        md5_hash = mock.Mock(spec=["update"])
+        decoder = download_mod._BrotliDecoder(md5_hash)
+
+        data = b"\xc1\xf8I\xc0/\x83\xf3\xfa"
+        result = decoder.decompress(data)
+
+        assert result == b""
         md5_hash.update.assert_called_once_with(data)
 
 

Reply via email to