summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2018-10-14 20:39:46 -0400
committerNed Batchelder <ned@nedbatchelder.com>2018-10-14 20:59:57 -0400
commitae9f040dc4189d73fdd708aa4ba61bf50d7b2a25 (patch)
treeee36612ab56483fbbcae6fc60c4f2812ef9014a5
parent4a404ce724280bf9c5f4bcf1e6a5ba76d7499d89 (diff)
downloadpython-coveragepy-git-ae9f040dc4189d73fdd708aa4ba61bf50d7b2a25.tar.gz
Defer using the database when calling set_context #716
The collector calls set_context() before any code is run. If we touch the database there, it will get created *very* early. This causes problems with pytest-cov, which will delete those early-created files when erasing data. By deferring the database access until add_lines is called, the data file stays off the disk until the collection is done (or until the context switches), which avoids the problem.
-rw-r--r--CHANGES.rst4
-rw-r--r--coverage/sqldata.py25
-rw-r--r--tests/test_debug.py4
3 files changed, 19 insertions, 14 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 2ca34b11..e5f4aeb3 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -17,7 +17,9 @@ Change history for Coverage.py
Unreleased
----------
-Nothing yet.
+- Bug fixes to context support: `issue 716`_.
+
+.. _issue 716: https://github.com/nedbat/coveragepy/issues/716
.. _changes_50a3:
diff --git a/coverage/sqldata.py b/coverage/sqldata.py
index 6c12d681..561878fa 100644
--- a/coverage/sqldata.py
+++ b/coverage/sqldata.py
@@ -93,6 +93,7 @@ class CoverageSqliteData(SimpleReprMixin):
self._has_lines = False
self._has_arcs = False
+ self._current_context = None
self._current_context_id = None
def _choose_filename(self):
@@ -205,13 +206,17 @@ class CoverageSqliteData(SimpleReprMixin):
"""Set the current context for future `add_lines` etc."""
if self._debug.should('dataop'):
self._debug.write("Setting context: %r" % (context,))
- self._start_using()
- context = context or ""
- with self._connect() as con:
- row = con.execute("select id from context where context = ?", (context,)).fetchone()
- if row is not None:
- self._current_context_id = row[0]
- else:
+ self._current_context = context
+ self._current_context_id = None
+
+ def _set_context_id(self):
+ """Use the _current_context to set _current_context_id."""
+ context = self._current_context or ""
+ context_id = self._context_id(context)
+ if context_id is not None:
+ self._current_context_id = context_id
+ else:
+ with self._connect() as con:
cur = con.execute("insert into context (context) values (?)", (context,))
self._current_context_id = cur.lastrowid
@@ -229,8 +234,7 @@ class CoverageSqliteData(SimpleReprMixin):
))
self._start_using()
self._choose_lines_or_arcs(lines=True)
- if self._current_context_id is None:
- self.set_context("")
+ self._set_context_id()
with self._connect() as con:
for filename, linenos in iitems(line_data):
file_id = self._file_id(filename, add=True)
@@ -254,8 +258,7 @@ class CoverageSqliteData(SimpleReprMixin):
))
self._start_using()
self._choose_lines_or_arcs(arcs=True)
- if self._current_context_id is None:
- self.set_context("")
+ self._set_context_id()
with self._connect() as con:
for filename, arcs in iitems(arc_data):
file_id = self._file_id(filename, add=True)
diff --git a/tests/test_debug.py b/tests/test_debug.py
index 63edc84f..284d9567 100644
--- a/tests/test_debug.py
+++ b/tests/test_debug.py
@@ -144,8 +144,8 @@ class DebugTraceTest(CoverageTest):
self.assertRegex(real_messages[-1], r"^\s*\d+\.\w{4}: Writing data")
self.assertRegex(last_line, r"\s+_write_file : .*coverage[/\\]data.py @\d+$")
else:
- self.assertRegex(real_messages[-1], r"^\s*\d+\.\w{4}: Adding lines")
- self.assertRegex(last_line, r"\s+add_lines : .*coverage[/\\]sqldata.py @\d+$")
+ self.assertRegex(real_messages[-1], r"^\s*\d+\.\w{4}: Creating data file")
+ self.assertRegex(last_line, r"\s+_create_db : .*coverage[/\\]sqldata.py @\d+$")
def test_debug_config(self):
out_lines = self.f1_debug_output(["config"])