@@ -376,6 +376,15 @@ def install_extension(
376376 ext_path = self .get_dylib_ext_path (ext , module_name )
377377 os .makedirs (os .path .dirname (ext_path ), exist_ok = True )
378378
379+ # Make filenames relative to cwd where possible, to make logs and
380+ # errors below a little neater
381+
382+ cwd = os .getcwd ()
383+ if dylib_path .startswith (cwd ):
384+ dylib_path = os .path .relpath (dylib_path , cwd )
385+ if ext_path .startswith (cwd ):
386+ ext_path = os .path .relpath (ext_path , cwd )
387+
379388 logger .info ("Copying rust artifact from %s to %s" , dylib_path , ext_path )
380389
381390 # We want to atomically replace any existing library file. We can't
@@ -384,11 +393,18 @@ def install_extension(
384393 # This means that any process that currently uses the shared library
385394 # will see it modified and likely segfault.
386395 #
387- # We first copy the file to the same directory, as `os.rename `
396+ # We first copy the file to the same directory, as `os.replace `
388397 # doesn't work across file system boundaries.
389398 temp_ext_path = ext_path + "~"
390399 shutil .copyfile (dylib_path , temp_ext_path )
391- os .replace (temp_ext_path , ext_path )
400+ try :
401+ os .replace (temp_ext_path , ext_path )
402+ except PermissionError as e :
403+ msg = f"{ e } \n hint: check permissions for { ext_path !r} "
404+ if sys .platform == "win32" :
405+ # On Windows, dll files are locked by the system when in use.
406+ msg += "\n hint: the file may be in use by another Python process"
407+ raise CompileError (msg )
392408
393409 if sys .platform != "win32" and not debug_build :
394410 args = []
0 commit comments