summaryrefslogtreecommitdiff
path: root/lab/extract_code.py
blob: e9fc086f3b06797c3f915f0ef7d5d7d6671ef51e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
# For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt

"""
Use this to copy some indented code from the coverage.py test suite into a
standalone file for deeper testing, or writing bug reports.

Give it a file name and a line number, and it will find the indentend
multiline string containing that line number, and output the dedented
contents of the string.

If tests/test_arcs.py has this (partial) content::

    1630	    def test_partial_generators(self):
    1631	        # https://github.com/nedbat/coveragepy/issues/475
    1632	        # Line 2 is executed completely.
    1633	        # Line 3 is started but not finished, because zip ends before it finishes.
    1634	        # Line 4 is never started.
    1635	        cov = self.check_coverage('''\
    1636	            def f(a, b):
    1637	                c = (i for i in a)          # 2
    1638	                d = (j for j in b)          # 3
    1639	                e = (k for k in b)          # 4
    1640	                return dict(zip(c, d))
    1641
    1642	            f(['a', 'b'], [1, 2, 3])
    1643	            ''',
    1644	            arcz=".1 17 7.  .2 23 34 45 5.  -22 2-2  -33 3-3  -44 4-4",
    1645	            arcz_missing="3-3 -44 4-4",
    1646	        )

then you can do::

    % python lab/extract_code.py tests/test_arcs.py 1637
    def f(a, b):
        c = (i for i in a)          # 2
        d = (j for j in b)          # 3
        e = (k for k in b)          # 4
        return dict(zip(c, d))

    f(['a', 'b'], [1, 2, 3])
    %

"""

import sys
import textwrap

if len(sys.argv) == 2:
    fname, lineno = sys.argv[1].split(":")
else:
    fname, lineno = sys.argv[1:]
lineno = int(lineno)

with open(fname) as code_file:
    lines = ["", *code_file]

# Find opening triple-quote
for start in range(lineno, 0, -1):
    line = lines[start]
    if "'''" in line or '"""' in line:
        break

for end in range(lineno+1, len(lines)):
    line = lines[end]
    if "'''" in line or '"""' in line:
        break

code = "".join(lines[start+1: end])
code = textwrap.dedent(code)

print(code, end="")