проблема с shutil.move
в Windows заключается в том, что он не обрабатывает случай, когда:
- источник и место назначения не на одном диске И
- некоторые файлы в исходном каталоге защищены от записи.
Если оба условия соблюдены, shutil.move
не может выполнить os.rename
, он должен:
- скопировать файлы (что не проблема)
- удалить исходные файлы (что является проблемой из-за ограничения
shutil
)
Чтобы исправить это, я сделал себе копию модуля shutil
(под другим именем) и добавил эту строку (для вас это будет прямо перед строкой 250):
os.chmod(fullname,0o777) # <-- add that line
os.remove(fullname) # some versions have "unlink" instead
Функция rmtree
имеет ту же проблему в Windows.
В Linux этого не происходит, поскольку разрешения на удаление файлов обрабатываются не на уровне файлов, а на уровне каталогов. На окнах это не работает таким образом. Добавление os.chmod
делает свое дело (даже если это взлом), и os.remove
успешно (если файл не открыт в Word или что-то еще)
Обратите внимание, что shutil
авторы рекомендуют вам копировать и улучшать функции. Также примечание из документации shutil.move
:
Здесь можно сделать гораздо больше ... Взгляд на mv.c показывает, что
проблемы, которые затмевает эта реализация.
Если вы не хотите изменять shutil
, вы можете запустить рекурсивный chmod
для исходных файлов, чтобы убедиться, что shutil.move
будет работать, например, так:
for root, dirs, files in os.walk(path):
for f in dirs+files:
os.chmod(os.path.join(root, f), 0o777)
Вы также можете использовать shutil.copytree
, а затем модифицированную версию shutil.rmtree
(поскольку вы знаете , что source & dest не находятся в одной файловой системе)