1 |
commit: 6c865d6b3130de63dc3d534d2a0596dd59d5e662 |
2 |
Author: Zac Medico <zmedico <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue Apr 24 02:21:59 2018 +0000 |
4 |
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Apr 26 03:19:21 2018 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=6c865d6b |
7 |
|
8 |
AsynchronousTask: add scheduler attribute (bug 653856) |
9 |
|
10 |
Add an AsynchronousTask.scheduler attribute, which will hold an event |
11 |
loop instance in order to work with Future instances. Name the |
12 |
attribute "scheduler" because this is the name used by many existing |
13 |
subclasses of AsynchronousTask. Since the AsyncScheduler class already |
14 |
has an _event_loop attribute that it inherits from PollScheduler, use |
15 |
a property for compatibility. Also update the SlotObject constructor |
16 |
to allow a subclass to override an attribute from __slots__ with a |
17 |
property, so that AsyncScheduler can use a property for the scheduler |
18 |
attribute. |
19 |
|
20 |
Bug: https://bugs.gentoo.org/653856 |
21 |
|
22 |
pym/_emerge/AbstractPollTask.py | 3 +-- |
23 |
pym/_emerge/AsynchronousLock.py | 2 +- |
24 |
pym/_emerge/AsynchronousTask.py | 2 +- |
25 |
pym/_emerge/CompositeTask.py | 2 +- |
26 |
pym/portage/util/SlotObject.py | 9 ++++++++- |
27 |
pym/portage/util/_async/AsyncScheduler.py | 7 +++++++ |
28 |
pym/portage/util/_async/AsyncTaskFuture.py | 2 +- |
29 |
7 files changed, 20 insertions(+), 7 deletions(-) |
30 |
|
31 |
diff --git a/pym/_emerge/AbstractPollTask.py b/pym/_emerge/AbstractPollTask.py |
32 |
index 0d38bd481..aa8fc6593 100644 |
33 |
--- a/pym/_emerge/AbstractPollTask.py |
34 |
+++ b/pym/_emerge/AbstractPollTask.py |
35 |
@@ -11,8 +11,7 @@ from _emerge.AsynchronousTask import AsynchronousTask |
36 |
|
37 |
class AbstractPollTask(AsynchronousTask): |
38 |
|
39 |
- __slots__ = ("scheduler",) + \ |
40 |
- ("_registered",) |
41 |
+ __slots__ = ("_registered",) |
42 |
|
43 |
_bufsize = 4096 |
44 |
|
45 |
|
46 |
diff --git a/pym/_emerge/AsynchronousLock.py b/pym/_emerge/AsynchronousLock.py |
47 |
index 78ab37ecb..0178feab2 100644 |
48 |
--- a/pym/_emerge/AsynchronousLock.py |
49 |
+++ b/pym/_emerge/AsynchronousLock.py |
50 |
@@ -37,7 +37,7 @@ class AsynchronousLock(AsynchronousTask): |
51 |
signals to the main thread). |
52 |
""" |
53 |
|
54 |
- __slots__ = ('path', 'scheduler',) + \ |
55 |
+ __slots__ = ('path',) + \ |
56 |
('_imp', '_force_async', '_force_dummy', '_force_process', \ |
57 |
'_force_thread', '_unlock_future') |
58 |
|
59 |
|
60 |
diff --git a/pym/_emerge/AsynchronousTask.py b/pym/_emerge/AsynchronousTask.py |
61 |
index da58261db..e29324440 100644 |
62 |
--- a/pym/_emerge/AsynchronousTask.py |
63 |
+++ b/pym/_emerge/AsynchronousTask.py |
64 |
@@ -16,7 +16,7 @@ class AsynchronousTask(SlotObject): |
65 |
the task is complete and self.returncode has been set. |
66 |
""" |
67 |
|
68 |
- __slots__ = ("background", "cancelled", "returncode") + \ |
69 |
+ __slots__ = ("background", "cancelled", "returncode", "scheduler") + \ |
70 |
("_exit_listeners", "_exit_listener_stack", "_start_listeners", |
71 |
"_waiting") |
72 |
|
73 |
|
74 |
diff --git a/pym/_emerge/CompositeTask.py b/pym/_emerge/CompositeTask.py |
75 |
index f3acc9696..bfd4bacbd 100644 |
76 |
--- a/pym/_emerge/CompositeTask.py |
77 |
+++ b/pym/_emerge/CompositeTask.py |
78 |
@@ -6,7 +6,7 @@ from portage import os |
79 |
|
80 |
class CompositeTask(AsynchronousTask): |
81 |
|
82 |
- __slots__ = ("scheduler",) + ("_current_task",) |
83 |
+ __slots__ = ("_current_task",) |
84 |
|
85 |
_TASK_QUEUED = -1 |
86 |
|
87 |
|
88 |
diff --git a/pym/portage/util/SlotObject.py b/pym/portage/util/SlotObject.py |
89 |
index 4bb682258..ba6215874 100644 |
90 |
--- a/pym/portage/util/SlotObject.py |
91 |
+++ b/pym/portage/util/SlotObject.py |
92 |
@@ -20,7 +20,14 @@ class SlotObject(object): |
93 |
raise AssertionError( |
94 |
"class '%s' duplicates '%s' value in __slots__ of base class '%s'" % |
95 |
(self.__class__.__name__, myattr, c.__name__)) |
96 |
- setattr(self, myattr, myvalue) |
97 |
+ try: |
98 |
+ setattr(self, myattr, myvalue) |
99 |
+ except AttributeError: |
100 |
+ # Allow a property to override a __slots__ value, but raise an |
101 |
+ # error if the intended value is something other than None. |
102 |
+ if not (myvalue is None and |
103 |
+ isinstance(getattr(type(self), myattr, None), property)): |
104 |
+ raise |
105 |
|
106 |
if kwargs: |
107 |
raise TypeError( |
108 |
|
109 |
diff --git a/pym/portage/util/_async/AsyncScheduler.py b/pym/portage/util/_async/AsyncScheduler.py |
110 |
index 9beb8a848..b89b57dab 100644 |
111 |
--- a/pym/portage/util/_async/AsyncScheduler.py |
112 |
+++ b/pym/portage/util/_async/AsyncScheduler.py |
113 |
@@ -20,6 +20,13 @@ class AsyncScheduler(AsynchronousTask, PollScheduler): |
114 |
self._remaining_tasks = True |
115 |
self._loadavg_check_id = None |
116 |
|
117 |
+ @property |
118 |
+ def scheduler(self): |
119 |
+ """ |
120 |
+ Provides compatibility with the AsynchronousTask.scheduler attribute. |
121 |
+ """ |
122 |
+ return self._event_loop |
123 |
+ |
124 |
def _poll(self): |
125 |
if not (self._is_work_scheduled() or self._keep_scheduling()): |
126 |
self.wait() |
127 |
|
128 |
diff --git a/pym/portage/util/_async/AsyncTaskFuture.py b/pym/portage/util/_async/AsyncTaskFuture.py |
129 |
index c2316deeb..ce881ba8d 100644 |
130 |
--- a/pym/portage/util/_async/AsyncTaskFuture.py |
131 |
+++ b/pym/portage/util/_async/AsyncTaskFuture.py |
132 |
@@ -12,7 +12,7 @@ class AsyncTaskFuture(AsynchronousTask): |
133 |
Wraps a Future in an AsynchronousTask, which is useful for |
134 |
scheduling with TaskScheduler. |
135 |
""" |
136 |
- __slots__ = ('future', 'scheduler') |
137 |
+ __slots__ = ('future',) |
138 |
def _start(self): |
139 |
self.future.add_done_callback(self._done_callback) |