@@ -127,7 +127,8 @@ def readlines(self, hint=-1):
127
127
def seek (self , offset , whence = os .SEEK_SET ):
128
128
if whence not in (os .SEEK_CUR , os .SEEK_END , os .SEEK_SET ):
129
129
raise ValueError ("invalid value for 'whence'" )
130
- return self ._f .seek (offset , whence )
130
+ self ._f .seek (offset , whence )
131
+ return self ._f .tell ()
131
132
132
133
def seekable (self ):
133
134
return True
@@ -155,12 +156,14 @@ def readinto(self, b):
155
156
def write (self , b ):
156
157
if not self .__mode .writing :
157
158
raise IOError ('not open for reading' )
158
- return self ._f .write (b )
159
+ self ._f .write (b )
160
+ return len (b )
159
161
160
162
def truncate (self , size = None ):
161
163
if size is None :
162
164
size = self ._f .tell ()
163
- return self ._f .truncate (size )
165
+ self ._f .truncate (size )
166
+ return size
164
167
165
168
166
169
@contextlib .contextmanager
@@ -205,8 +208,10 @@ class S3FS(FS):
205
208
key from standard configuration files.
206
209
:param str aws_secret_access_key: The secret key, or None to read
207
210
the key from standard configuration files.
208
- :param str aws_sssion_token:
209
- :param str region: Option S3 region.
211
+ :param str endpoint_url: Alternative endpoint url (``None`` to use
212
+ default).
213
+ :param str aws_session_token:
214
+ :param str region: Optional S3 region.
210
215
:param str delimiter: The delimiter to separate folders, defaults to
211
216
a forward slash.
212
217
@@ -256,6 +261,7 @@ def __init__(self,
256
261
aws_access_key_id = None ,
257
262
aws_secret_access_key = None ,
258
263
aws_session_token = None ,
264
+ endpoint_url = None ,
259
265
region = None ,
260
266
delimiter = '/' ):
261
267
_creds = (aws_access_key_id , aws_secret_access_key )
@@ -270,6 +276,7 @@ def __init__(self,
270
276
self .aws_access_key_id = aws_access_key_id
271
277
self .aws_secret_access_key = aws_secret_access_key
272
278
self .aws_session_token = aws_session_token
279
+ self .endpoint_url = endpoint_url
273
280
self .region = region
274
281
self .delimiter = delimiter
275
282
self ._tlocal = threading .local ()
@@ -331,7 +338,13 @@ def _get_object(self, path, key):
331
338
@property
332
339
def s3 (self ):
333
340
if not hasattr (self ._tlocal , 's3' ):
334
- self ._tlocal .s3 = boto3 .resource ('s3' )
341
+ self ._tlocal .s3 = boto3 .resource (
342
+ 's3' ,
343
+ aws_access_key_id = self .aws_access_key_id ,
344
+ aws_secret_access_key = self .aws_secret_access_key ,
345
+ aws_session_token = self .aws_session_token ,
346
+ endpoint_url = self .endpoint_url
347
+ )
335
348
return self ._tlocal .s3
336
349
337
350
@property
@@ -341,7 +354,8 @@ def client(self):
341
354
's3' ,
342
355
aws_access_key_id = self .aws_access_key_id ,
343
356
aws_secret_access_key = self .aws_secret_access_key ,
344
- aws_session_token = self .aws_session_token
357
+ aws_session_token = self .aws_session_token ,
358
+ endpoint_url = self .endpoint_url
345
359
)
346
360
return self ._tlocal .client
347
361
@@ -663,7 +677,7 @@ def gen_info():
663
677
664
678
def setbytes (self , path , contents ):
665
679
if not isinstance (contents , bytes ):
666
- raise ValueError ('contents must be bytes' )
680
+ raise TypeError ('contents must be bytes' )
667
681
668
682
_path = self .validatepath (path )
669
683
_key = self ._path_to_key (_path )
@@ -706,15 +720,20 @@ def copy(self, src_path, dst_path, overwrite=False):
706
720
raise errors .ResourceNotFound (dst_path )
707
721
_src_key = self ._path_to_key (_src_path )
708
722
_dst_key = self ._path_to_key (_dst_path )
709
- with s3errors (src_path ):
710
- self .client .copy_object (
711
- Bucket = self ._bucket_name ,
712
- Key = _dst_key ,
713
- CopySource = {
714
- 'Bucket' :self ._bucket_name ,
715
- 'Key' :_src_key
716
- }
717
- )
723
+ try :
724
+ with s3errors (src_path ):
725
+ self .client .copy_object (
726
+ Bucket = self ._bucket_name ,
727
+ Key = _dst_key ,
728
+ CopySource = {
729
+ 'Bucket' :self ._bucket_name ,
730
+ 'Key' :_src_key
731
+ }
732
+ )
733
+ except errors .ResourceNotFound :
734
+ if self .exists (src_path ):
735
+ raise errors .FileExpected (src_path )
736
+ raise
718
737
719
738
def move (self , src_path , dst_path , overwrite = False ):
720
739
self .copy (src_path , dst_path , overwrite = overwrite )
0 commit comments