def openbin(self, path: str, mode: str = "r", buffering: int = -1, **options) -> "GCSFile": _mode = Mode(mode) _mode.validate_bin() self.check() _path = self.validatepath(path) _key = self._path_to_key(_path) def on_close(gcs_file): if _mode.create or _mode.writing: gcs_file.raw.seek(0) blob = self._get_blob(_key) if not blob: blob = self.bucket.blob(_key) blob.upload_from_file(gcs_file.raw) gcs_file.raw.close() if _mode.create: dir_path = dirname(_path) if dir_path != "/": _dir_key = self._path_to_dir_key(dir_path) if not self.bucket.get_blob(_dir_key): raise errors.ResourceNotFound(path) try: info = self.getinfo(path) except errors.ResourceNotFound: pass else: if _mode.exclusive: raise errors.FileExists(path) if info.is_dir: raise errors.FileExpected(path) gcs_file = GCSFile.factory(path, _mode, on_close=on_close) if _mode.appending: blob = self._get_blob(_key) if blob: # in case there is an existing blob in GCS, we download it and seek until the end of the stream gcs_file.seek(0, os.SEEK_END) blob.download_to_file(gcs_file.raw) return gcs_file if self.strict: info = self.getinfo(path) if info.is_dir: raise errors.FileExpected(path) gcs_file = GCSFile.factory(path, _mode, on_close=on_close) blob = self._get_blob(_key) if not blob: raise errors.ResourceNotFound blob.download_to_file(gcs_file.raw) gcs_file.seek(0) return gcs_file
def openbin(self, path, mode="r", buffering=-1, **options): _mode = Mode(mode) _mode.validate_bin() self.check() _path = self.validatepath(path) _key = self._path_to_key(_path) if _mode.create: def on_close(s3file): try: s3file.raw.seek(0) with s3errors(path): self.client.upload_fileobj(s3file.raw, self._bucket_name, _key) finally: s3file.raw.close() try: info = self.getinfo(path) except errors.ResourceNotFound: pass else: if _mode.exclusive: raise errors.FileExists(path) if info.is_dir: raise errors.FileExpected(path) s3file = S3File.factory(path, _mode, on_close=on_close) if _mode.appending: try: with s3errors(path): self.client.download_fileobj(self._bucket_name, _key, s3file.raw) except errors.ResourceNotFound: pass else: s3file.seek(0, os.SEEK_END) return s3file info = self.getinfo(path) if info.is_dir: raise errors.FileExpected(path) def on_close(s3file): try: if _mode.writing: s3file.raw.seek(0, os.SEEK_SET) with s3errors(path): self.client.upload_fileobj(s3file.raw, self._bucket_name, _key) finally: s3file.raw.close() s3file = S3File.factory(path, _mode, on_close=on_close) with s3errors(path): self.client.download_fileobj(self._bucket_name, _key, s3file.raw) s3file.seek(0, os.SEEK_SET) return s3file
def openbin(self, path, mode="r", buffering=-1, **options): """ Open file under `path` in binary mode. :param str path: Path pointing to a file. :param str mode: Text representation of open mode e.g. "rw+" :param int buffering: Whether the BaseIO instance should be buffered or not :param map options: Additional PyFilesystem options """ # type: (Text, Text, int, **Any) -> BinaryIO path = ensureUnicode(path) _mode = Mode(mode) _mode.validate_bin() _path = toAscii(self.validatepath(path)) with self._lock: try: info = self.getinfo(path) except errors.ResourceNotFound: if _mode.reading: raise errors.ResourceNotFound(path) if _mode.writing and not self.isdir(dirname(_path)): raise errors.ResourceNotFound(path) else: if info.is_dir: raise errors.FileExpected(path) if _mode.exclusive: raise errors.FileExists(path) # TODO support mode handle = self._odfs.open(_path) onedata_file = OnedataFile(self._odfs, handle, path, mode) return onedata_file # type: ignore
def open( self, path, # type: Text mode="r", # type: Text buffering=-1, # type: int encoding=None, # type: Optional[Text] newline="", # type: Text line_buffering=False, # type: bool **options # type: Any ): _open_mode = Mode(mode) base.validate_open_mode(mode) self.check() _path = self.norm_path(path) _parent_fs = self.delegate_fs() _encoding = encoding or "utf-8" file = _custom_conpot_file( file_system=self, parent_fs=_parent_fs, path=_path, mode=_open_mode.to_platform(), buffering=buffering, encoding=encoding, newline=newline, line_buffering=line_buffering, ) return file
def openbin(self, path, mode="r", buffering=-1, **options): path = self.fix_path(path) _mode = Mode(mode) mode = _mode _mode.validate_bin() _path = self.validatepath(path) log.debug("openbin: %s, %s", path, mode) with self._lock: try: info = self.getinfo(_path) except errors.ResourceNotFound: if not _mode.create: raise # Target doesn't exist and we're in create mode. Ensure the # parent is an existing directory before we try to create a file # in it. parent_path = self.get_parent(_path) # Can't use self.isdir() because it doesn't crash if the # directory doesn't exist, and we don't want to stat a file twice # if we can avoid it. info = self.getinfo(parent_path) if not info.is_dir: raise errors.DirectoryExpected(parent_path) return DropboxFile(self.dropbox, path, mode) # Target exists. if info.is_dir: raise errors.FileExpected(path) if _mode.exclusive: raise errors.FileExists(path) return DropboxFile(self.dropbox, path, mode)
def __init__(self, fs: PyFat, path: str, mode: Mode = Mode('r')) -> None: """Wrap basic I/O operations for PyFat. **Currently read-only**. :param fs: `PyFat`: Instance of opened filesystem :param path: `str`: Path to file. If `mode` is *r*, the file must exist. :param mode: `Mode`: Mode to open file in. """ super(FatIO, self).__init__() self.mode = Mode(mode) self.fs = fs self.name = str(path) # TODO: File locking self._lock = threading.Lock() self.dir_entry = self.fs.root_dir.get_entry(path) if self.dir_entry.is_directory() or self.dir_entry.is_special(): raise IsADirectoryError(errno.EISDIR, path) elif self.dir_entry.is_volume_id(): raise FileNotFoundError(errno.ENOENT, path) #: Position in bytes from beginning of file self.__bpos = 0 #: Current cluster chain number self.__cpos = self.dir_entry.get_cluster() #: Current cluster chain offset (in bytes) self.__coffpos = 0 #: Handle to cluster chain iterator self.__fp = self.fs.get_cluster_chain(self.__cpos)
def openbin(self, path, mode="r", buffering=-1, **options): path = self.fix_path(path) _mode = Mode(mode) mode = _mode _mode.validate_bin() _path = self.validatepath(path) log.debug("openbin: %s, %s", path, mode) with self._lock: try: info = self.getinfo(_path) log.debug("Info: %s", info) except errors.ResourceNotFound: if not _mode.create: raise errors.ResourceNotFound(path) # Check the parent is an existing directory if not self.getinfo(self.get_parent(_path)).is_dir: raise errors.DirectoryExpected(path) else: if info.is_dir: raise errors.FileExpected(path) if _mode.exclusive: raise errors.FileExists(path) return DropboxFile(self.dropbox, path, mode)
def openbin(self, path, mode="r", buffering=-1, **options): _mode = Mode(mode) _mode.validate_bin() self.check() _path = self.validatepath(path) _key = self._path_to_key(_path) info = None try: info = self.getinfo(path) except errors.ResourceNotFound: pass else: if info.is_dir: raise errors.FileExpected(path) if _mode.create: try: dir_path = dirname(_path) if dir_path != "/": self.getinfo(dir_path) except errors.ResourceNotFound: raise errors.ResourceNotFound(path) if info and _mode.exclusive: raise errors.FileExists(path) # AzureDLFile does not support exclusive mode, but we mimic it dlkfile = self.dlk.open(_key, str(_mode).replace("x", "")) return dlkfile
def openbin(self, path, mode="r", buffering=-1, **options): _mode = Mode(mode) _mode.validate_bin() self.check() _path = self.validatepath(path) if _path == "/": raise FileExpected(path) with convert_os_errors("openbin", path): fd = self._fs.open(_path, os.O_RDONLY) fdict = self._fs.openFiles[path] self._fs._ensure_region_available(path, fdict, fd, 0, fdict["obj"]["size"]) return open(fdict["path"], "r+b")
def openbin(self, path, mode="r", buffering=-1, **options): self.check() _mode = Mode(mode) _mode.validate_bin() if _mode.create: def on_close_create(mcfile): try: mcfile.raw.seek(0) self._c.upload_file( self._project_id, 1, ) finally: pass
def openbin(self, path: str, mode: str = "r", buffering: int = -1, **options): """Open file from filesystem. :param path: Path to file on filesystem :param mode: Mode to open file in :param buffering: TBD returns: `BinaryIO` stream """ path = self.validatepath(path) mode = Mode(mode + 'b') if mode.create: if mode.exclusive: try: self.getinfo(path) except ResourceNotFound: pass else: raise FileExists(path) self.create(path) if "t" in mode: raise ValueError('Text-mode not allowed in openbin') try: info = self.getinfo(path) except ResourceNotFound: raise ResourceNotFound(path) else: if info.is_dir: raise FileExpected(path) return FatIO(self.fs, path, mode)
def openbin(self, path, mode="r", buffering=-1, **options): # pylint: disable=unused-argument _CheckPath(path) with self._lock: _log.info(f"openbin: {path}, {mode}, {buffering}") parsedMode = Mode(mode) idsFromPath = self._itemsFromPath(path) item = idsFromPath.get(path) if parsedMode.exclusive and item is not None: raise FileExists(path) if parsedMode.reading and not parsedMode.create and item is None: raise ResourceNotFound(path) if item is not None and item["mimeType"] == _folderMimeType: raise FileExpected(path) parentDir = dirname(path) _log.debug(f"looking up id for {parentDir}") parentDirItem = idsFromPath.get(parentDir) # make sure that the parent directory exists if we're writing if parsedMode.writing and parentDirItem is None: raise ResourceNotFound(parentDir) return _UploadOnClose(fs=self, path=path, thisMetadata=item, parentMetadata=parentDirItem, parsedMode=parsedMode, **options)
def openbin(self, path, mode='r', buffering=-1, **options): """ Open a file in the ConpotFS in binary mode. """ logger.debug('Opening file {} with mode {}'.format(path, mode)) _path = self.norm_path(path) _bin_mode = Mode(mode).to_platform_bin() _bin_mode = _bin_mode.replace("t", "") if "t" in _bin_mode else _bin_mode _parent_fs = self.delegate_fs() self.check() binary_file = _custom_conpot_file(file_system=self, parent_fs=_parent_fs, path=_path, mode=_bin_mode, encoding=None) return binary_file
def openbin(self, path, mode="r", buffering=-1, **options): _CheckPath(path) with self._lock: if "t" in mode: raise ValueError("Text mode is not allowed in openbin") parsedMode = Mode(mode) exists = self.exists(path) if parsedMode.exclusive and exists: raise FileExists(path) if parsedMode.reading and not parsedMode.create and not exists: raise ResourceNotFound(path) if self.isdir(path): raise FileExpected(path) if parsedMode.writing: # make sure that the parent directory exists parentDir = dirname(path) response = self.session.get(_PathUrl(parentDir, "")) if response.status_code == 404: raise ResourceNotFound(parentDir) response.raise_for_status() itemId = None if exists: response = self.session.get(_PathUrl(path, "")) response.raise_for_status() itemId = response.json()["id"] return _UploadOnClose(session=self.session, path=path, itemId=itemId, mode=parsedMode)
def openbin(self, path, mode='r', buffering=-1, **options): _log.info(f'openbin({path}, {mode}, {buffering}, {options})') path = self.validatepath(path) with self._lock: parsedMode = Mode(mode) idsFromPath = self._itemsFromPath(path) item = idsFromPath.get(path) if parsedMode.exclusive and item is not None: raise FileExists(path) if parsedMode.reading and not parsedMode.create and item is None: raise ResourceNotFound(path) if item is not None and item['mimeType'] == _folderMimeType: raise FileExpected(path) parentDir = dirname(path) _log.debug( f'looking up id for {parentDir} in {list(idsFromPath.keys())}') parentDirItem = idsFromPath.get(parentDir) # make sure that the parent directory exists if we're writing if parsedMode.writing and parentDirItem is None: raise ResourceNotFound(parentDir) return _UploadOnClose(fs=self, path=path, thisMetadata=item, parentMetadata=parentDirItem, parsedMode=parsedMode, **options)
def openbin(self, path, mode="r", buffering=-1, **options): parsedMode = Mode(mode) if parsedMode.exclusive and self.exists(path): raise FileExists(path) elif parsedMode.reading and not parsedMode.create and not self.exists(path): raise ResourceNotFound(path) elif self.isdir(path): raise FileExpected(path) return UploadOnClose(client=self.client, path=path, mode=parsedMode)
def openbin(self, path, mode='r', buffering=-1, **options): # noqa: D102 """Open a binary file-like object. Arguments: path (str): A path on the filesystem. mode (str): Mode to open the file (must be a valid, non-text mode). Since this method only opens binary files, the ``b`` in the mode is implied. buffering (int): the buffering policy (-1 to use default buffering, 0 to disable completely, 1 to enable line based buffering, or any larger positive integer for a custom buffer size). Keyword Arguments: pipelined (bool): Set the transfer in pipelined mode (should improve transfer speed). Defaults to ``True``. Raises: fs.errors.FileExpected: if the path if not a file. fs.errors.FileExists: if the file already exists and *exclusive mode* is specified (``x`` in the mode). fs.errors.ResourceNotFound: if the path does not exist. Returns: io.IOBase: a file handle. """ self.check() _path = self.validatepath(path) _mode = Mode(mode) _mode.validate_bin() with self._lock: if _mode.exclusive and self.exists(_path): raise errors.FileExists(path) elif _mode.reading and not _mode.create and not self.exists(_path): raise errors.ResourceNotFound(path) elif self.isdir(_path): raise errors.FileExpected(path) with convert_sshfs_errors('openbin', path): _sftp = self._client.open_sftp() handle = _sftp.open(_path, mode=_mode.to_platform_bin(), bufsize=buffering) handle.set_pipelined(options.get("pipelined", True)) return SSHFile(handle)
def openbin(self, path, mode='r', buffering=-1, **options): _mode = Mode(mode) _mode.validate_bin() _path = self.validatepath(path) log.debug("openbin: %s, %s", path, mode) with self._lock: try: info = self.getinfo(_path) log.debug("Info: %s", info) except errors.ResourceNotFound: if not _mode.create: raise errors.ResourceNotFound(path) else: if info.is_dir: raise errors.FileExpected(path) if _mode.exclusive: raise errors.FileExists(path) return WebDAVFile(self, _path, _mode)
def openbin(self, path, mode="r", buffering=-1, **options): _mode = Mode(mode) _mode.validate_bin() self.check() _path = self.validatepath(path) _key = self._path_to_key(_path) if _mode.appending: raise errors.ResourceError(path, msg="append mode is not supported") if _mode.create: if self.strict: try: dir_path = dirname(_path) if dir_path != "/": _dir_key = self._path_to_dir_key(dir_path) self._get_object(dir_path, _dir_key) except errors.ResourceNotFound: raise errors.ResourceNotFound(path) try: info = self._getinfo(path) except errors.ResourceNotFound: pass else: if _mode.exclusive: raise errors.FileExists(path) if self.strict and info.is_dir: raise errors.FileExpected(path) obj = self.s3.Object(self._bucket_name, _key) return S3OutputFile(obj, upload_kwargs=self._get_upload_args(_key)) if self.strict: info = self.getinfo(path) if info.is_dir: raise errors.FileExpected(path) obj = self.s3.Object(self._bucket_name, _key) return S3InputFile(obj)
def openbin(self, path, mode='r', buffering=-1, **options): _mode = Mode(mode) _mode.validate_bin() _path = self.validatepath(path) log.debug("openbin: %s, %s", path, mode) with self._lock: try: info = self.getinfo(_path) log.debug("Info: %s", info) except errors.ResourceNotFound: if not _mode.create: raise errors.ResourceNotFound(path) # Check the parent is an existing directory if self.gettype(dirname(_path)) is not ResourceType.directory: raise errors.DirectoryExpected(dirname(path)) else: if info.is_dir: raise errors.FileExpected(path) if _mode.exclusive: raise errors.FileExists(path) return WebDAVFile(self, _path, _mode)
def test_mode_object(self): with self.assertRaises(ValueError): Mode("") with self.assertRaises(ValueError): Mode("J") with self.assertRaises(ValueError): Mode("b") with self.assertRaises(ValueError): Mode("rtb") mode = Mode("w") repr(mode) self.assertEqual(text_type(mode), "w") self.assertTrue(mode.create) self.assertFalse(mode.reading) self.assertTrue(mode.writing) self.assertFalse(mode.appending) self.assertFalse(mode.updating) self.assertTrue(mode.truncate) self.assertFalse(mode.exclusive) self.assertFalse(mode.binary) self.assertTrue(mode.text)
def test_mode_object(self): with self.assertRaises(ValueError): Mode('') with self.assertRaises(ValueError): Mode('J') with self.assertRaises(ValueError): Mode('b') with self.assertRaises(ValueError): Mode('rtb') mode = Mode('w') repr(mode) self.assertEqual(text_type(mode), 'w') self.assertTrue(mode.create) self.assertFalse(mode.reading) self.assertTrue(mode.writing) self.assertFalse(mode.appending) self.assertFalse(mode.updating) self.assertTrue(mode.truncate) self.assertFalse(mode.exclusive) self.assertFalse(mode.binary) self.assertTrue(mode.text)
def __init__(self, fs: PyFat, path: str, mode: Mode = Mode('r')) -> None: """Wrap basic I/O operations for PyFat. **Currently read-only**. :param fs: `PyFat`: Instance of opened filesystem :param path: `str`: Path to file. If `mode` is *r*, the file must exist. :param mode: `Mode`: Mode to open file in. """ super(FatIO, self).__init__() self.mode = Mode(mode) self.fs = fs self.__fp = None self.name = str(path) # TODO: Seek support self.pos = 0 # TODO: File locking self._lock = threading.Lock() self.dir_entry = self.fs.root_dir.get_entry(path) if self.dir_entry.is_directory() or self.dir_entry.is_special(): raise IsADirectoryError(errno.EISDIR, path) elif self.dir_entry.is_volume_id(): raise FileNotFoundError(errno.ENOENT, path)
def openbin(self, path, mode="r", buffering=-1, **options): mode = Mode(mode) exists = True isDir = False try: isDir = self.getinfo(path).is_dir except ResourceNotFound: exists = False if mode.exclusive and exists: raise FileExists(path) elif mode.reading and not mode.create and not exists: raise ResourceNotFound(path) elif isDir: raise FileExpected(path) return DropboxFile(self.dropbox, path, mode)
def open(self, path, # type: Text mode='r', # type: Text buffering=-1, # type: int encoding=None, # type: Optional[Text] newline='', # type: Text line_buffering=False, # type: bool **options # type: Any ): _open_mode = Mode(mode) base.validate_open_mode(mode) self.check() _path = self.norm_path(path) _parent_fs = self.delegate_fs() _encoding = encoding or "utf-8" file = _custom_conpot_file(file_system=self, parent_fs=_parent_fs, path=_path, mode=_open_mode.to_platform(), buffering=buffering, encoding=encoding, newline=newline, line_buffering=line_buffering) return file
def openbin(self, path, mode="r", buffering=-1, **options): # pylint: disable=unused-argument _CheckPath(path) with self._lock: info(f"openbin: {path}, {mode}, {buffering}") parsedMode = Mode(mode) exists = self.exists(path) if parsedMode.exclusive and exists: raise FileExists(path) elif parsedMode.reading and not parsedMode.create and not exists: raise ResourceNotFound(path) elif self.isdir(path): raise FileExpected(path) if parsedMode.writing: # make sure that the parent directory exists parentDir = dirname(path) if self._itemFromPath(parentDir) is None: raise ResourceNotFound(parentDir) return _UploadOnClose(fs=self, path=path, parsedMode=parsedMode)
def openbin(self, path: str, mode: str = "r", buffering: int = -1, **options: Any) -> BinaryIO: self.check() self.validatepath(path) parent_dir = fs.path.dirname(fs.path.forcedir(path)[:-1]) if not parent_dir: parent_dir = "/" if not self.isdir(parent_dir): raise fs.errors.ResourceNotFound(path) mode_obj = Mode(mode) layer = self.layer(path) if layer == NO_LAYER: if mode_obj.create: for p in fs.path.recursepath(path)[:-1]: self.additions_fs.makedirs(p, recreate=True) self.mark_deletion(p) self.mark_deletion(path) return self.additions_fs.openbin(path, mode, buffering, **options) else: raise fs.errors.ResourceNotFound(path) elif layer == ADD_LAYER: self.mark_deletion(path) return self.additions_fs.openbin(path, mode, buffering, **options) elif layer == BASE_LAYER: if mode_obj.writing: self.copy_up(path) return self.additions_fs.openbin(path, mode, buffering, **options) else: return self.base_fs.openbin(path, mode, buffering, **options) elif layer == ROOT_LAYER: raise fs.errors.FileExpected(path) else: raise RuntimeError(f"Unknown layer {layer}.")
def _btopen(path, mode="r"): """Open the file (eg. return a BtIO object)""" stream = fire_fs.btopen(path, mode) _mode = Mode(mode) if _mode.truncate: stream.seek(0) stream.truncate() if _mode.reading and _mode.writing: stream = io.BufferedRandom(stream) elif _mode.reading: stream = io.BufferedReader(stream) elif _mode.writing or _mode.appending: stream = io.BufferedWriter(stream) # if not _mode.reading: # stream.readable = lambda: False # mock a write-only stream # if not _mode.writing: # stream.writable = lambda: False # mock a read-only stream if _mode.appending: stream.seek(0, 2) # io.SEEK_END io_object = RawWrapper(stream, mode=mode, name=path) return io_object
def __init__(self, odfs, handle, path, mode): """ `OnedataFile` constructor. `OnedataFile` is intentended to be constructed manually, but rather using `open()` or `openbin()` methods of `OnedataFS`. :param OnedataFS odfs: Reference to OnedataFS instance :param OnedataFileHandle handle: Instance of the OnedataFileHandle :param str path: Full path to file or directory, relative to the filesystem root :param int mode: File open mode """ # type: (OnedataFS, Text, Text) -> None super(OnedataFile, self).__init__() self.odfs = odfs self.handle = handle self.path = path self.mode = Mode(mode) self.pos = 0 self._lock = threading.Lock()
def openbin(self, path: Text, mode: Text = "r", buffering: int = -1, **options: Any) -> BinaryIO: """ Open a binary file. """ npath = self.normalize_path(path) if self._closed: raise errors.FilesystemClosed if not self.exists(dirname(npath)): raise errors.ResourceNotFound(dirname(path)) if "t" in mode: raise ValueError if "b" not in mode: mode += "b" file_mode = Mode(mode) exists = self.exists(npath) if file_mode.exclusive and exists: raise errors.FileExists(path) if file_mode.reading and not exists: raise errors.ResourceNotFound(path) if (file_mode.reading or (file_mode.writing and exists)) and self.isdir(path): raise errors.FileExpected(path) data = gzip.compress(b"") if file_mode.create and not exists: cursor = self.connection.cursor() cursor.execute( "INSERT INTO sqlar (name, mode, mtime, sz, data) VALUES (?, ?, ?, ?, ?)", (npath, 0o700, datetime.utcnow().timestamp(), 0, data) ) cursor.close() elif file_mode.truncate: cursor = self.connection.cursor() cursor.execute("UPDATE sqlar SET data = ? WHERE name = ?", (data, npath)) cursor.close() return SQLiteFile(self, npath, file_mode)
def openbin(self, path, mode="r", buffering=-1, **options): _mode = Mode(mode) _mode.validate_bin() _bucket_name_copy = self._bucket_name self.check() _path = self.validatepath(path) _key = self._path_to_key(_path) if _mode.create: def on_close_create(s3file): """Called when the S3 file closes, to upload data.""" try: s3file.raw.seek(0) with s3errors(path): self.client.upload_fileobj( s3file.raw, s3file._bucket_name, _key, ExtraArgs=self._get_upload_args(_key), ) finally: s3file.raw.close() try: dir_path = dirname(_path) if dir_path != "/": _dir_key = self._path_to_dir_key(dir_path) self._get_object(dir_path, _dir_key) except errors.ResourceNotFound: raise errors.ResourceNotFound(path) try: info = self._getinfo(path) except errors.ResourceNotFound: pass else: if _mode.exclusive: raise errors.FileExists(path) if info.is_dir: raise errors.FileExpected(path) s3file = S3File.factory(_bucket_name_copy, path, _mode, on_close=on_close_create) if _mode.appending: try: with s3errors(path): self.client.download_fileobj( s3file._bucket_name, _key, s3file.raw, ExtraArgs=self.download_args, ) except errors.ResourceNotFound: pass else: s3file.seek(0, os.SEEK_END) return s3file if self.strict: info = self.getinfo(path) if info.is_dir: raise errors.FileExpected(path) def on_close(s3file): """Called when the S3 file closes, to upload the data.""" try: if _mode.writing: s3file.raw.seek(0, os.SEEK_SET) with s3errors(path): self.client.upload_fileobj( s3file.raw, s3file._bucket_name, _key, ExtraArgs=self._get_upload_args(_key), ) finally: s3file.raw.close() s3file = S3File.factory(_bucket_name_copy, path, _mode, on_close=on_close) with s3errors(path): self.client.download_fileobj( s3file._bucket_name, _key, s3file.raw, ExtraArgs=self.download_args ) s3file.seek(0, os.SEEK_SET) return s3file