PyCharmから実行したときだけスクリプトが動かない場合

Python用のIDEとして名高いPyCharmをようやく導入したのですが、さっそく変なところで躓いたのでメモ。
結果から言えば、実行環境のPythonが同じでも、シェルのパスがPyCharm実行では異なることが原因でした。

問題

Pyomoという数理最適化モデルのモジュールを使ったPythonスクリプトの実行時に問題は発生しました。
スクリプトをターミナルでpython hogehoge.pyのように実行したときには何も問題なく動くにも関わらず、PyCharmから^Rで実行するとエラーが出ます。
実行環境はvirtualenvで仮想化したものですが、PyCharmでも同じ仮想環境を指定して実行しています。

実際のコードは以下の通り。

# -*- coding: utf-8 -*-
import pyomo.environ as pm
import pyomo.opt as opt

model = pm.AbstractModel()
model.m = 1
model.n = 2

model.I = pm.RangeSet(1, model.m)
model.J = pm.RangeSet(1, model.n)

a_init = {(1,1):3, (1,2):4}
b_init = {1:1}
c_init = {1:2, 2:3}

model.a = pm.Param(model.I, model.J, initialize=a_init)
model.b = pm.Param(model.I, initialize=b_init)
model.c = pm.Param(model.J, initialize = c_init)

model.x = pm.Var(model.J, domain=pm.NonNegativeReals)

def obj_expression(model):
    return pm.summation(model.c, model.x)

model.OBJ = pm.Objective(rule=obj_expression)

def ax_constant_rule(model, i):
    return sum(model.a[i,j] * model.x[j] for j in model.J) >= model.b[i]

model.AxbConstraint = pm.Constraint(model.I, rule=ax_constant_rule)

instance = model.create_instance()

solver = opt.SolverFactory("glpk")
result = solver.solve(instance)

print(result)

ターミナルでの実行時の出力

Problem:
- Name: unknown
  Lower bound: 0.666666666666667
  Upper bound: 0.666666666666667
  Number of objectives: 1
  Number of constraints: 2
  Number of variables: 3
  Number of nonzeros: 3
  Sense: minimize
Solver:
- Status: ok
  Termination condition: optimal
  Statistics:
    Branch and bound:
      Number of bounded subproblems: 0
      Number of created subproblems: 0
  Error rc: 0
  Time: 0.005264997482299805
Solution:
- number of solutions: 0
  number of solutions displayed: 0

何も問題なしです。

PyCharmでの実行時の出力

Traceback (most recent call last):
  File "/Users/Kiichi/Dropbox/prog/python/pyomo_opt/pyomo_test.py", line 60, in <module>
    result = solver.solve(instance)
WARNING: "[base]/site-packages/pyomo/solvers/plugins/solvers/GLPK_old.py", 68, _default_executable
  File "/Users/Kiichi/.virtualenvs/opt/lib/python3.5/site-packages/pyomo/opt/base/solvers.py", line 501, in solve
    Could not locate the 'glpsol' executable, which is required for solver 'glpk'
    self.available(exception_flag=True)
  File "/Users/Kiichi/.virtualenvs/opt/lib/python3.5/site-packages/pyomo/opt/solver/shellcmd.py", line 121, in available
    raise ApplicationError(msg % self.name)
pyutilib.common._exceptions.ApplicationError: No executable found for solver 'glpk'

Process finished with exit code 1

エラー。ソルバーであるglpkが見つからないようです。

解決策

Pythonはどちらも同じ仮想環境を指定しているので、残る原因としてはシェルが考えられます。
そこで以下をPyCharm上で実行。

import os
print(os.system("echo $PATH"))

#出力: /usr/bin:/bin:/usr/sbin:/sbin:/Users/Kiichi/.virtualenvs/opt/bin

どうやらPyCharmはPythonスクリプトを実行する際に普段のシェルのパスを引き継がないようです。
ソルバーglpkの実行コマンドであるglpsolはHomebrewでインストールすると/usr/local/bin/の中にあるので、PyCharmから実行した場合にパスが通ってなかったわけです。
したがって、上の出力を参考に仮想環境の中のbinフォルダにglpsolのシンボリックリンクを置いてやれば解決します。
今回の私の例なら

$ln -s /usr/local/bin/glpsol /Users/Kiichi/.virtualenvs/opt/bin/glpsol

でOKです。

無事、PyCharm上でもPythonスクリプトが思う通りに動いてくれるようになりました。