"WinError 32" after doing run_setup to find out package metadata

Issue

I’m using Python 3.6.1 on a Windows dev environment without any admin rights. I have a Python program which does the following:

  1. Create temporary directory using tempfile.mkdtemp()
  2. Clone a Git repo into it
  3. Build the code in the Git repo into a Python wheel
  4. Install the wheel into a target Python venv
  5. Delete the temporary directory using shutil.rmtree()

In the 5th step (removing the tempdir) I keep getting the error:

PermissionError: [WinError 32] The process cannot access the file 
    because it is being used by another process: <path of tmpdir>

Note that this error message seems to concern removing the directory, not any specific file within it.

After many thankless hours of debugging I think the following line which the script has to do as part of the 3rd step seems to cause it:

def get_metadata(path_to_setup_py):
    return distutils.core.run_setup(path_to_setup_py, stop_after='init').metadata

I am getting package metadata simulating the app setup by using run_setup(), but I think the function fails to close file handles or something, leading to above error.

I read the source code for run_setup but it’s not really intelligible to me. I think what is happening is that the exec() actually runs the complete setup.py, but calls to setup() are re-routed into the current process so data can be shared using the global variables _setup_stop_after and _setup_distribution.

Either way I cannot see why "another process" would keep a file/directory lock as the exec() should be happening inside the current process!? Note that after the script exits the tempdir is empty and I can remove it no-problem.

Solution

Well, I guess I just needed to type this question out to immediately get an idea for the answer. Immediately before removing the tree I printed out the current working directory:

print(os.getcwd())
shutil.rmtree(tmpdir)

And I realized that it was the directory I wanted to delete, I assume this is a side effect of run_setup. The solution is to simply change the directory before deleting it!

os.chdir(r'C:\Temp')
shutil.rmtree(tmpdir)

Answered By – xjcl

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published