Differences between revisions 19 and 20
Revision 19 as of 2021-08-24 19:24:12
Size: 807
Editor: MarlysHook
Comment:
Revision 20 as of 2021-08-24 23:35:23
Size: 3265
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
<<BR>>
Hi! Let me begin by stating my name - Dirty however I do not like when individuals use my complete name. It's not a typical thing however exactly what she likes doing is mountain biking but she's believing on beginning something brand-new. Office supervising is exactly what he does for a living. North Carolina is the place I love the majority of. She's been dealing with her website for some time now. Inspect it out here: http://Www.Railroadpics.com/__media__/js/netsoltrademark.php?d=featur.vs120084.hl-users.com%2Fbys%2Findex.php%3Fmod%3Dusers%26action%3Dview%26id%3D995357<<BR>>
<<BR>>
Here is my web page - [[http://Www.Railroadpics.com/__media__/js/netsoltrademark.php?d=featur.vs120084.hl-users.com%2Fbys%2Findex.php%3Fmod%3Dusers%26action%3Dview%26id%3D995357|Marriage Help]]<<BR>>
## page was renamed from WinShell
= The Problem =

`py2exe` doesn't find imported `win32com.shell` module, and creates invalid distribution without this file. As a result, an application that uses this module may crash at random or miss some features.

For example version 0.2 of [[http://tgolden.sc.sabren.com/python/winshell.html|winshell.py]] from Tim Golden (a thin wrapper around Windows Shell-Functions) starts with:
{{{
#!python
from win32com import storagecon
from win32com.shell import shell, shellcon
}}}

py2exe reports that something is missing:
{{{
The following modules appear to be missing
['Interface', 'intSet', 'mxDateTime.__version__', 'win32com.shell']
}}}

and starting the program leaves:
{{{
Traceback (most recent call last):
  File "xxxxxx.py", line 33, in ?
  File "xxxxxxx.pyo", line 9, in ?
  File "winshell.pyo", line 27, in ?
ImportError: No module named shell
}}}

in the log.file.


= Explanation =

`win32com` does some magic in order to allow loading of COM extensions during run time. The actual extensions reside in the `win32comext` directory under site-packages and can't be loaded directly. `win32com`'s [[http://docs.python.org/tutorial/modules.html#packages-in-multiple-directories|__path__]] variable has been changed to point to both `win32com` and `win32comext`. `py2exe`'s modulefinder can't handle runtime changes in `__path__` so we have to tell it about the change beforehand.

= Solution =

Without shame I browsed [[http://spambayes.svn.sourceforge.net/viewvc/spambayes/trunk/spambayes/|Spambayes source code]] and found the code to fix it.

{{{
#!python
# ...
# ModuleFinder can't handle runtime changes to __path__, but win32com uses them
try:
    # py2exe 0.6.4 introduced a replacement modulefinder.
    # This means we have to add package paths there, not to the built-in
    # one. If this new modulefinder gets integrated into Python, then
    # we might be able to revert this some day.
    # if this doesn't work, try import modulefinder
    try:
        import py2exe.mf as modulefinder
    except ImportError:
        import modulefinder
    import win32com, sys
    for p in win32com.__path__[1:]:
        modulefinder.AddPackagePath("win32com", p)
    for extra in ["win32com.shell"]: #,"win32com.mapi"
        __import__(extra)
        m = sys.modules[extra]
        for p in m.__path__[1:]:
            modulefinder.AddPackagePath(extra, p)
except ImportError:
    # no build path setup, no worries.
    pass

from distutils.core import setup
import py2exe

# ...
# The rest of the setup file.
# ...
}}}

And this worked.

= Impact =

The following products included workaround:
 * Spambayes
 * Mercurial
 * hgsvn

= Ideal proposal =

`py2exe` should detect such well-known problems with well-known modules, and when `win32com.shell` is missing, a workaround should be automatically applied with a corresponding log message:
{{{
The following modules appear to be missing
['Interface', 'intSet', 'mxDateTime.__version__', 'win32com.shell']
Applying automatic workaround for known problem with win32com.shell
}}}

`py2exe` should also fail if required modules are missing unless some `--force` key in effect.

The Problem

py2exe doesn't find imported win32com.shell module, and creates invalid distribution without this file. As a result, an application that uses this module may crash at random or miss some features.

For example version 0.2 of winshell.py from Tim Golden (a thin wrapper around Windows Shell-Functions) starts with:

   1 from win32com import storagecon
   2 from win32com.shell import shell, shellcon

py2exe reports that something is missing:

The following modules appear to be missing
['Interface', 'intSet', 'mxDateTime.__version__', 'win32com.shell']

and starting the program leaves:

Traceback (most recent call last):
  File "xxxxxx.py", line 33, in ?
  File "xxxxxxx.pyo", line 9, in ?
  File "winshell.pyo", line 27, in ?
ImportError: No module named shell

in the log.file.

Explanation

win32com does some magic in order to allow loading of COM extensions during run time. The actual extensions reside in the win32comext directory under site-packages and can't be loaded directly. win32com's __path__ variable has been changed to point to both win32com and win32comext. py2exe's modulefinder can't handle runtime changes in __path__ so we have to tell it about the change beforehand.

Solution

Without shame I browsed Spambayes source code and found the code to fix it.

   1 # ...
   2 # ModuleFinder can't handle runtime changes to __path__, but win32com uses them
   3 try:
   4     # py2exe 0.6.4 introduced a replacement modulefinder.
   5     # This means we have to add package paths there, not to the built-in
   6     # one.  If this new modulefinder gets integrated into Python, then
   7     # we might be able to revert this some day.
   8     # if this doesn't work, try import modulefinder
   9     try:
  10         import py2exe.mf as modulefinder
  11     except ImportError:
  12         import modulefinder
  13     import win32com, sys
  14     for p in win32com.__path__[1:]:
  15         modulefinder.AddPackagePath("win32com", p)
  16     for extra in ["win32com.shell"]: #,"win32com.mapi"
  17         __import__(extra)
  18         m = sys.modules[extra]
  19         for p in m.__path__[1:]:
  20             modulefinder.AddPackagePath(extra, p)
  21 except ImportError:
  22     # no build path setup, no worries.
  23     pass
  24 
  25 from distutils.core import setup
  26 import py2exe
  27 
  28 # ...
  29 # The rest of the setup file.
  30 # ...

And this worked.

Impact

The following products included workaround:

  • Spambayes
  • Mercurial
  • hgsvn

Ideal proposal

py2exe should detect such well-known problems with well-known modules, and when win32com.shell is missing, a workaround should be automatically applied with a corresponding log message:

The following modules appear to be missing
['Interface', 'intSet', 'mxDateTime.__version__', 'win32com.shell']
Applying automatic workaround for known problem with win32com.shell

py2exe should also fail if required modules are missing unless some --force key in effect.

win32com.shell (last edited 2021-08-24 23:35:23 by JimmyRetzlaff)