@@ -214,6 +214,13 @@ class S3FS(FS):
214
214
:param str region: Optional S3 region.
215
215
:param str delimiter: The delimiter to separate folders, defaults to
216
216
a forward slash.
217
+ :param bool strict: Validate correctness of the destination path.
218
+ For example, throw exception FileExpected() when a directory
219
+ path is supplied to ``setbinfile()`` method.
220
+ These validations are quite expensive and normally can be
221
+ safely disabled, assuming the client application doesn't mess
222
+ with file paths intentionally.
223
+ Defaults to ``True``.
217
224
218
225
"""
219
226
@@ -263,7 +270,8 @@ def __init__(self,
263
270
aws_session_token = None ,
264
271
endpoint_url = None ,
265
272
region = None ,
266
- delimiter = '/' ):
273
+ delimiter = '/' ,
274
+ strict = True ):
267
275
_creds = (aws_access_key_id , aws_secret_access_key )
268
276
if any (_creds ) and not all (_creds ):
269
277
raise ValueError (
@@ -279,6 +287,7 @@ def __init__(self,
279
287
self .endpoint_url = endpoint_url
280
288
self .region = region
281
289
self .delimiter = delimiter
290
+ self .strict = strict
282
291
self ._tlocal = threading .local ()
283
292
super (S3FS , self ).__init__ ()
284
293
@@ -529,9 +538,10 @@ def on_close_create(s3file):
529
538
530
539
return s3file
531
540
532
- info = self .getinfo (path )
533
- if info .is_dir :
534
- raise errors .FileExpected (path )
541
+ if self .strict :
542
+ info = self .getinfo (path )
543
+ if info .is_dir :
544
+ raise errors .FileExpected (path )
535
545
536
546
def on_close (s3file ):
537
547
"""Called when the S3 file closes, to upload the data."""
@@ -557,9 +567,10 @@ def remove(self, path):
557
567
self .check ()
558
568
_path = self .validatepath (path )
559
569
_key = self ._path_to_key (_path )
560
- info = self .getinfo (path )
561
- if info .is_dir :
562
- raise errors .FileExpected (path )
570
+ if self .strict :
571
+ info = self .getinfo (path )
572
+ if info .is_dir :
573
+ raise errors .FileExpected (path )
563
574
self .client .delete_object (
564
575
Bucket = self ._bucket_name ,
565
576
Key = _key
@@ -681,14 +692,15 @@ def setbytes(self, path, contents):
681
692
682
693
_path = self .validatepath (path )
683
694
_key = self ._path_to_key (_path )
684
- if not self .isdir (dirname (path )):
685
- raise errors .ResourceNotFound (path )
686
- try :
687
- info = self .getinfo (path )
688
- if info .is_dir :
689
- raise errors .FileExpected (path )
690
- except errors .ResourceNotFound :
691
- pass
695
+ if self .strict :
696
+ if not self .isdir (dirname (path )):
697
+ raise errors .ResourceNotFound (path )
698
+ try :
699
+ info = self .getinfo (path )
700
+ if info .is_dir :
701
+ raise errors .FileExpected (path )
702
+ except errors .ResourceNotFound :
703
+ pass
692
704
693
705
bytes_file = io .BytesIO (contents )
694
706
with s3errors (path ):
@@ -699,14 +711,16 @@ def setbytes(self, path, contents):
699
711
def setbinfile (self , path , file ):
700
712
_path = self .validatepath (path )
701
713
_key = self ._path_to_key (_path )
702
- if not self .isdir (dirname (path )):
703
- raise errors .ResourceNotFound (path )
704
- try :
705
- info = self .getinfo (path )
706
- if info .is_dir :
707
- raise errors .FileExpected (path )
708
- except errors .ResourceNotFound :
709
- pass
714
+
715
+ if self .strict :
716
+ if not self .isdir (dirname (path )):
717
+ raise errors .ResourceNotFound (path )
718
+ try :
719
+ info = self .getinfo (path )
720
+ if info .is_dir :
721
+ raise errors .FileExpected (path )
722
+ except errors .ResourceNotFound :
723
+ pass
710
724
711
725
with s3errors (path ):
712
726
self .client .upload_fileobj (file , self ._bucket_name , _key )
@@ -716,8 +730,9 @@ def copy(self, src_path, dst_path, overwrite=False):
716
730
raise errors .DestinationExists (dst_path )
717
731
_src_path = self .validatepath (src_path )
718
732
_dst_path = self .validatepath (dst_path )
719
- if not self .isdir (dirname (_dst_path )):
720
- raise errors .ResourceNotFound (dst_path )
733
+ if self .strict :
734
+ if not self .isdir (dirname (_dst_path )):
735
+ raise errors .ResourceNotFound (dst_path )
721
736
_src_key = self ._path_to_key (_src_path )
722
737
_dst_key = self ._path_to_key (_dst_path )
723
738
try :
0 commit comments