Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Numpy creates a tcl folder when using py2exe

When using py2exe on my Python program I get an executable, but also a tcl\ folder.

This is strange, because I don't use tcl/tk at all and nothing related to tkinter in my code.

Why importing numpy is responsible for adding this tcl\ folder ? How to prevent this to happen ?


test.py

import numpy

print 'hello'

PY2EXE CODE

from distutils.core import setup
import py2exe

setup(script_args = ['py2exe'],   windows=[{'script':'test.py'}], options = {'py2exe': {'compressed':1,'bundle_files': 1}}, zipfile = None)
like image 367
Basj Avatar asked Jan 26 '14 00:01

Basj


1 Answers

Modulefinder module which is used to determine dependencies gets "confused" and thinks you need Tkinter.

If you run following script...

from modulefinder import ModuleFinder

finder = ModuleFinder()
finder.run_script('test.py')
print finder.report()

...you will see found modules (shortened):

  Name                      File
  ----                      ----
m BaseHTTPServer            C:\Python27\lib\BaseHTTPServer.py
m ConfigParser              C:\Python27\lib\ConfigParser.py
m FixTk                     C:\Python27\lib\lib-tk\FixTk.py
m SocketServer              C:\Python27\lib\SocketServer.py
m StringIO                  C:\Python27\lib\StringIO.py
m Tkconstants               C:\Python27\lib\lib-tk\Tkconstants.py
m Tkinter                   C:\Python27\lib\lib-tk\Tkinter.py
m UserDict                  C:\Python27\lib\UserDict.py
m _LWPCookieJar             C:\Python27\lib\_LWPCookieJar.py
...

So now we know that Tkinter is imported, but it is not very useful. The report does not show what is the offending module. However, it is enough information to exclude Tkinter by modifying py2exe script:

from distutils.core import setup
import py2exe

setup(script_args = ['py2exe'],
      windows=[{'script':'test.py'}],
      options = {'py2exe': {'compressed':1,
                            'bundle_files': 1,
                            'excludes': ['Tkconstants', 'Tkinter']
                            },
                 },
      zipfile = None)

Usually that is enough. If you are still curious what modules are the offending ones, ModuleFinder is not much helpful. But you can install modulegraph and its dependency altgraph. Then you can run the following script and redirect the output to a HTML file:

import modulegraph.modulegraph

m = modulegraph.modulegraph.ModuleGraph()
m.run_script("test.py")
m.create_xref()

You will get dependency graph, where you will find that:

numpy -> numpy.lib -> numpy.lib.utils -> pydoc -> Tkinter 
like image 192
Fenikso Avatar answered Oct 18 '22 09:10

Fenikso