Search code examples
pythondjangopython-2.7cx-freeze

cx_freeze fails to bundle django.utils.six.moves


I am trying to bundle django with cx_freeze. With my setup.py I am able to bundle it together but when I invoke the generated executable I get the below import error. I have tried various ways to fix this but unable to get a way around.

Versions used: Django==1.6.4 cx-Freeze==4.3.3

./build/exe.linux-x86_64-2.7/script
Traceback (most recent call last):
  File "lib/python2.7/site-packages/cx_Freeze/initscripts/Console.py", line 27, in <module>
    exec(code, m.__dict__)
  File "script.py", line 7, in <module>
    from models import Project
  File "/remote/vgrnd77/pritam/tryout/package/models.py", line 6, in <module>
    from django.db.models import CharField, Model, \
  File "lib/python2.7/site-packages/django/db/models/__init__.py", line 5, in <module>
    from django.db.models.query import Q
  File "lib/python2.7/site-packages/django/db/models/query.py", line 14, in <module>
    from django.db.models.fields import AutoField
  File "lib/python2.7/site-packages/django/db/models/fields/__init__.py", line 15, in <module>
    from django import forms
  File "lib/python2.7/site-packages/django/forms/__init__.py", line 8, in <module>
    from django.forms.fields import *
  File "lib/python2.7/site-packages/django/forms/fields.py", line 17, in <module>
    from django.forms.util import ErrorList, from_current_timezone, to_current_timezone
  File "lib/python2.7/site-packages/django/forms/util.py", line 4, in <module>
    from django.utils.html import format_html, format_html_join
  File "lib/python2.7/site-packages/django/utils/html.py", line 12, in <module>
    from django.utils.text import normalize_newlines
  File "lib/python2.7/site-packages/django/utils/text.py", line 11, in <module>
    from django.utils.six.moves import html_entities
ImportError: cannot import name html_entities

Here is my sample script:

#!/usr/bin/env python

import os
import django
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from models import Project

if __name__ == '__main__':
    print "My first exe"
    p = Project.objects.all()
    for project in p:
        print project.name

Here is how the setup.py looks like:

main_python_file = "script.py"

import sys

from cx_Freeze import setup, Executable

# html_entities is missing
base = 'Console'
buildOptions = dict(
    create_shared_zip = False,
    append_script_to_exe = False,
    packages = [],
    includes = ['django'],
    excludes = ['tkinter']
    )

setup(
        name = "my_exe",
        version = "0.1",
        description = "My first exe",
        options = dict(build_exe = buildOptions),
        executables = [Executable(main_python_file, base = base)])

Here is how the project table looks like:

class Project(Model):
    """
    Project table
    """
    name = CharField(max_length=255)

Has anyone faced and solved this ?

Freeze Output shows it was not able to figure out django.utils.six.moves. It shows 'six' in missing modules:

Missing modules:

? django.utils.six.moves imported from django.db.backends, django.db.models.base, django.db.models.sql.where, django.dispatch.dispatcher, django.forms.formsets, django.http.cookie, django.http.response, django.utils.crypto, django.utils.functional, django.utils.html_parser, django.utils.ipv6, django.utils.regex_helper, django.utils.text
? django.utils.six.moves.urllib.parse imported from django.core.files.storage, django.core.validators, django.forms.fields, django.forms.widgets, django.http.request, django.http.response, django.utils.encoding, django.utils.html, django.utils.http

Solution

  • If you look in the django.utils.six file you will find the following code:

    ...
    MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
    MovedModule("http_cookies", "Cookie", "http.cookies"),
    MovedModule("html_entities", "htmlentitydefs", "html.entities"),
    MovedModule("html_parser", "HTMLParser", "html.parser"),
    ...
    

    What django does dynamically is build up the django.utils.six.moves module out of thin air. The parameters to MovedModule are . So the solution in python33 (the one I used) is to import html.entities in my Executable module. I tried to add it to the includes for the executable, but that didn't seem to work. I assume you could use the import htmlenditydefs for the python2 version.