55import time
66import zipfile
77from collections .abc import Awaitable , Callable
8- from io import BytesIO
8+ from io import IOBase
99from pathlib import Path
1010from typing import Any , Final , TypedDict , cast
1111
1212import aiofiles
1313import aiofiles .tempfile
1414import fsspec # type: ignore[import-untyped]
15+ import repro_zipfile
1516from pydantic import ByteSize , FileUrl , parse_obj_as
1617from pydantic .networks import AnyUrl
1718from servicelib .logging_utils import LogLevelInt , LogMessageStr
@@ -33,7 +34,7 @@ def _file_progress_cb(
3334 log_publishing_cb : LogPublishingCB ,
3435 text_prefix : str ,
3536 main_loop : asyncio .AbstractEventLoop ,
36- ** kwargs ,
37+ ** kwargs , # noqa: ARG001
3738):
3839 asyncio .run_coroutine_threadsafe (
3940 log_publishing_cb (
@@ -78,7 +79,7 @@ def _s3fs_settings_from_s3_settings(s3_settings: S3Settings) -> S3FsSettingsDict
7879 return s3fs_settings
7980
8081
81- def _file_chunk_streamer (src : BytesIO , dst : BytesIO ):
82+ def _file_chunk_streamer (src : IOBase , dst : IOBase ):
8283 data = src .read (CHUNK_SIZE )
8384 segment_len = dst .write (data )
8485 return (data , segment_len )
@@ -98,6 +99,8 @@ async def _copy_file(
9899 with fsspec .open (src_url , mode = "rb" , ** src_storage_kwargs ) as src_fp , fsspec .open (
99100 dst_url , "wb" , ** dst_storage_kwargs
100101 ) as dst_fp :
102+ assert isinstance (src_fp , IOBase ) # nosec
103+ assert isinstance (dst_fp , IOBase ) # nosec
101104 file_size = getattr (src_fp , "size" , None )
102105 data_read = True
103106 total_data_written = 0
@@ -159,7 +162,7 @@ async def pull_file_from_remote(
159162 if src_mime_type == _ZIP_MIME_TYPE and target_mime_type != _ZIP_MIME_TYPE :
160163 await log_publishing_cb (f"Uncompressing '{ dst_path .name } '..." , logging .INFO )
161164 logger .debug ("%s is a zip file and will be now uncompressed" , dst_path )
162- with zipfile . ZipFile (dst_path , "r" ) as zip_obj :
165+ with repro_zipfile . ReproducibleZipFile (dst_path , "r" ) as zip_obj :
163166 await asyncio .get_event_loop ().run_in_executor (
164167 None , zip_obj .extractall , dst_path .parents [0 ]
165168 )
@@ -248,7 +251,8 @@ async def push_file_to_remote(
248251 f"Compressing '{ src_path .name } ' to '{ archive_file_path .name } '..." ,
249252 logging .INFO ,
250253 )
251- with zipfile .ZipFile (
254+
255+ with repro_zipfile .ReproducibleZipFile (
252256 archive_file_path , mode = "w" , compression = zipfile .ZIP_STORED
253257 ) as zfp :
254258 await asyncio .get_event_loop ().run_in_executor (
0 commit comments