C ++ PyImport的Python覆盖率 [英] Python Coverage for C++ PyImport

查看:88
本文介绍了C ++ PyImport的Python覆盖率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况:

我正在尝试获取当前项目中所有python代码的覆盖率报告。在大多数情况下,我利用Coverage.py取得了巨大的成功。目前,我正在像这样使用它, sitecustomize.py流程。对于从命令行启动的所有操作,它的效果都很棒。

Situation:
I'm attempting to get coverage reports on all python code in my current project. I've utilized Coverage.py with great success for the most part. Currently I'm using it like this taking advantage of the sitecustomize.py process. For everything that's being started from the command line, and it works amazing.

问题:

我无法通过PyImport_Import()类型语句从C ++运行python模块来实际跟踪并输出覆盖率数据。

Issue:
I can't get python modules run from C++ via PyImport_Import() type statements to actually trace and output coverage data.

示例:

[test.cpp]

#include <stdio.h>
#include <iostream>
#include <Python.h>
int main()
{
    Py_Initialize();
    PyObject* sysPath = PySys_GetObject("path");
    PyList_Append(sysPath, PyString_FromString("."));
    // Load the module
    PyObject *pName = PyString_FromString("test_mod");
    PyObject *pModule = PyImport_Import(pName);
    if (pModule != NULL) {
        std::cout << "Python module found\n";
        // Load all module level attributes as a dictionary
        PyObject *pDict = PyModule_GetDict(pModule);
        PyObject *pFunc = PyObject_GetAttrString(pModule, "getInteger");
        if(pFunc)
        {
            if(PyCallable_Check(pFunc))
            {
                PyObject *pValue = PyObject_CallObject(pFunc, NULL);
                std::cout << PyLong_AsLong(pValue) << std::endl;
            }
            else
            {
                printf("ERROR: function getInteger()\n");
            }

        }
        else
        {
            printf("ERROR: pFunc is NULL\n");
        }
    }
    else
        std::cout << "Python Module not found\n";
    return 0;
}

[test_mod.py]

#!/bin/python
def getInteger():
     print('Python function getInteger() called')
     c = 100*50/30
     return c
print('Randomness')

输出:

如果我手动运行test_mod.py,它将按预期输出。但是,如果我运行已编译的test.cpp二进制文件,它不会为coverage数据输出任何内容。我知道sitecustomize.py仍然受到打击,因为我添加了一些调试以确保我不会发疯。我还可以在coverage调试日志中看到它确实希望跟踪该模块。

Output:
If I manually run test_mod.py it outputs as expected. However, if I run the compiled test.cpp binary, it doesn't output anything for coverage data. I know sitecustomize.py is still being hit, as I added some debugging to ensure I wasn't going insane. I can also see in the coverage debug log that it does indeed want to trace the module..

[cov.log]

New process: executable: /usr/bin/python
New process: cmd: ???
New process: parent pid: 69073
-- config ----------------------------------------------------
_include: None
_omit: None
attempted_config_files: /tmp/.coveragerc
branch: True
concurrency: thread
multiprocessing
config_files: /tmp/.coveragerc
cover_pylib: False
data_file: /tmp/python_data/.coverage
debug: process
trace
sys
config
callers
dataop
dataio
disable_warnings: -none-
exclude_list: #\s*(pragma|PRAGMA)[:\s]?\s*(no|NO)\s*(cover|COVER)
extra_css: None
fail_under: 0.0
html_dir: htmlcov
html_title: Coverage report
ignore_errors: False
note: None
New Section 1 Page 2note: None
parallel: True
partial_always_list: while (True|1|False|0):
if (True|1|False|0):
partial_list: #\s*(pragma|PRAGMA)[:\s]?\s*(no|NO)\s*(branch|BRANCH)
paths: {'source': ['/tmp/python_source', '/opt/test']}
plugin_options: {}
plugins: -none-
precision: 0
report_include: None
report_omit: None
run_include: None
run_omit: None
show_missing: False
skip_covered: False
source: /opt/test/
timid: False
xml_output: coverage.xml
xml_package_depth: 99
-- sys -------------------------------------------------------
version: 4.5.4
coverage: /usr/lib64/python2.7/site-packages/coverage/__init__.pyc
cover_paths: /usr/lib64/python2.7/site-packages/coverage
pylib_paths: /usr/lib64/python2.7
tracer: PyTracer
plugins.file_tracers: -none-
plugins.configurers: -none-
config_files: /tmp/.coveragerc
configs_read: /tmp/.coveragerc
data_path: /tmp/python_data/.coverage
python: 2.7.5 (default, Jun 11 2019, 14:33:56) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
platform: Linux-3.10.0-1062.el7.x86_64-x86_64-with-redhat-7.7-Maipo
implementation: CPython
executable: /usr/bin/python
cwd: /opt/test
path: /usr/lib64/python27.zip
/usr/lib64/python2.7
/usr/lib64/python2.7/plat-linux2
/usr/lib64/python2.7/lib-tk
/usr/lib64/python2.7/lib-old
/usr/lib64/python2.7/lib-dynload
/usr/lib64/python2.7/site-packages
environment: COVERAGE_DEBUG = process,trace,sys,config,callers,dataop,dataio
COVERAGE_DEBUG_FILE = /tmp/cov.log
COVERAGE_PROCESS_START = /tmp/.coveragerc
command_line: ???
source_match: /opt/test
source_pkgs_match: -none-
include_match: -none-
omit_match: -none-
cover_match: -none-
pylib_match: -none-
-- end -------------------------------------------------------
<module> : /usr/lib64/python2.7/site.py @556
New Section 1 Page 3<module> : /usr/lib64/python2.7/site.py @556
main : /usr/lib64/python2.7/site.py @539
addsitepackages : /usr/lib64/python2.7/site.py @317
addsitedir : /usr/lib64/python2.7/site.py @190
addpackage : /usr/lib64/python2.7/site.py @152
<module> : <string> @1
process_startup : /usr/lib64/python2.7/site-packages/coverage/control.py @1289
start : /usr/lib64/python2.7/site-packages/coverage/control.py @690
_init : /usr/lib64/python2.7/site-packages/coverage/control.py @362
_write_startup_debug : /usr/lib64/python2.7/site-packages/coverage/control.py @382
write_formatted_info : /usr/lib64/python2.7/site-packages/coverage/debug.py @120
Not tracing '/usr/lib64/python2.7/threading.py': falls outside the --source trees
<module> : /usr/lib64/python2.7/site.py @556
main : /usr/lib64/python2.7/site.py @539
addsitepackages : /usr/lib64/python2.7/site.py @317
addsitedir : /usr/lib64/python2.7/site.py @190
addpackage : /usr/lib64/python2.7/site.py @152
<module> : <string> @1
process_startup : /usr/lib64/python2.7/site-packages/coverage/control.py @1289
start : /usr/lib64/python2.7/site-packages/coverage/control.py @701
start : /usr/lib64/python2.7/site-packages/coverage/collector.py @318
settrace : /usr/lib64/python2.7/threading.py @99
_trace : /usr/lib64/python2.7/site-packages/coverage/pytracer.py @111
_should_trace : /usr/lib64/python2.7/site-packages/coverage/control.py @593


[... Not tracing a bunch of common python code ...]


Tracing './test_mod.py'
<module> : ./test_mod.py @3
_trace : /usr/lib64/python2.7/site-packages/coverage/pytracer.py @111
_should_trace : /usr/lib64/python2.7/site-packages/coverage/control.py @593


推荐答案

I使用您的代码重现了该问题,您只忘记了调用Py_Finalize()。结果,报告从不生成,而数据是被收集的。

I reproduced the issue using your code and you only forgot to call Py_Finalize(). As a result, the report is never generated whereas the data were collected.

它与以下代码段一起工作:

It works with the following piece of code:

#include <stdio.h>
#include <iostream>
#include <Python.h>
int main()
{
    Py_Initialize();
    PyEval_InitThreads();
    PyObject* sysPath = PySys_GetObject("path");
    PyList_Append(sysPath, PyString_FromString("."));
    // Load the module
    PyObject *pName = PyString_FromString("test_mod");
    PyObject *pModule = PyImport_Import(pName);
    if (pModule != NULL) {
        std::cout << "Python module found\n";
        // Load all module level attributes as a dictionary
        PyObject *pDict = PyModule_GetDict(pModule);
        PyObject *pFunc = PyObject_GetAttrString(pModule, "getInteger");
        if(pFunc)
        {
            if(PyCallable_Check(pFunc))
            {
                PyObject *pValue = PyObject_CallObject(pFunc, NULL);
                std::cout << PyLong_AsLong(pValue) << std::endl;
            }
            else
            {
                printf("ERROR: function getInteger()\n");
            }

        }
        else
        {
            printf("ERROR: pFunc is NULL\n");
        }
    }
    else
        std::cout << "Python Module not found\n";
    Py_Finalize();
    return 0;

这篇关于C ++ PyImport的Python覆盖率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆