如何删除未涵盖的python代码

时间:2013-04-03 23:27:11

标签: python dependencies code-coverage minify

是否有一个工具可以删除运行时未涵盖的python代码,或者删除特定函数不依赖的代码的工具?如果没有,那会是一个好方法吗?

更具体地说,这是我的问题:

我需要github上 networkx 算法模块的 maxflow子集

通常我只会下载整个库,然后导入我需要的模块:

1)。我需要在纸上打印出一些这些算法。

2)。有些比赛有一个运行代码的在线评委。判断没有安装networkx,所以我需要在上传到裁判之前将我需要的代码剪切并粘贴到单个.py文件中。法官规定了50,000字节的文件大小限制。

例如,剪切并粘贴一个函数后

def ford_fulkerson(G, s, t, capacity='capacity'):

但是ford_fulkerson依赖于其他算法,networkx自定义错误以及整个networkx图和有向图类。

在剪切并粘贴这些依赖项后,我从50行代码转到3000行代码。

我查看了一些应该涵盖所有内容的测试用例的覆盖范围,覆盖范围仅为39%。 39%的大部分只是读取甚至不使用的函数的函数名称。

C:\Users\robert\code\play\spoj>coverage run TOSCORE.py < in.txt
No goal
Goal

C:\Users\robert\code\play\spoj>coverage report -m
Name      Stmts   Miss  Cover   Missing
---------------------------------------
TOSCORE     733    444    39%   226, 233, 236, 252, 280-283, 301, 377-389, 437-4
56, 489-497, 526-534, 568-570, 597, 618, 633, 655-658, 712-715, 772-801, 835, 86
4-869, 900-906, 948-949, 988-991, 1011-1014, 1107, 1115-1119, 1167-1170, 1195, 1
221, 1257-1260, 1297-1308, 1328-1331, 1357, 1361, 1406-1415, 1452, 1493-1512, 15
38, 1570-1574, 1600, 1636-1640, 1673-1677, 1704-1707, 1731-1733, 1757-1759, 1803
-1828, 2029, 2078-2091, 2142-2154, 2160, 2193-2203, 2232-2243, 2296, 2300-2301,
2305-2307, 2309-2311, 2359-2391, 2424-2425, 2455-2459, 2467, 2474, 2483-2484, 24
90-2491, 2498, 2502, 2551-2562, 2588-2599, 2608, 2645-2658, 2698-2709, 2747-2758
, 2798-2801, 2838-2841, 2859-2862, 2867, 2910, 2949-2963, 2979-2990, 3032-3055,
3084, 3091-3092, 3134-3140, 3148-3151, 3178-3180, 3192, 3198, 3208, 3254, 3265-3
283

2 个答案:

答案 0 :(得分:1)

在我看来,作为第一次尝试,我可以使用coverage的输出作为读取原始TOSCORE.py的(比较)Python脚本的输入,并写出{ {1}}省略了所有未覆盖的行。

在实践中,这种方法可能有点天真。更复杂的方法可能是:

  1. 获取TOSCORE.py生成的未覆盖行列表。
  2. 找到长于1行的未覆盖行的第一个块(假设单个未覆盖的行不可能是完全未使用的函数)。
  3. 写出省略该块的coverage版本。
  4. TOSCORE.py的修订版本上运行测试套件。
  5. 如果测试成功运行,请返回步骤1,使用修订版TOSCORE.py作为TOSCORE.py的基本版本来测量覆盖范围。
  6. 如果省略给定的未覆盖代码块会导致测试失败,请继续尝试省略下一个未覆盖的代码块。
  7. 这可能需要一段时间才能执行,但应确保生成的缩短代码通过所有测试。

    执行时间较短的中间方法会在再次运行测试之前尝试省略几个未覆盖的代码块。

    更复杂的方法可能是插入TOSCORE.py语句来代替我们省略的行(以第一个省略行的缩进为前缀)来处理未覆盖的行包含在未使用的分支中的情况pass语句或未使用的if循环,因此只省略这些行会导致错误。

答案 1 :(得分:1)

我写了一个删除评论的小脚本,这就足够了。如果我使用了tokenizer会更好,但无论如何它都是:

data = open("mini_nx.py").read().replace("nx.", "").splitlines()
data = [line for line in data if not line.strip().startswith("#")]

final_data = []
inside = False
for line in data:
    if not inside and line.strip().startswith('"""'):
        if line.strip().endswith('"""') and line.count('"""') > 1:
            final_data.append(line)
        else:
            line = line.rstrip('"')
            if '"' in line:
                line += '-"""'
            else:
                line += '"""-"""'
            final_data.append(line)
            inside = True
        continue
    if inside and line.endswith('"""'):
        inside = False
    elif not inside and line.strip():
        final_data.append(line)

with open("converted_mini_nx.py", "w") as f:
    f.write("\n".join(final_data))