Skip to content

Conversation

@selik
Copy link
Contributor

@selik selik commented Nov 1, 2017

The lnotab variable -- a dict of executable lines -- is a helper for the show_missing parameter. When show_missing is false, we don't need to calculate that dict. However, emitting the cover files had been made conditional on that dict being non-empty in Commit f026dae. This reverts part of the commit to ensure the cover files are emitted regardless of the show_missing argument.

Additionally, the write_results_file is refactored to clarify the purpose of lnotab.

https://bugs.python.org/issue31908

selik added 6 commits October 31, 2017 17:11
Rather than nesting an if/else inside the last else of the outer
condition, the conditional can be flattened into four possibilities.
A blank line will not appear in ``lnotab`` as returned by
``_find_executable_linenos``. Alternately, ``lnotab`` might be set to an
empty dict. Either way, the check for whether a line is blank can be
done after checking for whether the ``lineno`` is in ``lnotab``.
There's no need to check for an empty line. Either we hit the line and
wrote the count, we didn't hit the line and wrote an annotation, or we
want to print some spaces to indent the line.
The lnotab parameter shouldn't be renamed, for compatibility, but it
could use some further explanation. One natural reading of it would be
"lines without tabs", but it's really a "line number table" -- a mapping
of line numbers to possible executable lines.

One nuance to that "table" is that ``_find_executable_linenos`` will
ignore some code that the user might want to highlight as unreachable.
For example, code inside a condition like ``if False:`` will be
excluded.

Further, it appears ``lnotab`` doesn't need to be a dict. A set would
suffice and might reduce the memory requirements of the trace module. If
the ``_find_lines`` function is used only by the trace module, as the
underscore prefix suggests, it could be refactored to return a set of
line numbers instead of a mapping of line numbers to lines.
Whether the show_missing parameter is true or false, the cover file
should be written. The ``lnotab`` parameter will be used simply to
decide whether to annotate unreached lines with some extra characters.
@selik selik changed the title Fix issue 31908 Fix issue bpo-31908 Nov 1, 2017
@serhiy-storchaka serhiy-storchaka added type-bug An unexpected behavior, bug, or error needs backport to 3.6 labels Mar 26, 2018
@serhiy-storchaka serhiy-storchaka changed the title Fix issue bpo-31908 bpo-31908: Fix output of cover files for trace module command-line tool Mar 26, 2018
@selik
Copy link
Contributor Author

selik commented Mar 28, 2018

This is waiting on me (or someone) to write some tests to help prevent future regressions.

The single test function checks that the coverfile is correctly written
and contains appropriate line count and unreached code highlighting.

The check for ``if []`` avoids interpreter optimization which might
allow the interpreter to recognize the conditional statement as a no-op
and eliminate it. For example, ``if False`` would not be counted, nor
would any code in the following block be highlighted by the trace.
@selik selik force-pushed the fix-issue-31908 branch from 5aa1eb3 to 50fec11 Compare April 24, 2018 00:10
@selik
Copy link
Contributor Author

selik commented Apr 24, 2018

@berkerpeksag I added a test case, treating the CLI as a black box.
@serhiy-storchaka I think this is ready to go, upon review of the test I added to Lib/test/test_trace.py.

Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test is passed if revert changes in trace.py. Please ensure that it fails with unpatched code.

def setUp(self):
with open(self.codefile, 'w') as f:
f.write(textwrap.dedent('''\
x = 42
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please increase the indentation of these lines for readability.

The --missing or -m option was hiding the bug. Testing the CLI with
--count option and only that option reveals the bug.
@selik
Copy link
Contributor Author

selik commented Apr 25, 2018

Whoops. I forgot that the --missing flag hides the bug. I added a test that uses only --count and no other CLI options. This fails without the patch.

Also, indented the triple-quote.

@serhiy-storchaka
Copy link
Member

Tests are failed because dedent() removes too much.

It may by simpler to not use dedent():

            self.assertEqual(f.read(), '''\
    1: x = 42
    1: if []:
           print('unreachable')
''')

or

            self.assertEqual(f.read(),
                "    1: x = 42\n"
                "    1: if []:\n"
                "           print('unreachable')\n"
            )

@selik
Copy link
Contributor Author

selik commented May 1, 2018

I chose the 2nd of those two suggestions. While the explicit newlines are awkward, I think the mismatched indentation of the closing brace was the worse evil.

My apologies for not checking the test pass/fail. It correctly passes the tests now in the branch.

@serhiy-storchaka serhiy-storchaka merged commit 47ab154 into python:master May 1, 2018
@miss-islington
Copy link
Contributor

Thanks @selik for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 3.6, 3.7.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request May 1, 2018
…ol. (pythonGH-4205)

Previously emitted cover files only when --missing option was used.
(cherry picked from commit 47ab154)

Co-authored-by: Michael Selik <[email protected]>
@bedevere-bot
Copy link

GH-6666 is a backport of this pull request to the 3.7 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request May 1, 2018
…ol. (pythonGH-4205)

Previously emitted cover files only when --missing option was used.
(cherry picked from commit 47ab154)

Co-authored-by: Michael Selik <[email protected]>
@bedevere-bot
Copy link

GH-6667 is a backport of this pull request to the 3.6 branch.

miss-islington added a commit that referenced this pull request May 1, 2018
…ol. (GH-4205)

Previously emitted cover files only when --missing option was used.
(cherry picked from commit 47ab154)

Co-authored-by: Michael Selik <[email protected]>
@miss-islington
Copy link
Contributor

Thanks @selik for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 3.6.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request May 1, 2018
…ol. (pythonGH-4205)

Previously emitted cover files only when --missing option was used.
(cherry picked from commit 47ab154)

Co-authored-by: Michael Selik <[email protected]>
@bedevere-bot
Copy link

GH-6668 is a backport of this pull request to the 3.6 branch.

miss-islington added a commit that referenced this pull request May 1, 2018
…ol. (GH-4205)

Previously emitted cover files only when --missing option was used.
(cherry picked from commit 47ab154)

Co-authored-by: Michael Selik <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type-bug An unexpected behavior, bug, or error

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants