LoginSignup
3
0

More than 3 years have passed since last update.

macOS+pyenvでpypy3.6-7.3.1をインストールできなかったがpypy3.6-7.3.0はインストールできた。モンテカルロ法でpypyの風を感じた。

Last updated at Posted at 2020-08-22

まとめ

  • pyenv で pypy をインストールしようとすると 403エラーが返ってきた
    • pyenv の更新により、この問題を解決できた
  • しかし、pypy3.6-7.3.1 はインストールできなかった (未解決issueに行き当たった)
  • 他方で、pypy3.6-7.3.0 をインストールすることはできた
  • おまけ: pypy で円周率を計算させたところ、CPython と比較して約4.7倍速く動作した (簡易的な実験のみ実施)

第一の現象: pyenv で pypy をインストールしようとすると 403 エラーが返ってくる

pyenv で pypy3.6-7.3.1 をインストールしようとしたところ、エラーメッセージが表示され、インストールに失敗した。

% pyenv install -v pypy3.6-7.3.1
/var/folders/fv/495qgk712lg73r5dxmr83mhh0000gn/T/python-build.20200822165404.41441 ~/work
Downloading pypy3.6-v7.3.1-osx64.tar.bz2...
-> https://bitbucket.org/pypy/pypy/downloads/pypy3.6-v7.3.1-osx64.tar.bz2
curl: (22) The requested URL returned error: 403
error: failed to download pypy3.6-v7.3.1-osx64.tar.bz2

BUILD FAILED (OS X 10.15.6 using 0000000000)

前提環境

  • macOS Catalina 10.15.6
  • pyenv 1.2.20

原因

pyenvが参照するmacOS用のアーカイブファイルのURLから、403エラーが返ってくること。

Downloading pypy3.6-v7.3.1-osx64.tar.bz2...
-> https://bitbucket.org/pypy/pypy/downloads/pypy3.6-v7.3.1-osx64.tar.bz2
curl: (22) The requested URL returned error: 403

これは、BitbucketがMercurialのサポートをやめ、2020年7月8日以降、リポジトリの中身にアクセスできなくなったから。

解決策

pyenvの最新ソースコードを利用すれば良い。なぜなら、この記事執筆時点の2日前 (2020/08/20) に、問題が修正されているから。以下のプルリクエストを参照:

brewでpyenvをインストールしている場合

  • pyenvの更新版リリースを待つ
  • もしくは、pyenvをGitHubから直接インストールする

ここでは、brewでインストールしたpyenvを消去し、GitHubからの直接インストール方式に変更する手順を説明する。

pyenvインストール方法の移行: brewからGitHubへ

まず、pyenv の root ディレクトリが ~/.pyenv にあることを確認しておく。(以下の手順は、このパスに root ディレクトリが存在することを前提に記載している。)

% pyenv root
/Users/snjot/.pyenv

brew uninstall で pyenv をシステムから削除する。

% brew uninstall pyenv
Uninstalling /usr/local/Cellar/pyenv/1.2.20... (708 files, 2.5MB)

あとは、Basic GitHub Checkout 記載の手順を実施すれば良い。

ただし、brew版pyenvが作成した ~/.pyenv ディレクトリが残っているため、そのままだと手順通りに git clone できない。そこで、手順 "1. Check out pyenv where you want it installed." に一工夫加える。以下のようにすると良い:

  • その1. .git ディレクトリの移植
% git clone https://github.com/pyenv/pyenv.git ~/.pyenv-temp
Cloning into '/Users/snjot/.pyenv-temp'...
remote: Enumerating objects: 123, done.
remote: Counting objects: 100% (123/123), done.
remote: Compressing objects: 100% (121/121), done.
remote: Total 18256 (delta 106), reused 5 (delta 0), pack-reused 18133
Receiving objects: 100% (18256/18256), 3.65 MiB | 2.80 MiB/s, done.
Resolving deltas: 100% (12440/12440), done.
% mv ~/.pyenv-temp/.git ~/.pyenv/.git
% rm -rf ~/.pyenv-temp
  • その2. .git からのファイル復元
% cd ~/.pyenv
% git reset HEAD --hard
HEAD is now at dc4e24e6 Fix PyPy download links (#1682)

残りは公式手順を参照。

最後に、正しくインストールできているか確認しておくと安心です。

% pyenv --version
pyenv 1.2.20-2-gdc4e24e6

GitHubから直接インストールしている場合

pyenvのバージョンを更新し、dc4e24e 以降のものを使う。

公式手順に沿って更新すれば良い。参考までに、以下にコマンドを転記しておく:

cd $(pyenv root)
git pull

第二の現象: 403エラー解決後もビルドエラーが出て pypy3.6-7.3.1 をインストールできない

解決策実施後に、pypy3.6-7.3.1 をインストールしようとして、以下のエラーに遭遇した:

% pyenv install pypy3.6-7.3.1
Downloading pypy3.6-v7.3.1-osx64.tar.bz2...
-> https://downloads.python.org/pypy/pypy3.6-v7.3.1-osx64.tar.bz2
Installing pypy3.6-v7.3.1-osx64...
/Users/snjot/.pyenv/plugins/python-build/bin/python-build: line 1590: 44564 Abort trap: 6           "$PYTHON_BIN" -c "import $1" > /dev/null 2>&1
WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?
/Users/snjot/.pyenv/plugins/python-build/bin/python-build: line 1590: 44565 Abort trap: 6           "$PYTHON_BIN" -c "import $1" > /dev/null 2>&1
WARNING: The Python readline extension was not compiled. Missing the GNU readline lib?
/Users/snjot/.pyenv/plugins/python-build/bin/python-build: line 1599: 44566 Abort trap: 6           "$PYTHON_BIN" -c "import $1" > /dev/null 2>&1
ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems

調査したところ、未解決issueに行き着いたため、pypy3.6-7.3.1 のインストールを断念した。

なお、ひとつ手前のバージョン pypy3.6-7.3.0 のインストールには、成功した。

% pyenv install pypy3.6-7.3.0
Downloading pypy3.6-v7.3.0-osx64.tar.bz2...
-> https://downloads.python.org/pypy/pypy3.6-v7.3.0-osx64.tar.bz2
Installing pypy3.6-v7.3.0-osx64...
Installed pypy3.6-v7.3.0-osx64 to /Users/snjot/.pyenv/versions/pypy3.6-7.3.0

調査内容

まずは、画面に出力された指示に従い、以下のURLを確認した:

Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems

そして、Prerequisitesを満たしているか確認した。筆者の場合、Prerequisitesを満たしていた。

次に、上記 URL に記載されている解決策を一通り試した。しかし、問題は解決しなかった。

pypy3.6-7.3.1 に特殊な問題なのかどうか調べるため、以下コマンドで pypy3.6-7.3.0 をインストールしたところ、問題なくインストールできた。

% pyenv install pypy3.6-7.3.0
Downloading pypy3.6-v7.3.0-osx64.tar.bz2...
-> https://downloads.python.org/pypy/pypy3.6-v7.3.0-osx64.tar.bz2
Installing pypy3.6-v7.3.0-osx64...
Installed pypy3.6-v7.3.0-osx64 to /Users/snjot/.pyenv/versions/pypy3.6-7.3.0

pyenv の GitHub リポジトリを確認し、issues を検索したところ、同様の問題が見つかった:

記事執筆時点では未解決 issue であるため、pypy3.6-v7.3.1 のインストールを断念した。

Hello, pypy!

pypy3.6-7.3.0 を導入できたので、動かしてみた。

% pyenv shell pypy3.6-7.3.0
% python
Python 3.6.9 (1608da62bfc7, Dec 23 2019, 10:50:17)
[PyPy 7.3.0 with GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>>

ちゃんと動いている :thumbsup:

おまけ: 円周率を計算させてpypyの風を感じる

せっかくなので、モンテカルロ法による円周率の近似計算で、pypyの速さを感じてみました。pypy の方が 4.7 倍ほど速く動きました。すばらしいですね。

コード

import math
import random
import time
from typing import List, Tuple


def generate_random_point2d() -> Tuple[float, float]:
    return (random.random(), random.random())


def generate_multiple_random_points2d(num_samples: int) -> List[Tuple[float, float]]:
    points = []
    for _ in range(num_samples):
        points.append(generate_random_point2d())
    return points


def calculate_l2norm(point2d: Tuple[float, float]) -> float:
    return math.sqrt(point2d[0] ** 2 + point2d[1] ** 2)


def count_points_within_quadrant(l2norms: List[float]) -> int:
    num_points = 0
    for l in l2norms:
        if l <= 1:
            num_points += 1
    return num_points


def calculate_pi(num_samples: int) -> float:
    points = generate_multiple_random_points2d(num_samples)
    l2norms = [calculate_l2norm(p) for p in points]
    num_points_within_quadrant = count_points_within_quadrant(l2norms)
    pi = 4 * num_points_within_quadrant / num_samples
    return pi


if __name__ == "__main__":
    random.seed(0, version = 2)

    tic = time.time()
    pi = calculate_pi(10_000_000)
    tac = time.time()

    print(f"pi = {pi}; ({tac - tic} sec)")

こちらのGitHubリポジトリにコードを公開しています。

簡易実験

まず、pypyで実行:

% python -m pimonte
pi = 3.1413028; (1.8637058734893799 sec)

次に、CPythonで同じコードを実行:

% python -m pimonte
pi = 3.1413028; (8.742990016937256 sec)

計算に要した時間を比較すると、pypy が CPython の 4.69 倍速く計算できていました。

簡易的な実験なので、考察は省きます。

みなさんも、pypy の速さを感じてみてください。以上!

3
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
3
0