Search code examples
pythonwxpythoncx-freezeshelve

Python and Freeze Application with shelve.py


I am trying to freeze an application that involves the use of the shelve module. To freeze it, I am using the GUI2EXE python code and utilizing the cx_freeze portion (everything works great if i remove the shelve part).

When I go to run my compiled application, it complains of

File "anydbm.pyc", line 62, in ?
ImportError: no dbm clone found; tried ['dbhash', 'gdbm', 'dbm',
'dumbdbm']

I have searched around for answers. Most of them said to add this to the script:

for i in ['dbhash', 'gdbm', 'dbm', 'dumbdbm']:
    try: eval('import '+i)
    except: pass

But, this didn't do anything for me. If i include the dbhash module i then get errors related to no bsddb module exists. I cannot seem to figure this problem out. Did i implement the above incorrectly? Am i missing something?

PS, I need to use cx_freeze -- the others (py2exe, pyinstaller) do not work well with the other portions of my program. Also, i really would like to use shelve -- like i said, it compiles and works fine without it.

Thanks!

EDIT

Per Mike's request, I have attached the setup script. Yes, I have tried to include the modules (not shown) but it doesn't work. I have even included anydbm and dbhash in my main script. This doesn't seem to work either.

Also, if you know of a better way to store my variables/lists/dicts/etc than shelve, I would love to know. I tried ZODB (didn't build well either). Currently, i did find pdict (with PersistentDict) and this works well when I freeze the application. However, I find shelve to be faster. Would like to get shelve working if possible...

My setup script:

from cx_Freeze import setup, Executable

includes = []
excludes = ['_gtkagg', '_tkagg', 'bsddb', 'curses', 'email', 'pywin.debugger',
            'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl',
            'Tkconstants', 'Tkinter']
packages = []
path = []

for i in ['dbhash', 'gdbm', 'dbm', 'dumbdbm']:
    try: 
        eval('import '+i)
    except: 
        pass


GUI2Exe_Target_1 = Executable(
    # what to build
    script = "myscript.py",
    initScript = None,
    base = 'Win32GUI',
    targetDir = r"dist",
    targetName = "myscript.exe",
    compress = True,
    copyDependentFiles = False,
    appendScriptToExe = False,
    appendScriptToLibrary = False,
    icon = None
    )

setup(

    version = "0.1",
    description = "No Description",
    author = "No Author",
    name = "cx_Freeze Sample File",

    options = {"build_exe": {"includes": includes,
                             "excludes": excludes,
                             "packages": packages,
                             "path": path
                             }
               },

    executables = [GUI2Exe_Target_1]
    )

Solution

  • eval('import foo') will always fail: eval is for expressions, but import is a statement. You should avoid except: clauses that don't specify the exception type - they hide real bugs in your code.

    Try something like this:

    for dbmodule in ['dbhash', 'gdbm', 'dbm', 'dumbdbm']:
        try:
            __import__(dbmodule)
        except ImportError:
            pass
        else:
            # If we found the module, ensure it's copied to the build directory.
            packages.append(dbmodule)