pyinstaller / pyinstaller

Freeze (package) Python programs into stand-alone executables
http://www.pyinstaller.org
Other
11.84k stars 1.94k forks source link

No such file or directory: with ciscoconfparse library #3552

Closed kochargs closed 6 years ago

kochargs commented 6 years ago

I created an .exe of my python code using pyinstaller and it was working fine. But after importing this specific package "from ciscoconfparse import CiscoConfParse ", pyinstaller is able to create the .exe but when i execute the .exe it throws an error message

Please see this link for screenshot. https://i.stack.imgur.com/ajuxd.png

I tried to do the workaround as mentioned in some other posts but none seem to work and this problem is seen only when i use ciscoconfparse module.

Please help how can i get around this problem, it is important to use this module.

tallforasmurf commented 6 years ago

It is possible to copy and paste text from a console window, please do that instead of posting a screen shot which cannot be searched and is hard to read. However in this case it seems obvious that this CiscoConfParse module is trying to open a data file, ciscoconfparse\version that it expects must exist. There is no way that PyInstaller could tell, from the source, that such a file should be included. You have to find out where that is in the original distribution, and tell PyInstaller to include it, see the docs on adding data files.

kochargs commented 6 years ago

Thanks for your help, i am able to locate the version file in site-packages/ciscoconfparse However, as i understood to include the version in .exe, i have to add an arguement to .spec file

  1. I created a spec file using pyi-makespec --onefile name.py

  2. Modified the data field in spec file to

a = Analysis(['RR Config Scrub_v1.py'], pathex=['C:\Python27\Scripts'], binaries=[], datas=['C:\Python27\Lib\site-packages\ciscoconfparse\version'],

  1. Build exe again using pyinstaller --onefile "RR Config Scrub_v1.spec"

If the above steps are correct, i am still getting now while creating the .exe

pyinstaller --onefile "RR Config Scrub_v1.spec"14160 INFO: Appending 'datas' from .spec Traceback (most recent call last): File "C:\Python27\Scripts\pyinstaller-script.py", line 11, in load_entry_point('PyInstaller==3.3.1', 'console_scripts', 'pyinstaller')() File "c:\python27\lib\site-packages\PyInstaller__main.py", line 94, in run run_build(pyi_config, spec_file, vars(args)) File "c:\python27\lib\site-packages\PyInstaller__main__.py", line 46, in run_build PyInstaller.building.build_main.main(pyi_config, spec_file, kwargs) File "c:\python27\lib\site-packages\PyInstaller\building\build_main.py", line 791, in main build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build')) File "c:\python27\lib\site-packages\PyInstaller\building\build_main.py", line 737, in build exec(text, spec_namespace) File "", line 16, in File "c:\python27\lib\site-packages\PyInstaller\building\build_main.py", line 224, in init__ for name, pth in format_binaries_and_datas(datas, workingdir=spec_dir): File "c:\python27\lib\site-packages\PyInstaller\building\utils.py", line 472, in format_binaries_and_datas for src_root_path_or_glob, trg_root_dir in binaries_or_datas: ValueError: too many values to unpack

kochargs commented 6 years ago

The console dies in a split second and i could only manage to take a screenshot. Does it appear to you as if pyinstaller is creating a temp folder under Appdata\Local\Temp\ciscoconfparse and trying to read/write version file to it but is unable to do so.

Could you please guide how to proceed with manually adding data files to pyinstaller ?

Thanks

tallforasmurf commented 6 years ago

You have missed one important point, which is that each added data file is a tuple with two items, the source path and the destination folder.

datas=[  (  'C:\Python27\Lib\site-packages\ciscoconfparse\version', 'ciscoconfparse' ) ],

Also for easy experimenting it is simpler to use the command line option --add-data instead of modifying the spec file. In this case, I think what would work is

pyinstaller --clean -y --onefile --add-data "C:\Python27\Lib\site-packages\ciscoconfparse\version:ciscoconfparse" "RR Config Scrub_v1.py"

but I can't test either of these.

kochargs commented 6 years ago

14601 INFO: Appending 'datas' from .spec Unable to find "C:\Python27\Lib\site-packages\ciscoconfparse♂ersion" when adding binary and data files.

I get this as error when creating .exe using the above command. Notice the strange symbol in version "ciscoconfparse♂ersion"

Why does windows show this strange symbol when i can confirm the version file is located under "C:\Python27\Lib\site-packages\ciscoconfparse" so the actual path becomes

C:\Python27\Lib\site-packages\ciscoconfparse\version

kochargs commented 6 years ago

Thanks a lot @tallforasmurf, It is working now, what i did was instead of adding ciscoconfparse\version, i added ciscoconfparse* and it did the trick.

datas=[ ( 'C:\Python27\Lib\site-packages\ciscoconfparse*', 'ciscoconfparse' ) ],

This got it working. thanks for all your help in guiding in the correct direction.

htgoebel commented 6 years ago

Notice the strange symbol in version "ciscoconfparse♂ersion"

I assume you want to learn about python strings, e.g. https://www.tutorialspoint.com/python/python_strings.htm

datas=[ ( 'C:\Python27\Lib\site-packages\ciscoconfparse*', 'ciscoconfparse' ) ],

This will unconditionally add all files from that package to the bundle. This works, but is ugly. Nevertheless I'm closing this, since tallforasmurf already provided the solution

kochargs commented 6 years ago

Hello @htgoebel , your assumption is absolutely incorrect.

I do understand the meaning of '*' but since i was troubleshooting it so i figured if adding a specific file may or not be working so i should try that and then work backwards. secondly, i did that too because there is absolutely nothing in that folder except version file, so even if it wants to add all files unconditionally,

I could have done something like this too \v gets interpreted as ASCII Vertical Tab (VT). So \v instead should have solved the problem too

Thanks for your help in closing the issue timely.