MacOS Mojave & Python3.7 でTensorflow環境構築しようとして詰まった話

# 前提
MacOS 10.14 Mojave
python 3.7.0

基本的には<a href=https://qiita.com/tom_ato/items/bbdf4574b3ecb0048fa1>「Python3 TensorFlow for Mac 環境構築」</a>の記事（python 3.6.0）のやり方を参考にpython3.7で構築しようとしてつまずいて調べたことをまとめておきます。

# 先に結論
記事を書いておいてアレなんですが、現時点（2018/10/13）で**python 3.7に正式に対応できているTensorflowのpipパッケージはまだ追いついてないようです。。**一応強引な回避策もあるにはあるようなのでそちらも書いておきます。

MacOS 10.14 Mojave
MacOS 10.13 High Sierra
をお使いの方は<a href=https://qiita.com/nahshi/items/fcf4898f7c45f11a5c63#1-pyenv-install-%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BC>「1. pyenv install でエラー」</a>の項のみ参考にしてください。

**普通に構築されたい方は素直にpythonを3.6にダウングレードして、対応するpipのtensorflowパッケージでインストールすることを推奨します！**（ちなみにTensorflowのissueで3.6.6でも本記事<a href=https://qiita.com/nahshi/items/fcf4898f7c45f11a5c63#3-tensorflow%E3%81%AEimport%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BC>「3. TensorFlowのimportでエラー」</a>と同様の現象が起きるとの投稿もあったので3.6.0でやるのが無難かと思います。）

# 1. pyenv install でエラー
### 問題
`pyenv install 3.7.0`でインストール時に下記のエラーが発生

```
$ pyenv install 3.7.0
python-build: use openssl from homebrew
python-build: use readline from homebrew
Downloading Python-3.7.0.tar.xz...
-> https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tar.xz
Installing Python-3.7.0...
python-build: use readline from homebrew

BUILD FAILED (OS X 10.14 using python-build 20180424)

Inspect or clean up the working tree at /var/folders/8t/k8ysfq2x42jgmgt2krg63k9h0000gn/T/python-build.20181012224040.19418
Results logged to /var/folders/8t/k8ysfq2x42jgmgt2krg63k9h0000gn/T/python-build.20181012224040.19418.log

Last 10 log lines:
  File "/private/var/folders/8t/k8ysfq2x42jgmgt2krg63k9h0000gn/T/python-build.20181012224040.19418/Python-3.7.0/Lib/ensurepip/__main__.py", line 5, in <module>
    sys.exit(ensurepip._main())
  File "/private/var/folders/8t/k8ysfq2x42jgmgt2krg63k9h0000gn/T/python-build.20181012224040.19418/Python-3.7.0/Lib/ensurepip/__init__.py", line 204, in _main
    default_pip=args.default_pip,
  File "/private/var/folders/8t/k8ysfq2x42jgmgt2krg63k9h0000gn/T/python-build.20181012224040.19418/Python-3.7.0/Lib/ensurepip/__init__.py", line 117, in _bootstrap
    return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
  File "/private/var/folders/8t/k8ysfq2x42jgmgt2krg63k9h0000gn/T/python-build.20181012224040.19418/Python-3.7.0/Lib/ensurepip/__init__.py", line 27, in _run_pip
    import pip._internal
zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1
```

`xcode-select --install`は実施済だしzlibやxzをインストールしても同じエラーは出続けました。

### 解決策
<a href=https://medium.com/@digitalnauts/pyenv-install-error-mac-dcbd28fdc9db>こちらのサイト</a>で全く同じ現象について書かれており解決。
pyenvの前に下記の環境変数の設定が必要ということでした。

```
CFLAGS="-I$(brew --prefix readline)/include -I$(brew --prefix openssl)/include -I$(xcrun --show-sdk-path)/usr/include" \
LDFLAGS="-L$(brew --prefix readline)/lib -L$(brew --prefix openssl)/lib" \
PYTHON_CONFIGURE_OPTS=--enable-unicode=ucs2
```

<a href=https://github.com/pyenv/pyenv/pull/1025>pyenvのissue</a>も漁った感じ、**macOS 10.13（High Sierra）以降**でこの現象が起きてるようです。OpenSSLなどのライブラリを見つけられていないっぽい。（今回参考にさせて頂いた記事ではmacOS 10.12だったのでギリギリ起きなかった？）

# 2. pip3 install --upgrade tensorflow でエラー
### 問題
pipでtensorflowをインストールしようとすると下記のようにエラーに。

```
$ pip3 install --upgrade tensorflow
Collecting tensorflow
  Could not find a version that satisfies the requirement tensorflow (from versions: )
No matching distribution found for tensorflow
```

### 解決策
調べたところ、<a href=https://www.haneca.net/python3-7-tensorflow-install-error-on-mac/>こちらのサイト</a>が参考になりました。MacのPython3.7に対応させたTensorflowのインストールパッケージをURLで直接指定する必要があるようです。最新は1.10.1だったのでそちらを指定

```
$ pip3 install --upgrade https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.10.1-py3-none-any.whl
```

# 3. TensorFlowのimportでエラー
### 問題
```
$ python
Python 3.7.0 (default, Oct 12 2018, 22:42:02)
[Clang 10.0.0 (clang-1000.10.44.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/User/.pyenv/versions/TensorFlow/lib/python3.7/site-packages/tensorflow/__init__.py", line 22, in <module>
    from tensorflow.python import pywrap_tensorflow  # pylint: disable=unused-import
  File "/Users/User/.pyenv/versions/TensorFlow/lib/python3.7/site-packages/tensorflow/python/__init__.py", line 49, in <module>
    from tensorflow.python import pywrap_tensorflow
  File "/Users/User/.pyenv/versions/TensorFlow/lib/python3.7/site-packages/tensorflow/python/pywrap_tensorflow.py", line 58, in <module>
    from tensorflow.python.pywrap_tensorflow_internal import *
  File "/Users/User/.pyenv/versions/TensorFlow/lib/python3.7/site-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 114
    def TFE_ContextOptionsSetAsync(arg1, async):
                                             ^
SyntaxError: invalid syntax
```

### 原因
<a href=https://github.com/tensorflow/tensorflow/issues/20690#issuecomment-410513792>Tensorflowのissue</a>を読むと、`async`はpython3.7では予約語なのでエラーになるそうです。現時点（2018/10/13）でもまだ新しいバージョンは出ていないようでした。。


### 回避策？
一応こうしたら動く的なことが<a href=https://github.com/tensorflow/tensorflow/issues/20690#issuecomment-410513792>issue</a>に書いてあったのでそれを試してみました。
**（素直にpythonを3.6にダウングレードして対応したpipのtensorflowパッケージでインストールすることを推奨します!）**

要はエラーメッセージで原因となっている、python3.7で予約語の`async`を何か適当な別名(`async1`とか)に変えてあげるというだけの対応。
1.10.1では**114〜115,154〜155行目**　に例の　`async`がいるので置換。

```
def TFE_ContextOptionsSetAsync(arg1, async1):
    return _pywrap_tensorflow_internal.TFE_ContextOptionsSetAsync(arg1, async1)
TFE_ContextOptionsSetAsync = _pywrap_tensorflow_internal.TFE_ContextOptionsSetAsync
```

```
def TFE_ContextSetAsyncForThread(arg1, async1):
    return _pywrap_tensorflow_internal.TFE_ContextSetAsyncForThread(arg1, async1)
TFE_ContextSetAsyncForThread = _pywrap_tensorflow_internal.TFE_ContextSetAsyncForThread
```

一応動いた！

```
>>> import tensorflow as tf
/Users/User/.pyenv/versions/TensorFlow/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: compiletimeversion 3.6 of module 'tensorflow.python.framework.fast_tensor_util' does not match runtime version 3.7
  return f(*args, **kwds)
>>> hello = tf.constant('Hello, TensorFlow!')
>>> sess = tf.Session()
2018-10-13 00:30:37.765746: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
>>> print(sess.run(hello))
b'Hello, TensorFlow!'
```

警告が出てますけど、そちらは<a href=https://qiita.com/KEINOS/items/4c66eeda4347f8c13abb>「macOS で「this TensorFlow binary was not compiled to use: AVX2 FMA」エラー」</a>の記事にあるようにスルーして大丈夫っぽいです。