1515from tornado .web import HTTPError
1616from traitlets import Bool
1717from traitlets .config import Configurable
18+ from traitlets .config .configurable import LoggingConfigurable
1819
1920from jupyter_server .utils import ApiPath , to_api_path , to_os_path
2021
@@ -165,7 +166,7 @@ def _simple_writing(path, text=True, encoding="utf-8", log=None, **kwargs):
165166 fileobj .close ()
166167
167168
168- class FileManagerMixin (Configurable ):
169+ class FileManagerMixin (LoggingConfigurable , Configurable ):
169170 """
170171 Mixin for ContentsAPI classes that interact with the filesystem.
171172
@@ -187,7 +188,7 @@ class FileManagerMixin(Configurable):
187188 True ,
188189 config = True ,
189190 help = """By default notebooks are saved on disk on a temporary file and then if succefully written, it replaces the old ones.
190- This procedure, namely 'atomic_writing', causes some bugs on file system whitout operation order enforcement (like some networked fs).
191+ This procedure, namely 'atomic_writing', causes some bugs on file system without operation order enforcement (like some networked fs).
191192 If set to False, the new notebook is written directly on the old one which could fail (eg: full filesystem or quota )""" ,
192193 )
193194
@@ -214,7 +215,7 @@ def atomic_writing(self, os_path, *args, **kwargs):
214215 return
215216
216217 with self .perm_to_403 (os_path ):
217- kwargs ["log" ] = self .log # type:ignore
218+ kwargs ["log" ] = self .log
218219 if self .use_atomic_writing :
219220 with atomic_writing (os_path , * args , ** kwargs ) as f :
220221 yield f
@@ -234,7 +235,7 @@ def perm_to_403(self, os_path=""):
234235 # but nobody should be doing that anyway.
235236 if not os_path :
236237 os_path = e .filename or "unknown file"
237- path = to_api_path (os_path , root = self .root_dir ) # type:ignore
238+ path = to_api_path (os_path , root = self .root_dir ) # type:ignore[attr-defined]
238239 # iOS: better error message
239240 import sys
240241 if (sys .platform == "darwin" and os .uname ().machine .startswith ("iP" )):
@@ -249,7 +250,7 @@ def _copy(self, src, dest):
249250
250251 like shutil.copy2, but log errors in copystat
251252 """
252- copy2_safe (src , dest , log = self .log ) # type:ignore
253+ copy2_safe (src , dest , log = self .log )
253254
254255 def _get_os_path (self , path ):
255256 """Given an API path, return its file system path.
@@ -268,7 +269,8 @@ def _get_os_path(self, path):
268269 ------
269270 404: if path is outside root
270271 """
271- root = os .path .abspath (self .root_dir ) # type:ignore
272+ self .log .debug ("Reading path from disk: %s" , path )
273+ root = os .path .abspath (self .root_dir ) # type:ignore[attr-defined]
272274 # to_os_path is not safe if path starts with a drive, since os.path.join discards first part
273275 if os .path .splitdrive (path )[0 ]:
274276 raise HTTPError (404 , "%s is not a relative API path" % path )
@@ -375,7 +377,7 @@ async def _copy(self, src, dest):
375377
376378 like shutil.copy2, but log errors in copystat
377379 """
378- await async_copy2_safe (src , dest , log = self .log ) # type:ignore
380+ await async_copy2_safe (src , dest , log = self .log )
379381
380382 async def _read_notebook (self , os_path , as_version = 4 , capture_validation_error = None ):
381383 """Read a notebook from an os path."""
0 commit comments