Ich möchte eine bytecode-only-Verteilung von distutils erstellen (Nein, wirklich, ich weiß; ich weiß, was ich mache). Mit setuptools und dem Befehl bdist_egg können Sie einfach den Parameter --exclude-source angeben. Leider haben die Standardbefehle keine solche Option.Wie entferne ich Quelle von Binärverteilungen von distutils?
Antwort
Der Befehl "build_py" von distutils ist wichtig, da er von allen Befehlen, die Verteilungen erstellen, (indirekt) wiederverwendet wird. Wenn Sie die byte_compile (Dateien) Methode überschreiben, so etwas wie:
try:
from setuptools.command.build_py import build_py
except ImportError:
from distutils.command.build_py import build_py
class build_py(build_py)
def byte_compile(self, files):
super(build_py, self).byte_compile(files)
for file in files:
if file.endswith('.py'):
os.unlink(file)
setup(
...
cmdclass = dict(build_py=build_py),
...
)
sollten Sie in der Lage sein, es zu machen, so dass die Quelldateien aus dem Build-Baum gelöscht werden, bevor sie in die kopierte sind Verzeichnis „install“ (Dies ist ein temporäres Verzeichnis, wenn bdist-Befehle sie aufrufen.
Hinweis: Ich habe diesen Code nicht getestet; YMMV.
+1. Das ist genau die Art von Dingen, auf die ich gehofft hatte. Ich hatte nicht bemerkt, dass es eine gemeinsame build_py gab, in die ich mich einklinken konnte. Ich werde das versuchen und sehen, ob es irgendwelche Feinabstimmungen braucht. – Draemon
+1, aber auf Python 2.7.6 funktioniert es nicht, da build_py eine alte Klasse ist und nicht mit super() verwendet werden kann. Ich habe 'build_py.byte_compile (self, files)' stattdessen verwendet. (Ich habe auch die Klasse build_py umbenannt, damit sie das importierte build_py nicht klobberte.) –
Versuchen Sie folgendes:
from distutils.command.install_lib import install_lib
class install_lib(install_lib, object):
""" Class to overload install_lib so we remove .py files from the resulting
RPM """
def run(self):
""" Overload the run method and remove all .py files after compilation
"""
super(install_lib, self).run()
for filename in self.install():
if filename.endswith('.py'):
os.unlink(filename)
def get_outputs(self):
""" Overload the get_outputs method and remove any .py entries in the
file list """
filenames = super(install_lib, self).get_outputs()
return [filename for filename in filenames
if not filename.endswith('.py')]
Vielleicht ein voll funktions Code hier :)
try:
from setuptools.command.build_py import build_py
except ImportError:
from distutils.command.build_py import build_py
import os
import py_compile
class custom_build_pyc(build_py):
def byte_compile(self, files):
for file in files:
if file.endswith('.py'):
py_compile.compile(file)
os.unlink(file)
....
setup(
name= 'sample project',
cmdclass = dict(build_py=custom_build_pyc),
....
"die Standardbefehle keine solche Option haben"?
Haben Sie die neueste Version von setuptools
installiert? Und hast du eine setup.py
Datei geschrieben?
Wenn ja, sollte dies funktionieren: python setup.py bdist_egg --exclude-source-files
.
Ich bemerkte in der Frage, dass ich dies für bdist_egg geschafft habe. Bei den anderen Ausgaben (z. B. zip) fehlt die Option. – Draemon
Sehr ähnlich: http://stackoverflow.com/questions/261638/how-doi-i-protect-python-code Die kompilierten Python-Dateien (Pyc/Pyo) sind ziemlich trivial zu dekompilieren. –
@Nick: Nicht wirklich. Ich habe den Schutz überhaupt nicht erwähnt, und diese Frage erwähnt keine Disteln. Offensichtlich ist der Python-Bytecode leicht zu analysieren. Wie wäre es nun mit der Frage, die ich eigentlich gestellt habe? – Draemon
Wenn Sie nur alle * .py Dateien aus einer Zip entfernen möchten: '7z d archive.zip * .py -r' –