py2exe data_files

Question:

I am trying to build an executable for my python program like so:

from distutils.core import setup
import py2exe, sys, os 
import matplotlib
import numpy
from glob import glob

sys.argv.append('py2exe')

datafiles = [('files', glob(r'C:Program FilesMicrosoft Visual Studio 9.0VCredistx86Microsoft.VC90.CRT*.*'))]

setup(windows=['main.py'], data_files= datafiles, options={"py2exe": {"includes": ["matplotlib"]}})

This works, however, I need to include these matplotlibfiles obtained by this command as well in order to make the programm work:

matplotlib.get_py2exe_datafiles()

But somehow I am not able to include them into the data_files… I tried stuff like the following, but I am getting errors like “tuple’ object has no attribute ‘split'”

mpl = [('files', [matplotlib.get_py2exe_datafiles()])]
datafiles.append(mpl)

Also, after compiling the working version without the matplotlibfiles, I get a warning that my project is depending on several other dlls – is there any way to force them all at once into the program?

Thanks for your help!

Asked By: bigsleep

||

Answers:

Could it be that matplotlib.get_py2exe_datafiles() isn’t returning files in the way that you’d like? What is the output of this?

Perhaps you need to use list() instead, and drop the extra [] around your mpl:

mpl = ('files', list(matplotlib.get_py2exe_datafiles()))
datafiles.append(mpl)

From the docs, this is what the datafiles should look like when you’re done:

# data_files specifies a sequence of (directory, files) pairs in the following way:

setup(...,
      data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
                  ('config', ['cfg/data.cfg']),
                  ('/etc/init.d', ['init-script'])]
     )
Answered By: Adam Morris

I’m little bit wondering that you want to append the mpl list to the existing datafilesone.

Having a look on following py2exe-wiki-help http://www.py2exe.org/index.cgi/MatPlotLib is showing that you have to use directly the list of matpotlib.get_py2exe_datafiles()

import matplotlib
...
setup(
   ...
data_files=matplotlib.get_py2exe_datafiles(), # <-- here
)

But you append mpl (a list) to the still existing datafiles list which will result not in a continuing list but in a matrix:

>>> datafiles = ['<datafile_one>', '<datafile_two>']
>>> mpl = [('files', ['<mpl_file_one>', '<mpl_file_two>', ...])]
>>> print(datafiles.append(mpl)]
['<datafile_one>', '<datafile_two>', [('files', ['<mpl_file_one>',  '<mpl_file_two>', ...])]

… and this seems to be not correct.

I guess you want to extend(mpl) the list of you visual studio dll files (second index slot) in your datafiles list, do you?

[('files', ['<datafile_one>', '<datafile_two>', '<mpl_file_one>',  '<mpl_file_two>', ...])]

So finally I think that you should try the following way:

datafiles = glob(r'C:Program FilesMicrosoft Visual Studio 9.0VCredistx86Microsoft.VC90.CRT*.*'))]
datafiles.extend(matplotlib.get_py2exe_datafiles())
...
setup(windows=['main.py'], 
    data_files= [('files', datafiles)], #<-- important: tuple will be build here finally
    ...
)

-Colin-

Answered By: Colin O'Coal

I managed to do get the following working:

datafiles = [("Microsoft.VC90.CRT", glob(r'C:Program FilesMicrosoft Visual Studio 9.0VCredistx86Microsoft.VC90.CRT*.*'))]
datafiles.extend(matplotlib.get_py2exe_datafiles()) 

setup(windows=['main.py'], data_files= datafiles, options={"py2exe": {"includes": ["matplotlib"]}})

Thanks for your responses, which pointed me into the right direction!

Answered By: bigsleep

It looks like from Matplotlib 3.3.0 the function get_py2exe_datafiles() doesn’t exist anymore:
https://matplotlib.org/stable/api/prev_api_changes/api_changes_3.3.0.html

To know what to do, please look at:
https://github.com/py2exe/py2exe/issues/71
and
https://github.com/py2exe/py2exe/issues/169

SUMMARY:

I currently have matplotlib 3.6.0, wxpython 4.2.0, py2exe 0.13.0.0:

2 cases:

A – test.py with matplotlib only:

setup.py:

from distutils.core import setup
import py2exe

setup(
    windows = ["test.py"]
)

should work

B – test.py with matplotlib and wxpython:

setup.py:

from distutils.core import setup
import py2exe

setup(
    windows = ["test.py"]
)

should work BUT the need is ALSO to check stuff in py2exe/hooks.py as described in https://github.com/py2exe/py2exe/issues/169

def hook_matplotlib(finder, module):
    """matplotlib requires data files in a 'mpl-data' subdirectory in
    the same directory as the executable.
    """
    import ast
    from pkg_resources._vendor.packaging import version as pkgversion

    import matplotlib

    mpl_data_path = matplotlib.get_data_path()
    finder.add_datadirectory("mpl-data", mpl_data_path, recursive=True)

    # --- COMMENT BELOW LINE NOT TO EXCLUDE WXPYTHON ---------------------
    ##finder.excludes.append("wx")
    ## XXX matplotlib requires tkinter which modulefinder does not
    ## detect because of the six bug.
    # ------------------------------------------------------------------

    ...
Answered By: roural
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.