Модуль Windows PermissionError & tempfile - PullRequest
0 голосов
/ 11 декабря 2018

Мы используем модуль tempfile для генерации временных файлов и каталогов во время наших тестов.Недавно мы также начали тестирование на Windows и столкнулись с кучей ошибок PermissionErrors.

Сначала я думал, что это может быть из-за того, что Windows, в отличие от Unix, не допускает одновременный доступ к файлу.Когда я посмотрел на код, это происходило даже без одновременного доступа к файлу.

Одна общая нить, казалось, была ошибкой, произошедшей, когда мы использовали структуры модуля tempfile в контексте (с оператором).Ошибка исчезает, когда мы используем ручную попытку-исключение-окончание.

Я работаю над способами исправить это, вышеупомянутая попытка-исключение-окончание также находится на столе.

Кто угодноеще сталкивался с этим или имеет какое-либо понимание?

Это наша тестовая функция (тестирование носа, но я не думаю, что это проблема)

from nibabel.tmpdirs import InTemporaryDirectory
def test_high_level_glm_with_data():
    with InTemporaryDirectory():
        shapes, rk = ((7, 8, 7, 15), (7, 8, 7, 16)), 3
        mask, fmri_data, design_matrices = write_fake_fmri_data(shapes, rk)
        multi_session_model = FirstLevelModel(mask=mask).fit(
            fmri_data, design_matrices=design_matrices)
        z_image = multi_session_model.compute_contrast(
            np.eye(rk)[:2], output_type='z_score')
        variance_image = multi_session_model.compute_contrast(
            np.eye(rk)[:2], output_type='effect_variance')

        assert_array_equal(z_image.get_data() == 0., load(mask).get_data() == 0.)  # no error
        assert_true(
            (variance_image.get_data()[load(mask).get_data() > 0] > .001).all())  # error

Вот обратная связь:

Traceback (most recent call last):
  File "C:\Users\kshit\AppData\Local\conda\conda\envs\nistats-py37-latest\lib\site-packages\nose\case.py", line 197, in runTest
    self.test(*self.arg)
  File "C:\Users\kshit\OneDrive\workspace\nistats-org\nistats-repo\kchawla-pi\nistats\nistats\tests\test_first_level_model.py", line 104, in test_high_level_glm_with_data
    (variance_image.get_data()[load(mask).get_data() > 0] > .001).all())
  File "C:\Users\kshit\AppData\Local\conda\conda\envs\nistats-py37-latest\lib\site-packages\nibabel\tmpdirs.py", line 76, in __exit__
    return super(InTemporaryDirectory, self).__exit__(exc, value, tb)
  File "C:\Users\kshit\AppData\Local\conda\conda\envs\nistats-py37-latest\lib\site-packages\nibabel\tmpdirs.py", line 48, in __exit__
    self.cleanup()
  File "C:\Users\kshit\AppData\Local\conda\conda\envs\nistats-py37-latest\lib\site-packages\nibabel\tmpdirs.py", line 44, in cleanup
    shutil.rmtree(self.name)
  File "C:\Users\kshit\AppData\Local\conda\conda\envs\nistats-py37-latest\lib\shutil.py", line 507, in rmtree
    return _rmtree_unsafe(path, onerror)
  File "C:\Users\kshit\AppData\Local\conda\conda\envs\nistats-py37-latest\lib\shutil.py", line 391, in _rmtree_unsafe
    onerror(os.unlink, fullname, sys.exc_info())
  File "C:\Users\kshit\AppData\Local\conda\conda\envs\nistats-py37-latest\lib\shutil.py", line 389, in _rmtree_unsafe
    os.unlink(fullname)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\kshit\\AppData\\Local\\Temp\\tmpbmgjqk03\\mask.nii'

Если я не использую with InTemporaryDir():, тесты сработают.

1 Ответ

0 голосов
/ 17 декабря 2018

Замена nibabel.tmpdirs.InTemporaryDirectory на Python tempfile.TemporaryDirectory решает проблему.

Возможно, версия Nibabel не закрывает файл перед очисткой?Не уверен, что здесь происходит, это решило мой вопрос.

...