事象
以下のようにshutil.copytree()
コマンドで、dirs_exist_ok=True
オプションを指定し、かつ同一ディレクトリを指定しまったとき、エラーメッセージが異常に読みにくくなる
import shutil
shutil.copytree('/tmp/dir', '/tmp/dir', dirs_exist_ok=True)
このとき以下のような配列の中に1文字づつ入った読みにくいエラーメッセージになる
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/fetaro/.pyenv/versions/3.12.8/lib/python3.12/shutil.py", line 600, in copytree
return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/fetaro/.pyenv/versions/3.12.8/lib/python3.12/shutil.py", line 554, in _copytree
raise Error(errors)
shutil.Error: ['<', 'D', 'i', 'r', 'E', 'n', 't', 'r', 'y', ' ', "'", 'a', "'", '>', ' ', 'a', 'n', 'd', ' ', "'", '/', 't', 'm', 'p', '/', 'd', 'i', 'r', '/', 'a', "'", ' ', 'a', 'r', 'e', ' ', 't', 'h', 'e', ' ', 's', 'a', 'm', 'e', ' ', 'f', 'i', 'l', 'e', '<', 'D', 'i', 'r', 'E', 'n', 't', 'r', 'y', ' ', "'", 'b', "'", '>', ' ', 'a', 'n', 'd', ' ', "'", '/', 't', 'm', 'p', '/', 'd', 'i', 'r', '/', 'b', "'", ' ', 'a', 'r', 'e', ' ', 't', 'h', 'e', ' ', 's', 'a', 'm', 'e', ' ', 'f', 'i', 'l', 'e']
原因
調べてみると、shutilのソースコードこの部分で「SameFileError」という例外を投げているのだが、
raise SameFileError("{!r} and {!r} are the same file".format(src, dst))
例外の文字列の引数である src
の部分が、文字列ではなく、DirEntry
のオブジェクトになっていることが原因っぽい。
以下のように、例外を補足して変換してあげると、投げたかったエラーメッセージがわかる
import shutil
if __name__ == "__main__":
try:
shutil.copytree('/tmp/dir', '/tmp/dir', dirs_exist_ok=True)
except Exception as e:
print( "".join(e.args[0]))
<DirEntry 'a'> and '/tmp/dir/a' are the same file<DirEntry 'b'> and '/tmp/dir/b' are the same file
教訓
この問題を修正するのは面倒なので、shutil.copytree()するときは、srcとdstが違うことを事前にチェックする。