Accepting request 892209 from home:alarrosa:branches:devel:languages:python
- Add a patch from upstream (slightly rebased) to make data collection operations thread safe: * 0001-make-data-collection-operations-thread-safe.patch OBS-URL: https://build.opensuse.org/request/show/892209 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-coverage?expand=0&rev=93
This commit is contained in:
140
0001-make-data-collection-operations-thread-safe.patch
Normal file
140
0001-make-data-collection-operations-thread-safe.patch
Normal file
@@ -0,0 +1,140 @@
|
||||
From e36b42e2db46e892d9347ba0408c99b187ba8cb8 Mon Sep 17 00:00:00 2001
|
||||
From: Ned Batchelder <ned@nedbatchelder.com>
|
||||
Date: Mon, 3 May 2021 07:56:05 -0400
|
||||
Subject: [PATCH] fix: make data collection operations thread-safe
|
||||
|
||||
---
|
||||
CHANGES.rst | 3 +++
|
||||
coverage/sqldata.py | 20 ++++++++++++++++++++
|
||||
tests/test_data.py | 7 ++++++-
|
||||
3 files changed, 29 insertions(+), 1 deletion(-)
|
||||
|
||||
#diff --git a/CHANGES.rst b/CHANGES.rst
|
||||
#index 29af7340..3c65e5d8 100644
|
||||
#--- a/CHANGES.rst
|
||||
#+++ b/CHANGES.rst
|
||||
#@@ -26,6 +26,9 @@ Unreleased
|
||||
#
|
||||
# - Dropped support for Python 2.7, PyPy 2, and Python 3.5.
|
||||
#
|
||||
#+- Data collection is now thread-safe. There may have been rare instances of
|
||||
#+ exceptions raised in multi-threaded programs.
|
||||
#+
|
||||
# - Plugins (like the `Django coverage plugin`_) were generating "Already
|
||||
# imported a file that will be measured" warnings about Django itself. These
|
||||
# have been fixed, closing `issue 1150`_.
|
||||
Index: coverage-5.5/coverage/sqldata.py
|
||||
===================================================================
|
||||
--- coverage-5.5.orig/coverage/sqldata.py
|
||||
+++ coverage-5.5/coverage/sqldata.py
|
||||
@@ -8,12 +8,14 @@
|
||||
|
||||
import collections
|
||||
import datetime
|
||||
+import functools
|
||||
import glob
|
||||
import itertools
|
||||
import os
|
||||
import re
|
||||
import sqlite3
|
||||
import sys
|
||||
+import threading
|
||||
import zlib
|
||||
|
||||
from coverage import env
|
||||
@@ -179,6 +181,10 @@ class CoverageData(SimpleReprMixin):
|
||||
Data in a :class:`CoverageData` can be serialized and deserialized with
|
||||
:meth:`dumps` and :meth:`loads`.
|
||||
|
||||
+ The methods used during the coverage.py collection phase
|
||||
+ (:meth:`add_lines`, :meth:`add_arcs`, :meth:`set_context`, and
|
||||
+ :meth:`add_file_tracers`) are thread-safe. Other methods may not be.
|
||||
+
|
||||
"""
|
||||
|
||||
def __init__(self, basename=None, suffix=None, no_disk=False, warn=None, debug=None):
|
||||
@@ -207,6 +213,8 @@ class CoverageData(SimpleReprMixin):
|
||||
# Maps thread ids to SqliteDb objects.
|
||||
self._dbs = {}
|
||||
self._pid = os.getpid()
|
||||
+ # Synchronize the operations used during collection.
|
||||
+ self._lock = threading.Lock()
|
||||
|
||||
# Are we in sync with the data file?
|
||||
self._have_used = False
|
||||
@@ -218,6 +226,15 @@ class CoverageData(SimpleReprMixin):
|
||||
self._current_context_id = None
|
||||
self._query_context_ids = None
|
||||
|
||||
+ def _locked(method): # pylint: disable=no-self-argument
|
||||
+ """A decorator for methods that should hold self._lock."""
|
||||
+ @functools.wraps(method)
|
||||
+ def _wrapped(self, *args, **kwargs):
|
||||
+ with self._lock:
|
||||
+ # pylint: disable=not-callable
|
||||
+ return method(self, *args, **kwargs)
|
||||
+ return _wrapped
|
||||
+
|
||||
def _choose_filename(self):
|
||||
"""Set self._filename based on inited attributes."""
|
||||
if self._no_disk:
|
||||
@@ -381,6 +398,7 @@ class CoverageData(SimpleReprMixin):
|
||||
else:
|
||||
return None
|
||||
|
||||
+ @_locked
|
||||
def set_context(self, context):
|
||||
"""Set the current context for future :meth:`add_lines` etc.
|
||||
|
||||
@@ -422,6 +440,7 @@ class CoverageData(SimpleReprMixin):
|
||||
"""
|
||||
return self._filename
|
||||
|
||||
+ @_locked
|
||||
def add_lines(self, line_data):
|
||||
"""Add measured line data.
|
||||
|
||||
@@ -454,6 +473,7 @@ class CoverageData(SimpleReprMixin):
|
||||
(file_id, self._current_context_id, linemap),
|
||||
)
|
||||
|
||||
+ @_locked
|
||||
def add_arcs(self, arc_data):
|
||||
"""Add measured arc data.
|
||||
|
||||
@@ -498,6 +518,7 @@ class CoverageData(SimpleReprMixin):
|
||||
('has_arcs', str(int(arcs)))
|
||||
)
|
||||
|
||||
+ @_locked
|
||||
def add_file_tracers(self, file_tracers):
|
||||
"""Add per-file plugin information.
|
||||
|
||||
Index: coverage-5.5/tests/test_data.py
|
||||
===================================================================
|
||||
--- coverage-5.5.orig/tests/test_data.py
|
||||
+++ coverage-5.5/tests/test_data.py
|
||||
@@ -488,10 +488,14 @@ class CoverageDataTest(DataTestHelpers,
|
||||
|
||||
def test_thread_stress(self):
|
||||
covdata = CoverageData()
|
||||
+ exceptions = []
|
||||
|
||||
def thread_main():
|
||||
"""Every thread will try to add the same data."""
|
||||
- covdata.add_lines(LINES_1)
|
||||
+ try:
|
||||
+ covdata.add_lines(LINES_1)
|
||||
+ except Exception as ex:
|
||||
+ exceptions.append(ex)
|
||||
|
||||
threads = [threading.Thread(target=thread_main) for _ in range(10)]
|
||||
for t in threads:
|
||||
@@ -500,6 +504,7 @@ class CoverageDataTest(DataTestHelpers,
|
||||
t.join()
|
||||
|
||||
self.assert_lines1_data(covdata)
|
||||
+ assert exceptions == []
|
||||
|
||||
|
||||
class CoverageDataTestInTempDir(DataTestHelpers, CoverageTest):
|
@@ -1,3 +1,10 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue May 11 10:44:16 UTC 2021 - Antonio Larrosa <alarrosa@suse.com>
|
||||
|
||||
- Add a patch from upstream (slightly rebased) to make data
|
||||
collection operations thread safe:
|
||||
* 0001-make-data-collection-operations-thread-safe.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sun May 9 22:27:19 UTC 2021 - Matej Cepl <mcepl@suse.com>
|
||||
|
||||
|
@@ -27,6 +27,8 @@ Source: https://files.pythonhosted.org/packages/source/c/coverage/covera
|
||||
# PATCH-FIX-UPSTREAM traced_file_absolute.patch gh#nedbat/coveragepy#1161 mcepl@suse.com
|
||||
# traced file names seem to be absolute now?
|
||||
Patch0: traced_file_absolute.patch
|
||||
# PATCH-FIX-UPSTREAM 0001-make-data-collection-operations-thread-safe.patch alarrosa@suse.com -- Make data collection operations thread safe
|
||||
Patch1: 0001-make-data-collection-operations-thread-safe.patch
|
||||
BuildRequires: %{python_module devel}
|
||||
BuildRequires: %{python_module flaky}
|
||||
BuildRequires: %{python_module hypothesis >= 4.57}
|
||||
|
Reference in New Issue
Block a user