0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

WindowsでPDMを使ってtorchvisionを入れようとしたらエラーで怒られてしまった人へ

Last updated at Posted at 2021-11-26

はじめに

Windowsでpdm add torchvisionしようとしたら

assert record is not None, "In {}, {} is not mentioned in RECORD".format(
AssertionError: In C:\Users\hoge\AppData\Local\Temp\pip-unpack-XXXXXXXX\torchvision-0.11.1-cp39-cp39-win_amd64.whl, torchvision-0.11.1.dist-info/LICENSE is not mentioned in RECORD

とassertが出てインストールできなかった。本稿では何とかしてインストールするための方法を紹介する。

実行環境

OS: Windows 10 Pro (19044.1348)
pdm: version 1.10.3
pyenv-win: version 2.64.11
Python: version 3.9.6

エラーの再現方法

  1. $mkdir tmp で空のディレクトリを作成する。
  2. powershellを開いて、上で作成したディレクトリをカレントディレクトリにする。
  3. powershellのコンソールに$pdm initを入力しenter。この時聞かれるパッケージの初期設定については、Please enter the Python interpreter to use に対してはpyenv-winのpython 3.9.6を選択し、他の設定はデフォルトを選択する(何も入力せずにenter)。
  4. $pdm add torchvision==0.11.1を入力する。

出力されるエラーメッセージ

ERRORS:
add torchvision failed:
Traceback (most recent call last):
  File "C:\Users\hoge\scoop\apps\pyenv\current\pyenv-win\versions\3.9.6\lib\concurrent\futures\thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "C:\Users\hoge\AppData\Roaming\pdm\venv\lib\site-packages\pdm\installers\synchronizers.py", line 190, in install_candidate
    self.manager.install(can)
  File "C:\Users\hoge\AppData\Roaming\pdm\venv\lib\site-packages\pdm\installers\manager.py", line 38, in install
    installer(candidate.build(), self.environment, candidate.direct_url())
  File "C:\Users\hoge\AppData\Roaming\pdm\venv\lib\site-packages\pdm\installers\installers.py", line 124, in install_wheel_with_cache
    dist_info_dir = _install_wheel(
  File "C:\Users\hoge\AppData\Roaming\pdm\venv\lib\site-packages\pdm\installers\installers.py", line 176, in _install_wheel
    for record_elements, stream in source.get_contents():
  File "C:\Users\hoge\AppData\Roaming\pdm\venv\lib\site-packages\installer\sources.py", line 170, in get_contents
    assert record is not None, "In {}, {} is not mentioned in RECORD".format(
AssertionError: In C:\Users\hoge\AppData\Local\Temp\pip-unpack-XXXXXXXX\torchvision-0.11.1-cp39-cp39-win_amd64.whl, torchvision-0.11.1.dist-info/LICENSE is not mentioned in RECORD

See C:\Users\hoge\AppData\Local\Temp\pdm-install-XXXXXXXXX.log for detailed debug log.
[InstallationError]: Some package operations are not complete yet
Add '-v' to see the detailed traceback

エラーの原因

エラーメッセージの下の方を見てみると、

File "C:\Users\hoge\AppData\Roaming\pdm\venv\lib\site-packages\installer\sources.py", line 170, in get_contents
    assert record is not None, "In {}, {} is not mentioned in RECORD".format(
AssertionError: In C:\Users\hoge\AppData\Local\Temp\pip-unpack-XXXXXXXX\torchvision-0.11.1-cp39-cp39-win_amd64.whl, torchvision-0.11.1.dist-info/LICENSE is not mentioned in RECORD

とある。C:\Users\hoge\AppData\Roaming\pdm\venv\lib\site-packages\installer\sources.pyを見てみると、エラーの発生個所は以下の関数らしい。

source.pyの152行目~
    def get_contents(self):
        # type: () -> Iterator[WheelContentElement]
        """Sequential access to all contents of the wheel (including dist-info files).

        This implementation requires that every file that is a part of the wheel
        archive has a corresponding entry in RECORD. If they are not, an
        :any:`AssertionError` will be raised.
        """
        # Convert the record file into a useful mapping
        record_lines = self.read_dist_info("RECORD").splitlines()
        records = installer.records.parse_record_file(record_lines)
        record_mapping = {record[0]: record for record in records}

        for item in self._zipfile.infolist():
            if item.filename[-1:] == "/":  # looks like a directory
                continue

            record = record_mapping.pop(item.filename, None)
            assert record is not None, "In {}, {} is not mentioned in RECORD".format(
                self._zipfile.filename,
                item.filename,
            )  # should not happen for valid wheels

            with self._zipfile.open(item) as stream:
                stream_casted = cast("BinaryIO", stream)
                yield record, stream_casted

この関数はPDMが内部で使っているinstallerというパッケージのものらしい。この関数の説明文によると、この関数はインストールしようとしたwheelに含まれている各ファイルが、whlのdist-infoのRECORDに書いてあることを確認し、書いてなかったら先のエラーを出すらしい。

先のエラーを見直すと、AssertionError: In C:\Users\hoge\AppData\Local\Temp\pip-unpack-XXXXXXXX\torchvision-0.11.1-cp39-cp39-win_amd64.whl, torchvision-0.11.1.dist-info/LICENSE is not mentioned in RECORDとあり、torchvision-0.11.1.dist-info/LICENSEがRECORDに書いてないらしい。1

本当に書いていないことを確かめるため、torchvisionのpypiからtorchvision-0.11.1-cp39-cp39-win_amd64.whlをダウンロードして、unzipしてみる。unzipしたファイルのtorchvision-0.11.1.dist-info/RECORDを見てみると、121行目にtorchvision-0.11.1.dist-info\LICENSEとある。一方で、上のエラーメッセージではtorchvision-0.11.1.dist-info/LICENSE is not mentioned in RECORDと書いてあった。確かにtorchvision-0.11.1.dist-info/LICENSEはRECORDに記載されていないものの、ディレクトリ区切り文字が異なるtorchvision-0.11.1.dist-info\LICENSEが記載されている。ということで、RECORDに記載されているパス(torchvision-0.11.1.dist-info\LICENSE)と、wheelに含まれているファイルのパス(torchvision-0.11.1.dist-info/LICENSE)の区切り文字が異なってしまうことがエラーの原因らしい。

エラーの回避方法

回避方法の方針としては、RECORDとinstallerのディレクトリ区切り文字を一致させてやれば良さそうである。そのための雑な方法として、

sources.pyの161行目
record_lines = self.read_dist_info("RECORD").splitlines()

sources.pyの161行目
record_lines = [ line.replace("\\", "/") for line in self.read_dist_info("RECORD").splitlines()]

に置換する。self.read_dist_info("RECORD").splitlines()の返り値はRECORDファイルの各行が入っているリストで、[ line.replace("\\", "/") for line in self.read_dist_info("RECORD").splitlines()]はRECORDの各行の\/に置換したものである。

この方法だと、Pathだけでなく、RECORDに含まれる各ファイルのハッシュも置換してしまう。セキュリティ的にまずいはずなので、パスのみを置換の範囲にするべきです。

  1. RECORDが何なのかというと、"RECORD is a list of (almost) all the files in the wheel and their secure hashes. Unlike PEP 376, every file except RECORD, which cannot contain a hash of itself, must include its hash. The hash algorithm must be sha256 or better; specifically, md5 and sha1 are not permitted, as signed wheel files rely on the strong hashes in RECORD to validate the integrity of the archive." らしい。PEP 427より。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?