Prérequis

Premièrement, je recommende d'utiliser la version 2.3 de python, elle n'est pas encore dépassée et surtout, elle permet de se passer des la DLL qui est nécessaire à python 2.4 : msvcr71.dll.

Pour créer un exe contenant l'ensemble des fichiers, il faut au moins la version 0.6 de py2exe.

L'astuce

Fortement inspiré par le script img2py.py que l'on trouve dans la bibliothèque wxWidget, j'ai écri le script tout simple data2py.py que voici :

import os
import sys
import getopt

__doc__ = """
convert file into an importable module

data2py.py toto.dat >toto.py

extract from python  :

import toto
f = file("toto.dat", "wb")
f.write(toto.data.decode("base64"))
"""
def main(args):
    if not args or ("-h" in args):
        print __doc__
        return

    try:
        opts, fileArgs = getopt.getopt(args, "")
    except getopt.GetoptError:
        print __doc__
        return

    f = file(fileArgs[0], "rb")
    buff = f.read()
    print "data = %s%s%s" % ('"""', buff.encode("base64"), '"""')

if __name__ == "__main__":
    main(sys.argv[1:])

Pour l'utiliser il suffit de faire :

python data2py.py text.txt >text.py

Contenu de text.py :

data = """Qm9uam91ciE=
"""

Le script crée un fichier python contenant les données correspondantes au fichier d'origine mais encodé en base64. Ensuite, un import donnera accès aux données.

Pour créer un nouveau fichier :

import text
f = file("text.txt", "wb")
f.write(text.data.decode("base64"))
f.close()

Pour afficher le contenu du fichier :

import text
print text.data.decode("base64")

Création du fichier .exe

Pour créer un fichier .exe avec py2exe, il faut passer par un fichier setup.py. Il n'y a rien de particulier à faire ici, un script classique suffira :

import py2exe
from distutils.core import setup

setup(console = ["test.py"],
      options = {"py2exe": {"optimize": 2,
                            "bundle_files": 1,
                            "compressed": 1}},
      zipfile = None)

Il suffit de créer le fichier .exe ainsi :

python setup.py py2exe

On obtient un fichier unique ! Il reste juste un problème dans le cas de la diffusion vers Win9X, le fichier w9xpopen.exe est nécessaire.

Conclusion

C'est simple non ? Python est un bon langage ! Plus je l'utilise et plus je suis épaté par sa simplicité.

Il existe d'autres méthodes pour arriver à un résultat proche. En particulier cette solution, basée sur ctype et une autre solution en utilisant NSIS (moins pratique, elle ne permet pas d'utiliser la ligne de commande).

Améliorations possibles

On pourrait envisager une petite automatisation de la mise en place des fichiers dans le module et l'utilisation de la zlib pour gagner un peu de place (histoire de compenser un peu la place perdue avec l'utilisation de Base64). Justement en parlant de gain de place, il est aussi possible d'automatiser l'utilisation de UPX (UPX, outil multiplateforme, permet de comprimer les .exe. Il ne fonctionne pas sur un .exe résultant de py2exe mais peut être utilisé sur les dlls).