GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

qtsass.watchers.polling   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 16
eloc 55
dl 0
loc 127
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A PollingThread.run() 0 12 3
A PollingWatcher.setup() 0 8 1
A PollingThread.stopped() 0 4 1
A PollingWatcher.stop() 0 3 1
A PollingThread.__init__() 0 14 1
A PollingThread.shutdown() 0 4 1
A PollingWatcher.start() 0 3 1
A PollingWatcher.run() 0 10 2
A PollingThread.started() 0 4 1
A PollingThread.stop() 0 7 3
A PollingWatcher.join() 0 6 1
1
# -*- coding: utf-8 -*-
2
# -----------------------------------------------------------------------------
3
# Copyright (c) 2015 Yann Lanthony
4
# Copyright (c) 2017-2018 Spyder Project Contributors
5
#
6
# Licensed under the terms of the MIT License
7
# (See LICENSE.txt for details)
8
# -----------------------------------------------------------------------------
9
"""Contains the fallback implementation of the Watcher api."""
10
11
# yapf: disable
12
13
from __future__ import absolute_import, print_function
14
15
# Standard library imports
16
import atexit
17
import threading
18
19
# Local imports
20
from qtsass.watchers import snapshots
21
from qtsass.watchers.api import Watcher
22
23
24
# yapf: enable
25
26
27
class PollingThread(threading.Thread):
28
    """A thread that fires a callback at an interval."""
29
30
    def __init__(self, callback, interval):
31
        """Initialize the thread.
32
33
        :param callback: Callback function to repeat.
34
        :param interval: Number of seconds to sleep between calls.
35
        """
36
        super(PollingThread, self).__init__()
37
        self.daemon = True
38
        self.callback = callback
39
        self.interval = interval
40
        self._shutdown = threading.Event()
41
        self._stopped = threading.Event()
42
        self._started = threading.Event()
43
        atexit.register(self.stop)
44
45
    @property
46
    def started(self):
47
        """Check if the thread has started."""
48
        return self._started.is_set()
49
50
    @property
51
    def stopped(self):
52
        """Check if the thread has stopped."""
53
        return self._stopped.is_set()
54
55
    @property
56
    def shutdown(self):
57
        """Check if the thread has shutdown."""
58
        return self._shutdown.is_set()
59
60
    def stop(self):
61
        """Set the shutdown event for this thread and wait for it to stop."""
62
        if not self.started and not self.shutdown:
63
            return
64
65
        self._shutdown.set()
66
        self._stopped.wait()
67
68
    def run(self):
69
        """Threads main loop."""
70
        try:
71
            self._started.set()
72
73
            while True:
74
                self.callback()
75
                if self._shutdown.wait(self.interval):
76
                    break
77
78
        finally:
79
            self._stopped.set()
80
81
82
class PollingWatcher(Watcher):
83
    """Polls a directory recursively for changes.
84
85
    Detects file and directory changes, deletions, and creations. Recursion
86
    depth is limited to 2 levels. We use a limit because the scss file we're
87
    watching for changes could be sitting in the root of a project rather than
88
    a dedicated scss directory. That could lead to snapshots taking too long
89
    to build and diff. It's probably safe to assume that users aren't nesting
90
    scss deeper than a couple of levels.
91
    """
92
93
    def setup(self):
94
        """Set up the PollingWatcher.
95
96
        A PollingThread is created but not started.
97
        """
98
        self._snapshot_depth = 2
99
        self._snapshot = snapshots.take(self._watch_dir, self._snapshot_depth)
100
        self._thread = PollingThread(self.run, interval=1)
101
102
    def start(self):
103
        """Start the PollingThread."""
104
        self._thread.start()
105
106
    def stop(self):
107
        """Stop the PollingThread."""
108
        self._thread.stop()
109
110
    def join(self):
111
        """Wait for the PollingThread to finish.
112
113
        You should always call stop before join.
114
        """
115
        self._thread.join()
116
117
    def run(self):
118
        """Take a new snapshot and call on_change when a change is detected.
119
120
        Called repeatedly by the PollingThread.
121
        """
122
        next_snapshot = snapshots.take(self._watch_dir, self._snapshot_depth)
123
        changes = snapshots.diff(self._snapshot, next_snapshot)
124
        if changes:
125
            self._snapshot = next_snapshot
126
            self.on_change()
127