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 2026-04-07 16:33:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-google-resumable-media (Old)
 and      /work/SRC/openSUSE:Factory/.python-google-resumable-media.new.21863 
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-google-resumable-media"

Tue Apr  7 16:33:28 2026 rev:26 rq:1344790 version:2.8.2

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-google-resumable-media/python-google-resumable-media.changes
      2025-11-24 14:17:11.441519167 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-google-resumable-media.new.21863/python-google-resumable-media.changes
   2026-04-07 16:49:02.356863531 +0200
@@ -1,0 +2,9 @@
+Mon Apr  6 20:32:52 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 2.8.2
+  * Drop support for Python 3.7 and 3.8 (#500)
+  * Minimum supported Python version is now 3.9
+  * Add max_length support to decompress methods (#499)
+  * Update checksumming for Gzip/Brotli decoders (#491)
+
+-------------------------------------------------------------------

Old:
----
  google_resumable_media-2.8.0.tar.gz

New:
----
  google_resumable_media-2.8.2.tar.gz

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

Other differences:
------------------
++++++ python-google-resumable-media.spec ++++++
--- /var/tmp/diff_new_pack.yM5ott/_old  2026-04-07 16:49:02.964888674 +0200
+++ /var/tmp/diff_new_pack.yM5ott/_new  2026-04-07 16:49:02.964888674 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-google-resumable-media
 #
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,18 +16,17 @@
 #
 
 
-%define skip_python2 1
 %{?sle15_python_module_pythons}
 Name:           python-google-resumable-media
-Version:        2.8.0
+Version:        2.8.2
 Release:        0
 Summary:        Utilities for Google Media Downloads and Resumable Uploads
 License:        Apache-2.0
 Group:          Development/Languages/Python
 URL:            https://github.com/googleapis/google-resumable-media-python
 Source:         
https://files.pythonhosted.org/packages/source/g/google_resumable_media/google_resumable_media-%{version}.tar.gz
-BuildRequires:  %{python_module google-auth}
-BuildRequires:  %{python_module google-crc32c}
+BuildRequires:  %{python_module google-auth >= 1.22.0}
+BuildRequires:  %{python_module google-crc32c >= 1.0.0}
 BuildRequires:  %{python_module pip}
 BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module requests >= 2.18.0}
@@ -35,8 +34,8 @@
 BuildRequires:  %{python_module wheel}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
-Requires:       python-google-crc32c
-Recommends:     python-aiohttp
+Requires:       python-google-crc32c >= 1.0.0
+Recommends:     python-aiohttp >= 3.6.2
 Recommends:     python-requests >= 2.18.0
 BuildArch:      noarch
 %if 0%{?sle_version} >= 150400

++++++ google_resumable_media-2.8.0.tar.gz -> 
google_resumable_media-2.8.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google_resumable_media-2.8.0/PKG-INFO 
new/google_resumable_media-2.8.2/PKG-INFO
--- old/google_resumable_media-2.8.0/PKG-INFO   2025-11-17 16:33:30.043297000 
+0100
+++ new/google_resumable_media-2.8.2/PKG-INFO   2026-03-31 01:19:18.028955700 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: google-resumable-media
-Version: 2.8.0
+Version: 2.8.2
 Summary: Utilities for Google Media Downloads and Resumable Uploads
 Home-page: https://github.com/googleapis/google-resumable-media-python
 Author: Google Cloud Platform
@@ -12,8 +12,6 @@
 Classifier: License :: OSI Approved :: Apache Software License
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
@@ -21,7 +19,7 @@
 Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: 3.14
 Classifier: Topic :: Internet
-Requires-Python: >= 3.7
+Requires-Python: >= 3.9
 License-File: LICENSE
 Requires-Dist: google-crc32c<2.0.0,>=1.0.0
 Provides-Extra: requests
@@ -60,18 +58,13 @@
 
 Supported Python Versions
 -------------------------
-Python >= 3.7
+Python >= 3.9
 
 Unsupported Python Versions
 ---------------------------
 
-Python == 2.7, Python == 3.5, Python == 3.6.
+Python <= 3.8
 
-The last version of this library compatible with Python 2.7 and 3.5 is
-`google-resumable-media==1.3.3`.
-
-The last version of this library compatible with Python 3.6 is
-`google-resumable-media==2.3.3`.
 
 License
 -------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google_resumable_media-2.8.0/README.rst 
new/google_resumable_media-2.8.2/README.rst
--- old/google_resumable_media-2.8.0/README.rst 2025-11-17 16:32:57.000000000 
+0100
+++ new/google_resumable_media-2.8.2/README.rst 2026-03-31 01:07:04.000000000 
+0200
@@ -16,18 +16,13 @@
 
 Supported Python Versions
 -------------------------
-Python >= 3.7
+Python >= 3.9
 
 Unsupported Python Versions
 ---------------------------
 
-Python == 2.7, Python == 3.5, Python == 3.6.
+Python <= 3.8
 
-The last version of this library compatible with Python 2.7 and 3.5 is
-`google-resumable-media==1.3.3`.
-
-The last version of this library compatible with Python 3.6 is
-`google-resumable-media==2.3.3`.
 
 License
 -------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/_async_resumable_media/__init__.py 
new/google_resumable_media-2.8.2/google/_async_resumable_media/__init__.py
--- old/google_resumable_media-2.8.0/google/_async_resumable_media/__init__.py  
2025-11-17 16:32:57.000000000 +0100
+++ new/google_resumable_media-2.8.2/google/_async_resumable_media/__init__.py  
2026-03-31 01:07:04.000000000 +0200
@@ -42,7 +42,6 @@
 .. _pip: https://pip.pypa.io/
 """
 
-
 from google.resumable_media.common import DataCorruption
 from google.resumable_media.common import InvalidResponse
 from google.resumable_media.common import PERMANENT_REDIRECT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/_async_resumable_media/_download.py 
new/google_resumable_media-2.8.2/google/_async_resumable_media/_download.py
--- old/google_resumable_media-2.8.0/google/_async_resumable_media/_download.py 
2025-11-17 16:32:57.000000000 +0100
+++ new/google_resumable_media-2.8.2/google/_async_resumable_media/_download.py 
2026-03-31 01:07:06.000000000 +0200
@@ -236,7 +236,7 @@
     def __init__(self, media_url, chunk_size, stream, start=0, end=None, 
headers=None):
         if start < 0:
             raise ValueError(
-                "On a chunked download the starting " "value cannot be 
negative."
+                "On a chunked download the starting value cannot be negative."
             )
         super(ChunkedDownload, self).__init__(
             media_url, stream=stream, start=start, end=end, headers=headers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/_async_resumable_media/_helpers.py 
new/google_resumable_media-2.8.2/google/_async_resumable_media/_helpers.py
--- old/google_resumable_media-2.8.0/google/_async_resumable_media/_helpers.py  
2025-11-17 16:32:57.000000000 +0100
+++ new/google_resumable_media-2.8.2/google/_async_resumable_media/_helpers.py  
2026-03-31 01:07:04.000000000 +0200
@@ -97,7 +97,7 @@
             "Request failed with status code",
             status_code,
             "Expected one of",
-            *status_codes
+            *status_codes,
         )
     return status_code
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/_async_resumable_media/requests/__init__.py
 
new/google_resumable_media-2.8.2/google/_async_resumable_media/requests/__init__.py
--- 
old/google_resumable_media-2.8.0/google/_async_resumable_media/requests/__init__.py
 2025-11-17 16:32:57.000000000 +0100
+++ 
new/google_resumable_media-2.8.2/google/_async_resumable_media/requests/__init__.py
 2026-03-31 01:07:05.000000000 +0200
@@ -662,6 +662,7 @@
    >>> json_response['name'] == blob_name
    True
 """
+
 from google._async_resumable_media.requests.download import ChunkedDownload
 from google._async_resumable_media.requests.download import Download
 from google._async_resumable_media.requests.upload import MultipartUpload
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/_async_resumable_media/requests/_request_helpers.py
 
new/google_resumable_media-2.8.2/google/_async_resumable_media/requests/_request_helpers.py
--- 
old/google_resumable_media-2.8.0/google/_async_resumable_media/requests/_request_helpers.py
 2025-11-17 16:32:57.000000000 +0100
+++ 
new/google_resumable_media-2.8.2/google/_async_resumable_media/requests/_request_helpers.py
 2026-03-31 01:07:06.000000000 +0200
@@ -17,7 +17,6 @@
 This utilities are explicitly catered to ``requests``-like transports.
 """
 
-
 import functools
 
 from google._async_resumable_media import _helpers
@@ -114,7 +113,7 @@
     data=None,
     headers=None,
     retry_strategy=_DEFAULT_RETRY_STRATEGY,
-    **transport_kwargs
+    **transport_kwargs,
 ):
     """Make an HTTP request.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/_async_resumable_media/requests/download.py
 
new/google_resumable_media-2.8.2/google/_async_resumable_media/requests/download.py
--- 
old/google_resumable_media-2.8.0/google/_async_resumable_media/requests/download.py
 2025-11-17 16:32:57.000000000 +0100
+++ 
new/google_resumable_media-2.8.2/google/_async_resumable_media/requests/download.py
 2026-03-31 01:07:03.000000000 +0200
@@ -311,7 +311,6 @@
     async def consume_next_chunk(
         self, transport, timeout=_request_helpers._DEFAULT_TIMEOUT
     ):
-
         """
         Consume the next chunk of the resource to be downloaded.
 
@@ -452,14 +451,19 @@
         super(_GzipDecoder, self).__init__()
         self._checksum = checksum
 
-    def decompress(self, data):
+    def decompress(self, data, max_length=-1):
         """Decompress the bytes.
 
         Args:
             data (bytes): The compressed bytes to be decompressed.
+            max_length (int): Maximum number of bytes to return. -1 for no
+                limit. Forwarded to the underlying decoder when supported.
 
         Returns:
             bytes: The decompressed bytes from ``data``.
         """
         self._checksum.update(data)
-        return super(_GzipDecoder, self).decompress(data)
+        try:
+            return super(_GzipDecoder, self).decompress(data, 
max_length=max_length)
+        except TypeError:
+            return super(_GzipDecoder, self).decompress(data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/_async_resumable_media/requests/upload.py
 
new/google_resumable_media-2.8.2/google/_async_resumable_media/requests/upload.py
--- 
old/google_resumable_media-2.8.0/google/_async_resumable_media/requests/upload.py
   2025-11-17 16:32:57.000000000 +0100
+++ 
new/google_resumable_media-2.8.2/google/_async_resumable_media/requests/upload.py
   2026-03-31 01:07:02.000000000 +0200
@@ -18,7 +18,6 @@
 uploads that contain both metadata and a small file as payload.
 """
 
-
 from google._async_resumable_media import _upload
 from google._async_resumable_media.requests import _request_helpers
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/resumable_media/__init__.py 
new/google_resumable_media-2.8.2/google/resumable_media/__init__.py
--- old/google_resumable_media-2.8.0/google/resumable_media/__init__.py 
2025-11-17 16:32:57.000000000 +0100
+++ new/google_resumable_media-2.8.2/google/resumable_media/__init__.py 
2026-03-31 01:07:04.000000000 +0200
@@ -42,7 +42,6 @@
 .. _pip: https://pip.pypa.io/
 """
 
-
 from google.resumable_media.common import DataCorruption
 from google.resumable_media.common import InvalidResponse
 from google.resumable_media.common import PERMANENT_REDIRECT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/resumable_media/_download.py 
new/google_resumable_media-2.8.2/google/resumable_media/_download.py
--- old/google_resumable_media-2.8.0/google/resumable_media/_download.py        
2025-11-17 16:32:57.000000000 +0100
+++ new/google_resumable_media-2.8.2/google/resumable_media/_download.py        
2026-03-31 01:07:02.000000000 +0200
@@ -14,7 +14,6 @@
 
 """Virtual bases classes for downloading media from Google APIs."""
 
-
 import http.client
 import re
 
@@ -243,7 +242,7 @@
     def __init__(self, media_url, chunk_size, stream, start=0, end=None, 
headers=None):
         if start < 0:
             raise ValueError(
-                "On a chunked download the starting " "value cannot be 
negative."
+                "On a chunked download the starting value cannot be negative."
             )
         super(ChunkedDownload, self).__init__(
             media_url, stream=stream, start=start, end=end, headers=headers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/resumable_media/_helpers.py 
new/google_resumable_media-2.8.2/google/resumable_media/_helpers.py
--- old/google_resumable_media-2.8.0/google/resumable_media/_helpers.py 
2025-11-17 16:32:57.000000000 +0100
+++ new/google_resumable_media-2.8.2/google/resumable_media/_helpers.py 
2026-03-31 01:07:03.000000000 +0200
@@ -110,7 +110,7 @@
             "Request failed with status code",
             status_code,
             "Expected one of",
-            *status_codes
+            *status_codes,
         )
     return status_code
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/resumable_media/_upload.py 
new/google_resumable_media-2.8.2/google/resumable_media/_upload.py
--- old/google_resumable_media-2.8.0/google/resumable_media/_upload.py  
2025-11-17 16:32:57.000000000 +0100
+++ new/google_resumable_media-2.8.2/google/resumable_media/_upload.py  
2026-03-31 01:07:03.000000000 +0200
@@ -53,8 +53,7 @@
     "{:d} bytes have already been updated (they should match)."
 )
 _STREAM_READ_PAST_TEMPLATE = (
-    "{:d} bytes have been read from the stream, which exceeds "
-    "the expected total {:d}."
+    "{:d} bytes have been read from the stream, which exceeds the expected 
total {:d}."
 )
 _DELETE = "DELETE"
 _POST = "POST"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/resumable_media/common.py 
new/google_resumable_media-2.8.2/google/resumable_media/common.py
--- old/google_resumable_media-2.8.0/google/resumable_media/common.py   
2025-11-17 16:32:57.000000000 +0100
+++ new/google_resumable_media-2.8.2/google/resumable_media/common.py   
2026-03-31 01:07:03.000000000 +0200
@@ -20,7 +20,7 @@
 import http.client
 
 _SLEEP_RETRY_ERROR_MSG = (
-    "At most one of `max_cumulative_retry` and `max_retries` " "can be 
specified."
+    "At most one of `max_cumulative_retry` and `max_retries` can be specified."
 )
 
 UPLOAD_CHUNK_SIZE = 262144  # 256 * 1024
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/resumable_media/requests/__init__.py 
new/google_resumable_media-2.8.2/google/resumable_media/requests/__init__.py
--- 
old/google_resumable_media-2.8.0/google/resumable_media/requests/__init__.py    
    2025-11-17 16:32:57.000000000 +0100
+++ 
new/google_resumable_media-2.8.2/google/resumable_media/requests/__init__.py    
    2026-03-31 01:07:04.000000000 +0200
@@ -662,6 +662,7 @@
    >>> json_response['name'] == blob_name
    True
 """
+
 from google.resumable_media.requests.download import ChunkedDownload
 from google.resumable_media.requests.download import Download
 from google.resumable_media.requests.upload import MultipartUpload
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/resumable_media/requests/download.py 
new/google_resumable_media-2.8.2/google/resumable_media/requests/download.py
--- 
old/google_resumable_media-2.8.0/google/resumable_media/requests/download.py    
    2025-11-17 16:32:57.000000000 +0100
+++ 
new/google_resumable_media-2.8.2/google/resumable_media/requests/download.py    
    2026-03-31 01:07:02.000000000 +0200
@@ -667,17 +667,22 @@
         super().__init__()
         self._checksum = checksum
 
-    def decompress(self, data):
+    def decompress(self, data, max_length=-1):
         """Decompress the bytes.
 
         Args:
             data (bytes): The compressed bytes to be decompressed.
+            max_length (int): Maximum number of bytes to return. -1 for no
+                limit. Forwarded to the underlying decoder when supported.
 
         Returns:
             bytes: The decompressed bytes from ``data``.
         """
         self._checksum.update(data)
-        return super().decompress(data)
+        try:
+            return super().decompress(data, max_length=max_length)
+        except TypeError:
+            return super().decompress(data)
 
 
 # urllib3.response.BrotliDecoder might not exist depending on whether brotli is
@@ -703,17 +708,29 @@
             self._decoder = urllib3.response.BrotliDecoder()
             self._checksum = checksum
 
-        def decompress(self, data):
+        def decompress(self, data, max_length=-1):
             """Decompress the bytes.
 
             Args:
                 data (bytes): The compressed bytes to be decompressed.
+                max_length (int): Maximum number of bytes to return. -1 for no
+                    limit. Forwarded to the underlying decoder when supported.
 
             Returns:
                 bytes: The decompressed bytes from ``data``.
             """
             self._checksum.update(data)
-            return self._decoder.decompress(data)
+            try:
+                return self._decoder.decompress(data, max_length=max_length)
+            except TypeError:
+                return self._decoder.decompress(data)
+
+        @property
+        def has_unconsumed_tail(self):
+            try:
+                return self._decoder.has_unconsumed_tail
+            except AttributeError:
+                return False
 
         def flush(self):
             return self._decoder.flush()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google/resumable_media/requests/upload.py 
new/google_resumable_media-2.8.2/google/resumable_media/requests/upload.py
--- old/google_resumable_media-2.8.0/google/resumable_media/requests/upload.py  
2025-11-17 16:32:57.000000000 +0100
+++ new/google_resumable_media-2.8.2/google/resumable_media/requests/upload.py  
2026-03-31 01:07:03.000000000 +0200
@@ -18,7 +18,6 @@
 uploads that contain both metadata and a small file as payload.
 """
 
-
 from google.resumable_media import _upload
 from google.resumable_media.requests import _request_helpers
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/google_resumable_media.egg-info/PKG-INFO 
new/google_resumable_media-2.8.2/google_resumable_media.egg-info/PKG-INFO
--- old/google_resumable_media-2.8.0/google_resumable_media.egg-info/PKG-INFO   
2025-11-17 16:33:30.000000000 +0100
+++ new/google_resumable_media-2.8.2/google_resumable_media.egg-info/PKG-INFO   
2026-03-31 01:19:18.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: google-resumable-media
-Version: 2.8.0
+Version: 2.8.2
 Summary: Utilities for Google Media Downloads and Resumable Uploads
 Home-page: https://github.com/googleapis/google-resumable-media-python
 Author: Google Cloud Platform
@@ -12,8 +12,6 @@
 Classifier: License :: OSI Approved :: Apache Software License
 Classifier: Operating System :: OS Independent
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
@@ -21,7 +19,7 @@
 Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: 3.14
 Classifier: Topic :: Internet
-Requires-Python: >= 3.7
+Requires-Python: >= 3.9
 License-File: LICENSE
 Requires-Dist: google-crc32c<2.0.0,>=1.0.0
 Provides-Extra: requests
@@ -60,18 +58,13 @@
 
 Supported Python Versions
 -------------------------
-Python >= 3.7
+Python >= 3.9
 
 Unsupported Python Versions
 ---------------------------
 
-Python == 2.7, Python == 3.5, Python == 3.6.
+Python <= 3.8
 
-The last version of this library compatible with Python 2.7 and 3.5 is
-`google-resumable-media==1.3.3`.
-
-The last version of this library compatible with Python 3.6 is
-`google-resumable-media==2.3.3`.
 
 License
 -------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google_resumable_media-2.8.0/setup.py 
new/google_resumable_media-2.8.2/setup.py
--- old/google_resumable_media-2.8.0/setup.py   2025-11-17 16:32:57.000000000 
+0100
+++ new/google_resumable_media-2.8.2/setup.py   2026-03-31 01:07:06.000000000 
+0200
@@ -35,7 +35,7 @@
 
 setuptools.setup(
     name='google-resumable-media',
-    version = "2.8.0",
+    version = "2.8.2",
     description='Utilities for Google Media Downloads and Resumable Uploads',
     author='Google Cloud Platform',
     author_email='[email protected]',
@@ -51,15 +51,13 @@
     zip_safe=False,
     install_requires=REQUIREMENTS,
     extras_require=EXTRAS_REQUIRE,
-    python_requires='>= 3.7',
+    python_requires='>= 3.9',
     classifiers=[
         'Development Status :: 5 - Production/Stable',
         'Intended Audience :: Developers',
         'License :: OSI Approved :: Apache Software License',
         'Operating System :: OS Independent',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.7',
-        'Programming Language :: Python :: 3.8',
         'Programming Language :: Python :: 3.9',
         'Programming Language :: Python :: 3.10',
         'Programming Language :: Python :: 3.11',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/tests/unit/requests/test_download.py 
new/google_resumable_media-2.8.2/tests/unit/requests/test_download.py
--- old/google_resumable_media-2.8.0/tests/unit/requests/test_download.py       
2025-11-17 16:32:57.000000000 +0100
+++ new/google_resumable_media-2.8.2/tests/unit/requests/test_download.py       
2026-03-31 01:07:04.000000000 +0200
@@ -1274,6 +1274,37 @@
         assert result == b""
         md5_hash.update.assert_called_once_with(data)
 
+    def test_decompress_with_max_length(self):
+        md5_hash = mock.Mock(spec=["update"])
+        decoder = download_mod._GzipDecoder(md5_hash)
+
+        with mock.patch.object(
+            type(decoder).__bases__[0], "decompress"
+        ) as mock_super_decompress:
+            mock_super_decompress.return_value = b"decompressed"
+            data = b"\x1f\x8b\x08\x08"
+            result = decoder.decompress(data, max_length=10)
+
+            assert result == b"decompressed"
+            md5_hash.update.assert_called_once_with(data)
+            mock_super_decompress.assert_called_once_with(data, max_length=10)
+
+    def test_decompress_with_max_length_fallback(self):
+        md5_hash = mock.Mock(spec=["update"])
+        decoder = download_mod._GzipDecoder(md5_hash)
+
+        with mock.patch.object(
+            type(decoder).__bases__[0],
+            "decompress",
+            side_effect=[TypeError, b"decompressed"],
+        ) as mock_super_decompress:
+            data = b"\x1f\x8b\x08\x08"
+            result = decoder.decompress(data, max_length=10)
+
+            assert result == b"decompressed"
+            md5_hash.update.assert_called_once_with(data)
+            assert mock_super_decompress.call_count == 2
+
 
 class Test_BrotliDecoder(object):
     def test_constructor(self):
@@ -1290,6 +1321,45 @@
         assert result == b""
         md5_hash.update.assert_called_once_with(data)
 
+    def test_decompress_with_max_length(self):
+        md5_hash = mock.Mock(spec=["update"])
+        decoder = download_mod._BrotliDecoder(md5_hash)
+
+        decoder._decoder = mock.Mock(spec=["decompress"])
+        decoder._decoder.decompress.return_value = b"decompressed"
+
+        data = b"compressed"
+        result = decoder.decompress(data, max_length=10)
+
+        assert result == b"decompressed"
+        md5_hash.update.assert_called_once_with(data)
+        decoder._decoder.decompress.assert_called_once_with(data, 
max_length=10)
+
+    def test_decompress_with_max_length_fallback(self):
+        md5_hash = mock.Mock(spec=["update"])
+        decoder = download_mod._BrotliDecoder(md5_hash)
+
+        decoder._decoder = mock.Mock(spec=["decompress"])
+        decoder._decoder.decompress.side_effect = [TypeError, b"decompressed"]
+
+        data = b"compressed"
+        result = decoder.decompress(data, max_length=10)
+
+        assert result == b"decompressed"
+        md5_hash.update.assert_called_once_with(data)
+        assert decoder._decoder.decompress.call_count == 2
+
+    def test_has_unconsumed_tail(self):
+        decoder = download_mod._BrotliDecoder(mock.sentinel.md5_hash)
+        decoder._decoder = mock.Mock(spec=["has_unconsumed_tail"])
+        decoder._decoder.has_unconsumed_tail = True
+        assert decoder.has_unconsumed_tail is True
+
+    def test_has_unconsumed_tail_fallback(self):
+        decoder = download_mod._BrotliDecoder(mock.sentinel.md5_hash)
+        decoder._decoder = mock.Mock(spec=[])
+        assert decoder.has_unconsumed_tail is False
+
 
 def _mock_response(status_code=http.client.OK, chunks=(), headers=None):
     if headers is None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/tests/unit/test__helpers.py 
new/google_resumable_media-2.8.2/tests/unit/test__helpers.py
--- old/google_resumable_media-2.8.0/tests/unit/test__helpers.py        
2025-11-17 16:32:57.000000000 +0100
+++ new/google_resumable_media-2.8.2/tests/unit/test__helpers.py        
2026-03-31 01:07:03.000000000 +0200
@@ -337,7 +337,6 @@
 
 
 class Test__parse_checksum_header(object):
-
     CRC32C_CHECKSUM = "3q2+7w=="
     MD5_CHECKSUM = "c2l4dGVlbmJ5dGVzbG9uZw=="
 
@@ -409,7 +408,6 @@
 
 
 class Test__parse_generation_header(object):
-
     GENERATION_VALUE = 1641590104888641
 
     def test_empty_value(self):
@@ -451,7 +449,6 @@
 
 
 class Test__get_generation_from_url(object):
-
     GENERATION_VALUE = 1641590104888641
     MEDIA_URL = (
         
"https://storage.googleapis.com/storage/v1/b/my-bucket/o/my-object?alt=media";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_resumable_media-2.8.0/tests/unit/test__upload.py 
new/google_resumable_media-2.8.2/tests/unit/test__upload.py
--- old/google_resumable_media-2.8.0/tests/unit/test__upload.py 2025-11-17 
16:32:57.000000000 +0100
+++ new/google_resumable_media-2.8.2/tests/unit/test__upload.py 2026-03-31 
01:07:04.000000000 +0200
@@ -259,13 +259,7 @@
             ).encode("utf8")
         else:
             metadata_payload = b'{"Some": "Stuff"}\r\n'
-        remainder = (
-            b"--==3==\r\n"
-            b"content-type: text/plain\r\n"
-            b"\r\n"
-            b"Hi\r\n"
-            b"--==3==--"
-        )
+        remainder = b"--==3==\r\ncontent-type: 
text/plain\r\n\r\nHi\r\n--==3==--"
         expected_payload = preamble + metadata_payload + remainder
 
         assert payload == expected_payload
@@ -1127,7 +1121,7 @@
 
     @mock.patch("google.resumable_media._upload.get_boundary", 
return_value=b"==2==")
     def test_unicode(self, mock_get_boundary):
-        data_unicode = "\N{snowman}"
+        data_unicode = "\N{SNOWMAN}"
         # construct_multipart_request( ASSUMES callers pass bytes.
         data = data_unicode.encode("utf-8")
         metadata = {"name": "snowman.txt"}

Reply via email to