4
4
import tempfile
5
5
from dataclasses import dataclass
6
6
from datetime import datetime
7
- from typing import Any , Dict , List , Optional , Tuple , Union
7
+ from typing import Any , Dict , List , NoReturn , Optional , Tuple , Union
8
8
from urllib .parse import quote , unquote
9
9
10
10
import fsspec
@@ -180,7 +180,7 @@ def _align_revision_in_path_with_revision(
180
180
revision = _align_revision_in_path_with_revision (revision_in_path , revision )
181
181
repo_and_revision_exist , err = self ._repo_and_revision_exist (repo_type , repo_id , revision )
182
182
if not repo_and_revision_exist :
183
- raise FileNotFoundError (path ) from err
183
+ _raise_file_not_found (path , err )
184
184
else :
185
185
repo_id_with_namespace = "/" .join (path .split ("/" )[:2 ])
186
186
path_in_repo_with_namespace = "/" .join (path .split ("/" )[2 :])
@@ -195,9 +195,9 @@ def _align_revision_in_path_with_revision(
195
195
path_in_repo = path_in_repo_without_namespace
196
196
repo_and_revision_exist , _ = self ._repo_and_revision_exist (repo_type , repo_id , revision )
197
197
if not repo_and_revision_exist :
198
- raise FileNotFoundError (path ) from err
198
+ _raise_file_not_found (path , err )
199
199
else :
200
- raise FileNotFoundError (path ) from err
200
+ _raise_file_not_found (path , err )
201
201
else :
202
202
repo_id = path
203
203
path_in_repo = ""
@@ -229,7 +229,7 @@ def _open(
229
229
revision : Optional [str ] = None ,
230
230
** kwargs ,
231
231
) -> "HfFileSystemFile" :
232
- if mode == "ab" :
232
+ if "a" in mode :
233
233
raise NotImplementedError ("Appending to remote files is not yet supported." )
234
234
return HfFileSystemFile (self , path , mode = mode , revision = revision , ** kwargs )
235
235
@@ -413,7 +413,21 @@ class HfFileSystemFile(fsspec.spec.AbstractBufferedFile):
413
413
def __init__ (self , fs : HfFileSystem , path : str , revision : Optional [str ] = None , ** kwargs ):
414
414
super ().__init__ (fs , path , ** kwargs )
415
415
self .fs : HfFileSystem
416
- self .resolved_path = fs .resolve_path (path , revision = revision )
416
+
417
+ mode = kwargs .get ("mode" , "r" )
418
+ try :
419
+ self .resolved_path = fs .resolve_path (path , revision = revision )
420
+ except FileNotFoundError as e :
421
+ if "w" in mode :
422
+ raise FileNotFoundError (
423
+ f"{ e } .\n Make sure the repository and revision exist before writing data."
424
+ ) from e
425
+
426
+ def __del__ (self ):
427
+ if not hasattr (self , "resolved_path" ):
428
+ # Means that the constructor failed. Nothing to do.
429
+ return
430
+ return super ().__del__ ()
417
431
418
432
def _fetch_range (self , start : int , end : int ) -> bytes :
419
433
headers = {
@@ -462,3 +476,14 @@ def safe_revision(revision: str) -> str:
462
476
463
477
def safe_quote (s : str ) -> str :
464
478
return quote (s , safe = "" )
479
+
480
+
481
+ def _raise_file_not_found (path : str , err : Optional [Exception ]) -> NoReturn :
482
+ msg = path
483
+ if isinstance (err , RepositoryNotFoundError ):
484
+ msg = f"{ path } (repository not found)"
485
+ elif isinstance (err , RevisionNotFoundError ):
486
+ msg = f"{ path } (revision not found)"
487
+ elif isinstance (err , HFValidationError ):
488
+ msg = f"{ path } (invalid repository id)"
489
+ raise FileNotFoundError (msg ) from err
0 commit comments