Gentoo Archives: gentoo-portage-dev

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