@@ -376,6 +376,15 @@ def install_extension(
376
376
ext_path = self .get_dylib_ext_path (ext , module_name )
377
377
os .makedirs (os .path .dirname (ext_path ), exist_ok = True )
378
378
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
+
379
388
logger .info ("Copying rust artifact from %s to %s" , dylib_path , ext_path )
380
389
381
390
# We want to atomically replace any existing library file. We can't
@@ -384,11 +393,18 @@ def install_extension(
384
393
# This means that any process that currently uses the shared library
385
394
# will see it modified and likely segfault.
386
395
#
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 `
388
397
# doesn't work across file system boundaries.
389
398
temp_ext_path = ext_path + "~"
390
399
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 )
392
408
393
409
if sys .platform != "win32" and not debug_build :
394
410
args = []
0 commit comments