@@ -3165,14 +3165,22 @@ def __init__(self, handler: SFTPClientHandler, handle: bytes,
3165
3165
self ._appending = appending
3166
3166
self ._encoding = encoding
3167
3167
self ._errors = errors
3168
- self ._max_requests = max_requests
3169
3168
self ._offset = None if appending else 0
3170
3169
3171
3170
self .read_len = \
3172
3171
handler .limits .max_read_len if block_size == - 1 else block_size
3173
3172
self .write_len = \
3174
3173
handler .limits .max_write_len if block_size == - 1 else block_size
3175
3174
3175
+ if max_requests <= 0 :
3176
+ if self .read_len :
3177
+ max_requests = max (16 , min (MAX_SFTP_READ_LEN //
3178
+ self .read_len , 128 ))
3179
+ else :
3180
+ max_requests = 1
3181
+
3182
+ self ._max_requests = max_requests
3183
+
3176
3184
async def __aenter__ (self ) -> Self :
3177
3185
"""Allow SFTPClientFile to be used as an async context manager"""
3178
3186
@@ -3859,6 +3867,9 @@ async def _begin_copy(self, srcfs: _SFTPFSProtocol, dstfs: _SFTPFSProtocol,
3859
3867
block_size = min (srcfs .limits .max_read_len ,
3860
3868
dstfs .limits .max_write_len )
3861
3869
3870
+ if max_requests <= 0 :
3871
+ max_requests = max (16 , min (MAX_SFTP_READ_LEN // block_size , 128 ))
3872
+
3862
3873
if isinstance (srcpaths , (bytes , str , PurePath )):
3863
3874
srcpaths = [srcpaths ]
3864
3875
elif not isinstance (srcpaths , list ):
@@ -3916,7 +3927,7 @@ async def get(self, remotepaths: _SFTPPaths,
3916
3927
localpath : Optional [_SFTPPath ] = None , * ,
3917
3928
preserve : bool = False , recurse : bool = False ,
3918
3929
follow_symlinks : bool = False , block_size : int = - 1 ,
3919
- max_requests : int = _MAX_SFTP_REQUESTS ,
3930
+ max_requests : int = - 1 ,
3920
3931
progress_handler : SFTPProgressHandler = None ,
3921
3932
error_handler : SFTPErrorHandler = None ) -> None :
3922
3933
"""Download remote files
@@ -3957,7 +3968,9 @@ async def get(self, remotepaths: _SFTPPaths,
3957
3968
doesn't advertise limits.
3958
3969
3959
3970
The max_requests argument specifies the maximum number of
3960
- parallel read or write requests issued, defaulting to 128.
3971
+ parallel read or write requests issued, defaulting to a
3972
+ value between 16 and 128 depending on the selected block
3973
+ size to avoid excessive memory usage.
3961
3974
3962
3975
If progress_handler is specified, it will be called after
3963
3976
each block of a file is successfully downloaded. The arguments
@@ -4022,7 +4035,7 @@ async def put(self, localpaths: _SFTPPaths,
4022
4035
remotepath : Optional [_SFTPPath ] = None , * ,
4023
4036
preserve : bool = False , recurse : bool = False ,
4024
4037
follow_symlinks : bool = False , block_size : int = - 1 ,
4025
- max_requests : int = _MAX_SFTP_REQUESTS ,
4038
+ max_requests : int = - 1 ,
4026
4039
progress_handler : SFTPProgressHandler = None ,
4027
4040
error_handler : SFTPErrorHandler = None ) -> None :
4028
4041
"""Upload local files
@@ -4063,7 +4076,9 @@ async def put(self, localpaths: _SFTPPaths,
4063
4076
doesn't advertise limits.
4064
4077
4065
4078
The max_requests argument specifies the maximum number of
4066
- parallel read or write requests issued, defaulting to 128.
4079
+ parallel read or write requests issued, defaulting to a
4080
+ value between 16 and 128 depending on the selected block
4081
+ size to avoid excessive memory usage.
4067
4082
4068
4083
If progress_handler is specified, it will be called after
4069
4084
each block of a file is successfully uploaded. The arguments
@@ -4128,7 +4143,7 @@ async def copy(self, srcpaths: _SFTPPaths,
4128
4143
dstpath : Optional [_SFTPPath ] = None , * ,
4129
4144
preserve : bool = False , recurse : bool = False ,
4130
4145
follow_symlinks : bool = False , block_size : int = - 1 ,
4131
- max_requests : int = _MAX_SFTP_REQUESTS ,
4146
+ max_requests : int = - 1 ,
4132
4147
progress_handler : SFTPProgressHandler = None ,
4133
4148
error_handler : SFTPErrorHandler = None ,
4134
4149
remote_only : bool = False ) -> None :
@@ -4170,7 +4185,9 @@ async def copy(self, srcpaths: _SFTPPaths,
4170
4185
doesn't advertise limits.
4171
4186
4172
4187
The max_requests argument specifies the maximum number of
4173
- parallel read or write requests issued, defaulting to 128.
4188
+ parallel read or write requests issued, defaulting to a
4189
+ value between 16 and 128 depending on the selected block
4190
+ size to avoid excessive memory usage.
4174
4191
4175
4192
If progress_handler is specified, it will be called after
4176
4193
each block of a file is successfully copied. The arguments
@@ -4238,7 +4255,7 @@ async def mget(self, remotepaths: _SFTPPaths,
4238
4255
localpath : Optional [_SFTPPath ] = None , * ,
4239
4256
preserve : bool = False , recurse : bool = False ,
4240
4257
follow_symlinks : bool = False , block_size : int = - 1 ,
4241
- max_requests : int = _MAX_SFTP_REQUESTS ,
4258
+ max_requests : int = - 1 ,
4242
4259
progress_handler : SFTPProgressHandler = None ,
4243
4260
error_handler : SFTPErrorHandler = None ) -> None :
4244
4261
"""Download remote files with glob pattern match
@@ -4261,7 +4278,7 @@ async def mput(self, localpaths: _SFTPPaths,
4261
4278
remotepath : Optional [_SFTPPath ] = None , * ,
4262
4279
preserve : bool = False , recurse : bool = False ,
4263
4280
follow_symlinks : bool = False , block_size : int = - 1 ,
4264
- max_requests : int = _MAX_SFTP_REQUESTS ,
4281
+ max_requests : int = - 1 ,
4265
4282
progress_handler : SFTPProgressHandler = None ,
4266
4283
error_handler : SFTPErrorHandler = None ) -> None :
4267
4284
"""Upload local files with glob pattern match
@@ -4284,7 +4301,7 @@ async def mcopy(self, srcpaths: _SFTPPaths,
4284
4301
dstpath : Optional [_SFTPPath ] = None , * ,
4285
4302
preserve : bool = False , recurse : bool = False ,
4286
4303
follow_symlinks : bool = False , block_size : int = - 1 ,
4287
- max_requests : int = _MAX_SFTP_REQUESTS ,
4304
+ max_requests : int = - 1 ,
4288
4305
progress_handler : SFTPProgressHandler = None ,
4289
4306
error_handler : SFTPErrorHandler = None ,
4290
4307
remote_only : bool = False ) -> None :
@@ -4586,7 +4603,7 @@ async def open(self, path: _SFTPPath,
4586
4603
attrs : SFTPAttrs = SFTPAttrs (),
4587
4604
encoding : Optional [str ] = 'utf-8' , errors : str = 'strict' ,
4588
4605
block_size : int = - 1 ,
4589
- max_requests : int = _MAX_SFTP_REQUESTS ) -> SFTPClientFile :
4606
+ max_requests : int = - 1 ) -> SFTPClientFile :
4590
4607
"""Open a remote file
4591
4608
4592
4609
This method opens a remote file and returns an
@@ -4662,7 +4679,9 @@ async def open(self, path: _SFTPPath,
4662
4679
default of using the server-advertised limits.
4663
4680
4664
4681
The max_requests argument specifies the maximum number of
4665
- parallel read or write requests issued, defaulting to 128.
4682
+ parallel read or write requests issued, defaulting to a
4683
+ value between 16 and 128 depending on the selected block
4684
+ size to avoid excessive memory usage.
4666
4685
4667
4686
:param path:
4668
4687
The name of the remote file to open
@@ -4718,7 +4737,7 @@ async def open56(self, path: _SFTPPath,
4718
4737
attrs : SFTPAttrs = SFTPAttrs (),
4719
4738
encoding : Optional [str ] = 'utf-8' , errors : str = 'strict' ,
4720
4739
block_size : int = - 1 ,
4721
- max_requests : int = _MAX_SFTP_REQUESTS ) -> SFTPClientFile :
4740
+ max_requests : int = - 1 ) -> SFTPClientFile :
4722
4741
"""Open a remote file using SFTP v5/v6 flags
4723
4742
4724
4743
This method is very similar to :meth:`open`, but the pflags_or_mode
0 commit comments