• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

spesmilo / electrum / 4938565303402496

30 Apr 2025 02:34PM UTC coverage: 60.216% (-0.02%) from 60.236%
4938565303402496

Pull #9775

CirrusCI

f321x
fix: blocked Exception_Window by setting modality

If some dialogs are open while an exception was raised the input of
Exception_Window is blocked and the user cannot click the button to
submit the issue report. Only if the other dialog is closed
Exception_Window starts responding. By setting the modality of
`Exception_Windows` to `ApplicationModal` the `Exception_Window` will
get the 'highest priority' and accepts input even if other dialogs are
open.
Pull Request #9775: fix: blocked Exception_Window by setting modality

21615 of 35896 relevant lines covered (60.22%)

2.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.59
/electrum/sql_db.py
1
import os
4✔
2
import queue
4✔
3
import threading
4✔
4
import asyncio
4✔
5
import sqlite3
4✔
6

7
from .logging import Logger
4✔
8
from .util import test_read_write_permissions
4✔
9

10

11
def sql(func):
4✔
12
    """wrapper for sql methods
13

14
    returns an awaitable asyncio.Future
15
    """
16
    def wrapper(self: 'SqlDB', *args, **kwargs):
4✔
17
        assert threading.current_thread() != self.sql_thread
4✔
18
        f = self.asyncio_loop.create_future()
4✔
19
        self.db_requests.put((f, func, args, kwargs))
4✔
20
        return f
4✔
21
    return wrapper
4✔
22

23

24
class SqlDB(Logger):
4✔
25

26
    def __init__(self, asyncio_loop: asyncio.BaseEventLoop, path, commit_interval=None):
4✔
27
        Logger.__init__(self)
4✔
28
        self.asyncio_loop = asyncio_loop
4✔
29
        self.stopping = False
4✔
30
        self.stopped_event = asyncio.Event()
4✔
31
        self.path = path
4✔
32
        test_read_write_permissions(path)
4✔
33
        self.commit_interval = commit_interval
4✔
34
        self.db_requests = queue.Queue()
4✔
35
        self.sql_thread = threading.Thread(target=self.run_sql)
4✔
36
        self.sql_thread.start()
4✔
37

38
    def stop(self):
4✔
39
        self.stopping = True
4✔
40

41
    def filesize(self):
4✔
42
        return os.stat(self.path).st_size
×
43

44
    def run_sql(self):
4✔
45
        self.logger.info("SQL thread started")
4✔
46
        self.conn = sqlite3.connect(self.path)
4✔
47
        self.logger.info("Creating database")
4✔
48
        self.create_database()
4✔
49
        i = 0
4✔
50
        while not self.stopping and self.asyncio_loop.is_running():
4✔
51
            try:
4✔
52
                future, func, args, kwargs = self.db_requests.get(timeout=0.1)
4✔
53
            except queue.Empty:
4✔
54
                continue
4✔
55
            try:
×
56
                result = func(self, *args, **kwargs)
×
57
            except BaseException as e:
×
58
                self.asyncio_loop.call_soon_threadsafe(future.set_exception, e)
×
59
                continue
×
60
            if not future.cancelled():
×
61
                self.asyncio_loop.call_soon_threadsafe(future.set_result, result)
×
62
            # note: in sweepstore session.commit() is called inside
63
            # the sql-decorated methods, so committing to disk is awaited
64
            if self.commit_interval:
×
65
                i = (i + 1) % self.commit_interval
×
66
                if i == 0:
×
67
                    self.conn.commit()
×
68
        # write
69
        self.conn.commit()
4✔
70
        self.conn.close()
4✔
71

72
        self.logger.info("SQL thread terminated")
4✔
73
        self.asyncio_loop.call_soon_threadsafe(self.stopped_event.set)
4✔
74

75
    def create_database(self):
4✔
76
        raise NotImplementedError()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc