Reputation: 13
I'm working on a project for linear optimization with pulp. When I normally "run" the file it work good but I've some problems when I try to convert it into a .exe file with pyinstaller. If I run the .exe file from a command prompt are reported that errors:
Traceback (most recent call last):
File "price.py", line 116, in <module>
File "site-packages\pulp\pulp.py", line 1713, in solve
AttributeError: 'NoneType' object has no attribute 'actualSolve'
[9468] Failed to execute script price
The part of the code I'm having an issue with:
#type of problem
group_division = pulp.LpProblem("Group_division", pulp.LpMinimize)
#objective function to minimize
group_division += objectiveFunction(external_groups, internal_groups)
#specify the maximum number of groups
group_division += sum([x[group] for group in external_groups]) <= max_groups,
"Maximum_number_of_groups"
#every thickness must appear once
for cutType in cutTypes:
group_division += oneCutConstraint(x, y, external_groups, internal_groups, cutType) ==
1,"Must_appear_%s"%cutType
#solve the problem
group_division.solve()
Upvotes: 1
Views: 2009
Reputation: 1
This issue is because once you run pyinstaller, then it does not add the required dependencies for pulp as compared with dependencies of all other packages.
Explicit specification of the path for pulp folder is needed. The folder can be found in the directory where the python environment is installed.
Path for pulp folder can be found inside python path in
Lib/site-packages/pulp
We need to pass path for pulp as an additional argument as follows:
pyinstaller --noconfirm --onefile --console --add-data "C:/Users/.../Lib/site-packages/pulp;pulp/" "C:/Users/.../python_to_exe.py"
Where the first path is for pulp directory and second is for the python code having pulp dependency
Upvotes: 0
Reputation: 864
The solver is available when you use pulp from your python sources, because that solver is the only one that comes with pulp. But when you run pyinstaller, it is no longer available (because you do not explicitly tell pyinstaller to copy it).
When packaging pulp with pyinstaller you need to tell pyinstaller to get the directory with the CBC solver that comes with pulp too. If not, you will only get the python code and then your packaged version will not find the CBC solver.
Assuming you have a config.spec
file for pyinstaller, you have to edit it to something like the following (at least something like this works for me):
import sys
import os
block_cipher = None
def get_pulp_path():
import pulp
return pulp.__path__[0]
path_main = os.path.dirname(os.path.abspath(sys.argv[2]))
a = Analysis(['MAIN_SCRIPT.py'],
pathex=[path_main],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
a.datas += Tree(get_pulp_path(), prefix='pulp', excludes=["*.pyc"])
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(pyz, a.scripts, exclude_binaries=True, name='NAME', debug=False, strip=False, upx=True, console=True)
coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, name='NAME')
And then run
pyinstaller -y config.spec
Upvotes: 1