Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setuptools error when embbeding it into a frozen executable #841

Closed
nicoddemus opened this Issue Nov 8, 2016 · 3 comments

Comments

Projects
None yet
2 participants
@nicoddemus
Copy link
Contributor

nicoddemus commented Nov 8, 2016

Hi,

We distribute our applications in Windows and Linux using cx-freeze.

Recently we upgraded mock from 1.0.1 to 1.4.0, and one of the significant changes package-wise is that mock now uses setuptools to determine its __version__ attribute.

Packaging setuptools inside a frozen application poses a problem though: this code from setuptools.sandbox fails with an AssertionError:

try:
    from win32com.client.gencache import GetGeneratePath
    _EXCEPTIONS.append(GetGeneratePath())
    del GetGeneratePath
except ImportError:
    # it appears pywin32 is not installed, so no need to exclude.
    pass

The problem is that GetGeneratePath() fails with an AssertionError when called from a frozen application because the module is on a read-only store (the zipfile with all python modules):

def GetGeneratePath():
    """..."""
    assert not is_readonly, "Why do you want the genpath for a readonly store?"

As a workaround which seems to work for us, we monkeypatched win32com.client.gencache.GetGeneratePath to always raise an ImportError when the application is frozen so the error is handled by setuptools.sandbox, but I'm not sure if there are any ramifications that we are not seeing of that.

Any thoughts or advice on this issue would be really appreciated.

@jaraco

This comment has been minimized.

Copy link
Member

jaraco commented Nov 18, 2016

It'd be nice if Setuptools weren't having to consider the implementation details of certain packages like this. Tracing the blame history, I find this behavior was committed in 2cb36ad, referencing distribute 118.

@jaraco

This comment has been minimized.

Copy link
Member

jaraco commented Nov 18, 2016

Looking at that original issue, I see that the WMI package has a setup.py with import wmi at the top level (in order to grab the __version__ from that package)... and that's probably the behavior that was triggering the generation of caches at install time. I'd like to consider dropping support for that anti-pattern.

Looking at the latest WMI, it no longer imports wmi but instead does the following:

#
# Slight hack to avoid importing the module
# when setup is run
#
version = re.search (r'__version__ = "([a-z0-9\.]+)"', open ("wmi.py").read ()).group (1)

Although hacky, this approach is preferable to invoking behavior in dependencies, especially behavior that might write outside the sandbox.

Since the latest version of WMI, released 5 years ago already works around the issue, let's drop support for win32com generating interfaces during the install step.

@jaraco jaraco closed this in 7daf18f Nov 18, 2016

@nicoddemus

This comment has been minimized.

Copy link
Contributor Author

nicoddemus commented Nov 20, 2016

Thanks @jaraco!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.