2010-08-09 56 views
8

我想从distutils创建一个只有字节码的发行版(我真的不知道,我知道我在做什么)。使用setuptools和bdist_egg命令,您可以简单地提供--exclude-source参数。不幸的是,标准命令没有这样的选项。如何从distutils二进制发行版中去除源代码?

  • 是否有一种简单的方法在tar.gz,zip,rpm或deb创建之前去除源文件。
  • 是否有一个相对干净的每命令的方式来做到这一点(例如只是为tar.gz或zip)。
+1

非常相似:http://stackoverflow.com/questions/261638/how-do-i-protect-python-code编译的python文件(pyc/pyo)对于反编译非常简单。 – 2010-08-09 13:31:04

+8

@Nick:不是。我根本没有提到保护,而且这个问题没有提到distutils。显然python字节码很容易分析,现在怎么样解决我实际问到的问题? – Draemon 2010-08-09 13:57:48

+0

如果你只是想从zip中删除所有* .py文件:'7z d archive.zip * .py -r' – 2010-08-09 14:24:02

回答

11

distutils“build_py”命令是重要的命令,因为它被所有创建分发的命令(间接)重用。如果忽略byte_compile(文件)的方法,是这样的:

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), 
    ... 
) 

你应该能够让这个源文件是从之前他们复制到“安装”目录(编译树中删除当bdist命令调用它们时,它是一个临时目录)。

注:我没有测试过这个代码;因人而异。

+0

+1。这正是我所希望的。我没有意识到有一个共同的build_py我可以挂钩。我会试试看看是否需要调整。 – Draemon 2010-08-10 09:47:06

+1

+1但是在Python 2.7.6上它不起作用,因为build_py是一个旧式类,不能和super()一起使用。我使用'build_py.byte_compile(self,files)'代替。 (我也重命名了build_py类,所以它不会打开导入的build_py。) – 2014-07-28 18:08:45

1

试试这个:

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')] 
1

也许一个完整的工作代码在这里:)

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), 
.... 
0

“的标准命令没有这样的选择”?

您是否安装了最新版本的setuptools?你有没有写过setup.py文件?

如果是这样,这应该工作:python setup.py bdist_egg --exclude-source-files

+0

我在问题中注意到我设法为bdist_egg执行此操作。这是其他产出(例如拉链)缺乏选择。 – Draemon 2016-09-22 09:44:41