[Git][debian-gis-team/remotezip][upstream] New upstream version 0.12.6

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Sun Aug 30 08:14:33 BST 2026



Antonio Valentino pushed to branch upstream at Debian GIS Project / remotezip


Commits:
c4c83be2 by Antonio Valentino at 2026-08-30T06:58:51+00:00
New upstream version 0.12.6
- - - - -


9 changed files:

- PKG-INFO
- README.md
- + pyproject.toml
- remotezip.egg-info/PKG-INFO
- remotezip.egg-info/SOURCES.txt
- remotezip.egg-info/entry_points.txt
- remotezip.egg-info/requires.txt
- remotezip.py
- − setup.py


Changes:

=====================================
PKG-INFO
=====================================
@@ -1,15 +1,12 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
 Name: remotezip
-Version: 0.12.3
+Version: 0.12.6
 Summary: Access zip file content hosted remotely without downloading the full file.
-Home-page: https://github.com/gtsystem/python-remotezip
-Author: Giuseppe Tribulato
-Author-email: gtsystem at gmail.com
+Author-email: Giuseppe Tribulato <gtsystem at gmail.com>
 License: MIT
-Platform: UNKNOWN
+Project-URL: Homepage, https://github.com/gtsystem/python-remotezip
 Classifier: Intended Audience :: Developers
 Classifier: Development Status :: 5 - Production/Stable
-Classifier: License :: OSI Approved :: MIT License
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
@@ -21,9 +18,15 @@ 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
+Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3.14
+Requires-Python: >=2.7
 Description-Content-Type: text/markdown
-Provides-Extra: test
 License-File: LICENSE
+Requires-Dist: requests
+Dynamic: license-file
 
 # remotezip
 
@@ -43,13 +46,13 @@ This module provides a way to access single members of a zip file archive withou
 
 To download the content, this library rely on the `requests` module. The constructor interface matches the function `requests.get` module.
 
-* **url**: Url where the zip file is located *(required)*.
+* **url**: URL where the zip file is located *(required)*.
 * **auth**: authentication credentials.
 * **headers**: headers to pass to the request.
 * **timeout**: timeout for the request.
 * **verify**: enable/disable certificate verification or set custom certificates location.
-* ... Please look at the [requests](http://docs.python-requests.org/en/master/user/quickstart/#make-a-request) documentation for futher usage details.
-* **initial\_buffer\_size**: How much data (in bytes) to fetch during the first connection to download the zip file central directory. If your zip file conteins a lot of files, would be a good idea to increase this parameter in order to avoid the need for further remote requests. *Default: 64kb*.
+* ... Please look at the [requests](http://docs.python-requests.org/en/master/user/quickstart/#make-a-request) documentation for further usage details.
+* **initial\_buffer\_size**: How much data (in bytes) to fetch during the first connection to download the zip file central directory. If your zip file contains a lot of files, would be a good idea to increase this parameter in order to avoid the need for further remote requests. *Default: 64kb*.
 * **session**: a custom session object to use for the request.
 * **support_suffix_range**: You can set this attribute to `False` if the remote server doesn't support suffix range
   (negative offset). Notice that this option will use one more HEAD request to fetch the content length.
@@ -95,7 +98,7 @@ with RemoteZip('http://.../myfile.zip') as zip:
 
 
 #### Download a member
-The following example will extract the file `somefile.txt` from the archive stored at the url `http://.../myfile.zip`.
+The following example will extract the file `somefile.txt` from the archive stored at the URL `http://.../myfile.zip`.
 
 ```python
 from remotezip import RemoteZip
@@ -134,7 +137,7 @@ usage: remotezip [-h] [-l] [-d DIR] url [filename [filename ...]]
 Unzip remote files
 
 positional arguments:
-  url                Url of the zip archive
+  url                URL of the zip archive
   filename           File to extract
 
 optional arguments:
@@ -172,8 +175,6 @@ How many requests will this module perform to download a member?
 * If the central directory is bigger than **initial\_buffer\_size**, a third request will be required.
 * If negative seek operations are used in `ZipExtFile`, each of them will result in a new request.
 
-## Alternative modules
+## Alternative module
 
 There is a similar module available for python [pyremotezip](https://github.com/fcvarela/pyremotezip).
-
-


=====================================
README.md
=====================================
@@ -16,13 +16,13 @@ This module provides a way to access single members of a zip file archive withou
 
 To download the content, this library rely on the `requests` module. The constructor interface matches the function `requests.get` module.
 
-* **url**: Url where the zip file is located *(required)*.
+* **url**: URL where the zip file is located *(required)*.
 * **auth**: authentication credentials.
 * **headers**: headers to pass to the request.
 * **timeout**: timeout for the request.
 * **verify**: enable/disable certificate verification or set custom certificates location.
-* ... Please look at the [requests](http://docs.python-requests.org/en/master/user/quickstart/#make-a-request) documentation for futher usage details.
-* **initial\_buffer\_size**: How much data (in bytes) to fetch during the first connection to download the zip file central directory. If your zip file conteins a lot of files, would be a good idea to increase this parameter in order to avoid the need for further remote requests. *Default: 64kb*.
+* ... Please look at the [requests](http://docs.python-requests.org/en/master/user/quickstart/#make-a-request) documentation for further usage details.
+* **initial\_buffer\_size**: How much data (in bytes) to fetch during the first connection to download the zip file central directory. If your zip file contains a lot of files, would be a good idea to increase this parameter in order to avoid the need for further remote requests. *Default: 64kb*.
 * **session**: a custom session object to use for the request.
 * **support_suffix_range**: You can set this attribute to `False` if the remote server doesn't support suffix range
   (negative offset). Notice that this option will use one more HEAD request to fetch the content length.
@@ -68,7 +68,7 @@ with RemoteZip('http://.../myfile.zip') as zip:
 
 
 #### Download a member
-The following example will extract the file `somefile.txt` from the archive stored at the url `http://.../myfile.zip`.
+The following example will extract the file `somefile.txt` from the archive stored at the URL `http://.../myfile.zip`.
 
 ```python
 from remotezip import RemoteZip
@@ -107,7 +107,7 @@ usage: remotezip [-h] [-l] [-d DIR] url [filename [filename ...]]
 Unzip remote files
 
 positional arguments:
-  url                Url of the zip archive
+  url                URL of the zip archive
   filename           File to extract
 
 optional arguments:
@@ -145,6 +145,6 @@ How many requests will this module perform to download a member?
 * If the central directory is bigger than **initial\_buffer\_size**, a third request will be required.
 * If negative seek operations are used in `ZipExtFile`, each of them will result in a new request.
 
-## Alternative modules
+## Alternative module
 
 There is a similar module available for python [pyremotezip](https://github.com/fcvarela/pyremotezip).


=====================================
pyproject.toml
=====================================
@@ -0,0 +1,48 @@
+[build-system]
+requires = ["setuptools>=61.0"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "remotezip"
+version = "0.12.6"
+description = "Access zip file content hosted remotely without downloading the full file."
+readme = "README.md"
+requires-python = ">=2.7"
+authors = [
+    {name = "Giuseppe Tribulato", email = "gtsystem at gmail.com"},
+]
+license = {text = "MIT"}
+dependencies = [
+    "requests",
+]
+classifiers = [
+    "Intended Audience :: Developers",
+    "Development Status :: 5 - Production/Stable",
+    "Programming Language :: Python",
+    "Programming Language :: Python :: 2.7",
+    "Programming Language :: Python :: 3",
+    "Programming Language :: Python :: 3.3",
+    "Programming Language :: Python :: 3.4",
+    "Programming Language :: Python :: 3.5",
+    "Programming Language :: Python :: 3.6",
+    "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",
+    "Programming Language :: Python :: 3.12",
+    "Programming Language :: Python :: 3.13",
+    "Programming Language :: Python :: 3.14",
+]
+
+[dependency-groups]
+test = ["requests-mock"]
+
+[project.urls]
+Homepage = "https://github.com/gtsystem/python-remotezip"
+
+[project.scripts]
+remotezip = "remotezip:main"
+
+[tool.setuptools]
+py-modules = ["remotezip"]


=====================================
remotezip.egg-info/PKG-INFO
=====================================
@@ -1,15 +1,12 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
 Name: remotezip
-Version: 0.12.3
+Version: 0.12.6
 Summary: Access zip file content hosted remotely without downloading the full file.
-Home-page: https://github.com/gtsystem/python-remotezip
-Author: Giuseppe Tribulato
-Author-email: gtsystem at gmail.com
+Author-email: Giuseppe Tribulato <gtsystem at gmail.com>
 License: MIT
-Platform: UNKNOWN
+Project-URL: Homepage, https://github.com/gtsystem/python-remotezip
 Classifier: Intended Audience :: Developers
 Classifier: Development Status :: 5 - Production/Stable
-Classifier: License :: OSI Approved :: MIT License
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
@@ -21,9 +18,15 @@ 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
+Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3.14
+Requires-Python: >=2.7
 Description-Content-Type: text/markdown
-Provides-Extra: test
 License-File: LICENSE
+Requires-Dist: requests
+Dynamic: license-file
 
 # remotezip
 
@@ -43,13 +46,13 @@ This module provides a way to access single members of a zip file archive withou
 
 To download the content, this library rely on the `requests` module. The constructor interface matches the function `requests.get` module.
 
-* **url**: Url where the zip file is located *(required)*.
+* **url**: URL where the zip file is located *(required)*.
 * **auth**: authentication credentials.
 * **headers**: headers to pass to the request.
 * **timeout**: timeout for the request.
 * **verify**: enable/disable certificate verification or set custom certificates location.
-* ... Please look at the [requests](http://docs.python-requests.org/en/master/user/quickstart/#make-a-request) documentation for futher usage details.
-* **initial\_buffer\_size**: How much data (in bytes) to fetch during the first connection to download the zip file central directory. If your zip file conteins a lot of files, would be a good idea to increase this parameter in order to avoid the need for further remote requests. *Default: 64kb*.
+* ... Please look at the [requests](http://docs.python-requests.org/en/master/user/quickstart/#make-a-request) documentation for further usage details.
+* **initial\_buffer\_size**: How much data (in bytes) to fetch during the first connection to download the zip file central directory. If your zip file contains a lot of files, would be a good idea to increase this parameter in order to avoid the need for further remote requests. *Default: 64kb*.
 * **session**: a custom session object to use for the request.
 * **support_suffix_range**: You can set this attribute to `False` if the remote server doesn't support suffix range
   (negative offset). Notice that this option will use one more HEAD request to fetch the content length.
@@ -95,7 +98,7 @@ with RemoteZip('http://.../myfile.zip') as zip:
 
 
 #### Download a member
-The following example will extract the file `somefile.txt` from the archive stored at the url `http://.../myfile.zip`.
+The following example will extract the file `somefile.txt` from the archive stored at the URL `http://.../myfile.zip`.
 
 ```python
 from remotezip import RemoteZip
@@ -134,7 +137,7 @@ usage: remotezip [-h] [-l] [-d DIR] url [filename [filename ...]]
 Unzip remote files
 
 positional arguments:
-  url                Url of the zip archive
+  url                URL of the zip archive
   filename           File to extract
 
 optional arguments:
@@ -172,8 +175,6 @@ How many requests will this module perform to download a member?
 * If the central directory is bigger than **initial\_buffer\_size**, a third request will be required.
 * If negative seek operations are used in `ZipExtFile`, each of them will result in a new request.
 
-## Alternative modules
+## Alternative module
 
 There is a similar module available for python [pyremotezip](https://github.com/fcvarela/pyremotezip).
-
-


=====================================
remotezip.egg-info/SOURCES.txt
=====================================
@@ -1,7 +1,7 @@
 LICENSE
 README.md
+pyproject.toml
 remotezip.py
-setup.py
 remotezip.egg-info/PKG-INFO
 remotezip.egg-info/SOURCES.txt
 remotezip.egg-info/dependency_links.txt


=====================================
remotezip.egg-info/entry_points.txt
=====================================
@@ -1,3 +1,2 @@
 [console_scripts]
 remotezip = remotezip:main
-


=====================================
remotezip.egg-info/requires.txt
=====================================
@@ -1,4 +1 @@
 requests
-
-[test]
-requests_mock


=====================================
remotezip.py
=====================================
@@ -1,7 +1,6 @@
 #!/usr/bin/env python
 import io
 import zipfile
-from datetime import datetime
 from itertools import tee
 
 import requests
@@ -31,8 +30,45 @@ class PartialBuffer:
         however, any attempt to read data outside the partial data is going to fail
         with OutOfBound error.
     """
+    @staticmethod
+    def _read_up_to(buffer, size):
+        """Read at most `size` bytes into a new buffer.
+
+        A single read() is not enough: a socket-backed response can return
+        fewer bytes than requested while more are still coming. Data is written
+        straight into the result so that no intermediate copy of the whole
+        range is held.
+        """
+        result = io.BytesIO()
+        remaining = size
+        while remaining > 0:
+            chunk = buffer.read(remaining)
+            if not chunk:
+                break
+            result.write(chunk)
+            remaining -= len(chunk)
+        result.seek(0)
+        return result
+
+    @staticmethod
+    def _close_buffer(buffer):
+        """Close a response buffer and release its connection, if any."""
+        try:
+            buffer.close()
+        finally:
+            if hasattr(buffer, 'release_conn'):
+                buffer.release_conn()
+
     def __init__(self, buffer, offset, size, stream):
-        self.buffer = buffer if stream else io.BytesIO(buffer.read())
+        # Read at most `size` bytes: the declared range is what this buffer
+        # represents, and a server may send more than it announced.
+        if stream:
+            self.buffer = buffer
+        else:
+            try:
+                self.buffer = self._read_up_to(buffer, size)
+            finally:
+                self._close_buffer(buffer)
         self._offset = offset
         self._size = size
         self._position = offset
@@ -57,9 +93,7 @@ class PartialBuffer:
     def close(self):
         """Ensure memory and connections are closed"""
         if not self.buffer.closed:
-            self.buffer.close()
-            if hasattr(self.buffer, 'release_conn'):
-                self.buffer.release_conn()
+            self._close_buffer(self.buffer)
 
     def tell(self):
         """Returns the current position on the virtual buffer"""
@@ -224,7 +258,18 @@ class RemoteFetcher:
         kwargs = self.prepare_request(data_range)
         try:
             res, range_header = self._request(kwargs)
-            range_min, range_max = self.parse_range_header(range_header)
+            try:
+                try:
+                    range_min, range_max = self.parse_range_header(range_header)
+                except ValueError:
+                    raise RemoteZipError(
+                        "Malformed Content-Range returned by the server: %s" % range_header)
+                if range_max is None or range_max < range_min:
+                    raise RemoteZipError(
+                        "Invalid Content-Range returned by the server: %s" % range_header)
+            except RemoteZipError:
+                PartialBuffer._close_buffer(res)
+                raise
             return PartialBuffer(res, range_min, range_max - range_min + 1, stream)
         except IOError as e:
             raise RemoteIOError(str(e))
@@ -264,8 +309,8 @@ def _list_files(url, support_suffix_range, filenames):
         data = []
         for fname in filenames:
             zinfo = zip.getinfo(fname)
-            dt = datetime(*zinfo.date_time)
-            data.append((zinfo.file_size, dt.strftime('%Y-%m-%d %H:%M:%S'), zinfo.filename))
+            Y, m, d, H, M, S = zinfo.date_time
+            data.append((zinfo.file_size, f"{Y:04d}-{m:02d}-{d:02d} {H:02d}:{M:02d}:{S:02d}", zinfo.filename))
         _printTable(data, ('Length', 'DateTime', 'Name'), '><<')
 
 
@@ -298,7 +343,7 @@ def main():
     import os
 
     parser = argparse.ArgumentParser(description="Unzip remote files")
-    parser.add_argument('url', help='Url of the zip archive')
+    parser.add_argument('url', help='URL of the zip archive')
     parser.add_argument('filename', nargs='*', help='File to extract')
     parser.add_argument('-l', '--list', action='store_true', help='List files in the archive')
     parser.add_argument('-d', '--dir', default=os.getcwd(), help='Extract directory, default current directory')


=====================================
setup.py deleted
=====================================
@@ -1,41 +0,0 @@
-from setuptools import setup
-
-with open("README.md") as f:
-    description = f.read()
-
-setup(
-    name='remotezip',
-    version='0.12.3',
-    author='Giuseppe Tribulato',
-    author_email='gtsystem at gmail.com',
-    py_modules=['remotezip'],
-    url='https://github.com/gtsystem/python-remotezip',
-    license='MIT',
-    description='Access zip file content hosted remotely without downloading the full file.',
-    long_description=description,
-    long_description_content_type="text/markdown",
-    install_requires=["requests"],
-    extras_require={
-        "test": ["requests_mock"],
-    },
-    entry_points={
-        'console_scripts': ['remotezip = remotezip:main']
-    },
-    test_suite='test_remotezip',
-    classifiers=[
-        'Intended Audience :: Developers',
-        'Development Status :: 5 - Production/Stable',
-        'License :: OSI Approved :: MIT License',
-        'Programming Language :: Python',
-        'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.3',
-        'Programming Language :: Python :: 3.4',
-        'Programming Language :: Python :: 3.5',
-        'Programming Language :: Python :: 3.6',
-        'Programming Language :: Python :: 3.7',
-        'Programming Language :: Python :: 3.8',
-        'Programming Language :: Python :: 3.9',
-        'Programming Language :: Python :: 3.10'
-    ]
-)



View it on GitLab: https://salsa.debian.org/debian-gis-team/remotezip/-/commit/c4c83be22d77fb2f24e5fa8846ccd96f15696b4c

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/remotezip/-/commit/c4c83be22d77fb2f24e5fa8846ccd96f15696b4c
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20260830/7b1295b1/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list