{"id":31,"date":"2009-06-30T02:33:11","date_gmt":"2009-06-30T06:33:11","guid":{"rendered":"http:\/\/blog.jstump.com\/?p=31"},"modified":"2009-06-30T23:46:20","modified_gmt":"2009-07-01T03:46:20","slug":"py2exe-and-pyopengl-3x-with-no-manual-tinkering","status":"publish","type":"post","link":"https:\/\/stump.io\/blog\/2009\/06\/30\/py2exe-and-pyopengl-3x-with-no-manual-tinkering\/","title":{"rendered":"py2exe and pyOpenGL 3.x with no manual tinkering!"},"content":{"rendered":"<p>If you have ever had to py2exe a Python program using pyOpenGL, you know that it&#8217;s a painful, tedious, but above all unclean process.  (Even back with 2.x, that &#8220;version&#8221; file was so troublesome, but here we have one of py2exe&#8217;s worst enemies: funky import hooks.)<\/p>\n<p>I actually figured this out some time ago and have been using it in many of my projects; I first did it for <a href=\"http:\/\/code.google.com\/p\/fofix\/\">Frets on Fire X (FoFiX)<\/a>, and now, upon finding a certain lack of this information elsewhere on the Internet, I&#8217;m bringing it to you here.<\/p>\n<p>Other documents advocate excluding the OpenGL package from your distribution and manually adding it back in after you actually <em>run<\/em> py2exe.\u00a0 However, it&#8217;s actually quite trivial to work around the weird import hooks.\u00a0 The hooks don&#8217;t care whether <code>import<\/code> (well, really, <code>__import__<\/code>&#8230;) is operating the standard CPython way (loading modules and packages directly from the filesystem) or through zipimport, just as long as it returns something useful and doesn&#8217;t raise <code>ImportError<\/code>.\u00a0 So we can just force the stuff that gets indirectly imported to be included when py2exe does its thing.<\/p>\n<p>It&#8217;s a case of passing the necessary module names to py2exe via the py2exe includes option.\u00a0 To do that, pass a dictionary as a keyword argument named <code>options<\/code> to <code>setup<\/code>.  In that dictionary, assign the key <code>py2exe<\/code> to another dictionary.  In that sub-dictionary, set <code>includes<\/code> to a list that contains (at least) the following strings:<\/p>\n<pre>OpenGL.platform.win32\r\nOpenGL.arrays.ctypesarrays\r\nOpenGL.arrays.numpymodule\r\nOpenGL.arrays.lists\r\nOpenGL.arrays.numbers\r\nOpenGL.arrays.strings<\/pre>\n<p>(Note that you probably won&#8217;t need all of those array converters, and you may in fact need extra ones.  Those should cover practically all use cases, though.  FoFiX, which is a quite involved codebase, only needs those.)<\/p>\n<p>If all goes well, everything that pyOpenGL 3.x needs to run should end up actually in the distribution (cleanly!) once py2exe is invoked with the new includes.<\/p>\n<p>If you need to see an example of this in action, see <a href=\"http:\/\/code.google.com\/p\/fofix\/source\/browse\/MFH-Mod\/trunk\/src\/setup_exe.py\">FoFiX&#8217;s setup.py script<\/a>, and all will become clear to you.<\/p>\n<p>Happy py2exeing with pyOpenGL 3.x!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you have ever had to py2exe a Python program using pyOpenGL, you know that it&#8217;s a painful, tedious, but above all unclean process. (Even back with 2.x, that &#8220;version&#8221; file was so troublesome, but here we have one of py2exe&#8217;s worst enemies: funky import hooks.) I actually figured this out some time ago and [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/posts\/31"}],"collection":[{"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/comments?post=31"}],"version-history":[{"count":3,"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/posts\/31\/revisions"}],"predecessor-version":[{"id":34,"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/posts\/31\/revisions\/34"}],"wp:attachment":[{"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/media?parent=31"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/categories?post=31"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/stump.io\/blog\/wp-json\/wp\/v2\/tags?post=31"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}