覆盖冻结的可执行文件

Jor*_*ley 7 python windows pyinstaller coverage.py

有没有办法对使用pyinstaller构建的可执行文件运行覆盖?我尝试运行它就像它是一个python脚本,它不喜欢可执行文件作为输入(我真的不希望它工作)我怀疑答案是否有没有没有简单的方法来运行覆盖建立的可执行文件....(这是在Windows .exe)

我正在使用的覆盖包只是你从nedbatchelder.com(http://nedbatchelder.com/code/coverage/)获得的"easy_install coverage"的正常覆盖包

jlu*_*jan 6

这不是一个完整的答案,但到目前为止我发现了.

根据我对pyinstaller如何工作的理解,二进制文件是由一个嵌入python解释器和bootstraps加载脚本的小型C程序构造的.PyInstaller构造的EXE在包含python代码资源的实际二进制文件结束后包含一个存档.这在http://www.pyinstaller.org/export/develop/project/doc/Manual.html#pyinstaller-archives中有解释.

有一个从Pyinstaller /装载机/ iu.py iu.py 文档.您应该能够创建从二进制文件导入的导入挂钩.谷歌搜索pyinstaller反汇编程序发现https://bitbucket.org/Trundle/exetractor/src/00df9ce00e1a/exetractor/pyinstaller.py看起来可能会提取必要的部分.

另一部分是二进制存档中的所有资源都将被编译为python代码.最有可能的是,coverage.py将以与在正常条件下运行时击中任何其他已编译模块时相同的方式为您提供无用的输出.


小智 5

突出使用cover_pylib=True

我知道你问这个问题已经很久了,但我只是想得到答案。:)

使用当前的 bitbucket 源,coverage.py我能够成功地从PyInstaller生成的 EXE 文件中收集覆盖率数据。

在我的应用程序的主要来源中,我有条件地告诉覆盖范围开始收集覆盖范围,如下所示:

if os.environ.has_key('COVERAGE') and len(os.environ['COVERAGE']) > 0:
   usingCoverage = True
   import coverage
   import time
   cov = coverage.coverage(data_file='.coverage.' + version.GetFullString(), data_suffix=time.strftime(".%Y_%m_%d_%H_%M.%S", time.localtime()), cover_pylib=True)
   cov.start()
Run Code Online (Sandbox Code Playgroud)

仅当我需要时才开始覆盖范围收集。使用 data_suffix 可以让我cov.combine()以后更轻松地用于覆盖文件合并。 version.GetFullString()只是我的应用程序版本号。

cover_pylib设置为True此处是因为所有标准 Python 库模块__file__属性都类似于此...\_MEIXXXXX\random.pyc,因此与包内不存在的其他代码无法区分(基于路径)。

当应用程序准备退出时,我有这个小片段:

if usingCoverage:
   cov.stop()
   cov.save()
Run Code Online (Sandbox Code Playgroud)

一旦我的应用程序运行,coverage.py 仍然不会自动为我生成 HTML 报告。需要清理覆盖率数据,以便...\_MEIXXXX\...将文件引用转换为真实源代码的绝对文件路径。

我通过运行这段代码来做到这一点:

import sys
import os.path

from coverage.data import CoverageData
from coverage import coverage

from glob import glob

def cleanupLines(data):
    """
    The coverage data collected via PyInstaller coverage needs the data fixed up
    so that coverage.py's report generation code can analyze the source code.
    PyInstaller __file__ attributes on code objecters are all in subdirectories of the     _MEIXXXX 
    temporary subdirectory. We need to replace the _MEIXXXX temp directory prefix with     the correct 
    prefix for each source file. 
    """
    prefix = None
    for file, lines in data.lines.iteritems():
        origFile = file
        if prefix is None:
            index = file.find('_MEI')
            if index >= 0:
                pathSepIndex = file.find('\\', index)
                if pathSepIndex >= 0:
                    prefix = file[:pathSepIndex + 1]
        if prefix is not None and file.find(prefix) >= 0:
            file = file.replace(prefix, "", 1)
            for path in sys.path:
                if os.path.exists(path) and os.path.isdir(path):
                    fileName = os.path.join(path, file)
                    if os.path.exists(fileName) and os.path.isfile(fileName):
                        file = fileName
            if origFile != file:
                del data.lines[origFile]
                data.lines[file] = lines

for file in glob('.coverage.' + version.GetFullString() + '*'):
    print "Cleaning up: ", file
    data = CoverageData(file)
    data.read()
    cleanupLines(data)
    data.write()
Run Code Online (Sandbox Code Playgroud)

这里的 for 循环只是为了确保清除所有将要组合的覆盖文件。

注意:默认情况下,此代码不会清除的唯一覆盖数据是相关文件,这些文件的属性中PyInstaller不包含数据。_MEIXXX__file__

coverage.py您现在可以以正常方式成功生成 HTML 或 XML(或其他)报告。

就我而言,它看起来像这样:

cov = coverage(data_file='.coverage.' + version.GetFullString(), data_suffix='.combined')
cov.load()
cov.combine()
cov.save()
cov.load()
cov.html_report(ignore_errors=True,omit=[r'c:\python27\*', r'..\3rdParty\PythonPackages\*'])
Run Code Online (Sandbox Code Playgroud)

在构造函数中使用 data_file 是为了确保加载/组合能够正确识别我所有清理过的覆盖文件。

html_report调用告诉coverage.py我们忽略标准 python 库(以及签入我的版本控制树的 Python 库)并只关注我的应用程序代码。

我希望这有帮助。