Mercurial > libervia-backend
annotate libervia/backend/tools/trigger.py @ 4100:810921c33a47
tools (common/template): add filter to get media types:
Add 2 filters to get main type and subtype of media type. Jinja2 and Nunjucks don't handle
slices in the same way (Python way for Jinja2, JS way for Nunjucks), making it difficult
to retrieve main type of a media from media type. Thoses filters work in both cases.
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 22 Jun 2023 15:49:06 +0200 |
parents | 4b842c1fb686 |
children | 4dc00e848961 |
rev | line source |
---|---|
3028 | 1 #!/usr/bin/env python3 |
3137 | 2 |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
3 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
590
diff
changeset
|
4 # SAT: a jabber client |
3479 | 5 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
6 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
590
diff
changeset
|
7 # This program is free software: you can redistribute it and/or modify |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
590
diff
changeset
|
8 # it under the terms of the GNU Affero General Public License as published by |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
590
diff
changeset
|
9 # the Free Software Foundation, either version 3 of the License, or |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
590
diff
changeset
|
10 # (at your option) any later version. |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
11 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
590
diff
changeset
|
12 # This program is distributed in the hope that it will be useful, |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
590
diff
changeset
|
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
590
diff
changeset
|
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
590
diff
changeset
|
15 # GNU Affero General Public License for more details. |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
16 |
609
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
590
diff
changeset
|
17 # You should have received a copy of the GNU Affero General Public License |
84a6e83157c2
fixed licences in docstrings (they are now in comments)
Goffi <goffi@goffi.org>
parents:
590
diff
changeset
|
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
19 |
590
56531f9e9ac7
Fix pep8 support in src/tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
20 """Misc usefull classes""" |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
21 |
4071
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
22 from libervia.backend.core.i18n import _ |
4b842c1fb686
refactoring: renamed `sat` package to `libervia.backend`
Goffi <goffi@goffi.org>
parents:
4037
diff
changeset
|
23 from libervia.backend.core.log import getLogger |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
24 |
993
301b342c697a
core: use of the new core.log module:
Goffi <goffi@goffi.org>
parents:
876
diff
changeset
|
25 log = getLogger(__name__) |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
26 |
742
03744d9ebc13
plugin XEP-0033: implementation of the addressing feature:
souliane <souliane@mailoo.org>
parents:
741
diff
changeset
|
27 |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
28 class TriggerException(Exception): |
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
29 pass |
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
30 |
590
56531f9e9ac7
Fix pep8 support in src/tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
31 |
525
5431136501ab
core: Triggers can now frobid other triggers execution
Goffi <goffi@goffi.org>
parents:
516
diff
changeset
|
32 class SkipOtherTriggers(Exception): |
2499
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
33 """ Exception to raise if normal behaviour must be followed instead of following triggers list """ |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
34 |
525
5431136501ab
core: Triggers can now frobid other triggers execution
Goffi <goffi@goffi.org>
parents:
516
diff
changeset
|
35 pass |
5431136501ab
core: Triggers can now frobid other triggers execution
Goffi <goffi@goffi.org>
parents:
516
diff
changeset
|
36 |
590
56531f9e9ac7
Fix pep8 support in src/tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
37 |
588
beaf6bec2fcd
Remove every old-style class.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
572
diff
changeset
|
38 class TriggerManager(object): |
2499
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
39 """This class manage triggers: code which interact to change the behaviour of SàT""" |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
40 |
1347
ba41a81d14c2
frontends (QuickApp), tools (TriggerManager): frontends can also use triggers + add those for sending and receiving a message
souliane <souliane@mailoo.org>
parents:
993
diff
changeset
|
41 try: # FIXME: to be removed when a better solution is found |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
42 MIN_PRIORITY = float("-inf") |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
43 MAX_PRIORITY = float("+inf") |
1347
ba41a81d14c2
frontends (QuickApp), tools (TriggerManager): frontends can also use triggers + add those for sending and receiving a message
souliane <souliane@mailoo.org>
parents:
993
diff
changeset
|
44 except: # XXX: Pyjamas will bug if you specify ValueError here |
ba41a81d14c2
frontends (QuickApp), tools (TriggerManager): frontends can also use triggers + add those for sending and receiving a message
souliane <souliane@mailoo.org>
parents:
993
diff
changeset
|
45 # Pyjamas uses the JS Float class |
ba41a81d14c2
frontends (QuickApp), tools (TriggerManager): frontends can also use triggers + add those for sending and receiving a message
souliane <souliane@mailoo.org>
parents:
993
diff
changeset
|
46 MIN_PRIORITY = Number.NEGATIVE_INFINITY |
ba41a81d14c2
frontends (QuickApp), tools (TriggerManager): frontends can also use triggers + add those for sending and receiving a message
souliane <souliane@mailoo.org>
parents:
993
diff
changeset
|
47 MAX_PRIORITY = Number.POSITIVE_INFINITY |
741
00318e60a06a
core (tools): set min and max priorities for triggers and warn if several triggers have the same not null priority
souliane <souliane@mailoo.org>
parents:
609
diff
changeset
|
48 |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
49 def __init__(self): |
590
56531f9e9ac7
Fix pep8 support in src/tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
50 self.__triggers = {} |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
51 |
516
7ee15fbe8c08
core: added priority management in triggers
Goffi <goffi@goffi.org>
parents:
501
diff
changeset
|
52 def add(self, point_name, callback, priority=0): |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
53 """Add a trigger to a point |
2499
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
54 |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
55 @param point_name: name of the point when the trigger should be run |
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
56 @param callback: method to call at the trigger point |
590
56531f9e9ac7
Fix pep8 support in src/tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
57 @param priority: callback will be called in priority order, biggest |
56531f9e9ac7
Fix pep8 support in src/tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
58 first |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
59 """ |
590
56531f9e9ac7
Fix pep8 support in src/tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
60 if point_name not in self.__triggers: |
56531f9e9ac7
Fix pep8 support in src/tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
61 self.__triggers[point_name] = [] |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
62 if priority != 0 and priority in [ |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
63 trigger_tuple[0] for trigger_tuple in self.__triggers[point_name] |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
64 ]: |
876
65bf1bc70f6b
tools, plugin XEP-0077: small fixes
souliane <souliane@mailoo.org>
parents:
811
diff
changeset
|
65 if priority in (self.MIN_PRIORITY, self.MAX_PRIORITY): |
3028 | 66 log.warning(_("There is already a bound priority [%s]") % point_name) |
741
00318e60a06a
core (tools): set min and max priorities for triggers and warn if several triggers have the same not null priority
souliane <souliane@mailoo.org>
parents:
609
diff
changeset
|
67 else: |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
68 log.debug( |
3028 | 69 _("There is already a trigger with the same priority [%s]") |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
70 % point_name |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
71 ) |
516
7ee15fbe8c08
core: added priority management in triggers
Goffi <goffi@goffi.org>
parents:
501
diff
changeset
|
72 self.__triggers[point_name].append((priority, callback)) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
73 self.__triggers[point_name].sort( |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
74 key=lambda trigger_tuple: trigger_tuple[0], reverse=True |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
75 ) |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
76 |
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
77 def remove(self, point_name, callback): |
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
78 """Remove a trigger from a point |
2499
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
79 |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
80 @param point_name: name of the point when the trigger should be run |
2499
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
81 @param callback: method to remove, must exists in the trigger point |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
82 """ |
516
7ee15fbe8c08
core: added priority management in triggers
Goffi <goffi@goffi.org>
parents:
501
diff
changeset
|
83 for trigger_tuple in self.__triggers[point_name]: |
7ee15fbe8c08
core: added priority management in triggers
Goffi <goffi@goffi.org>
parents:
501
diff
changeset
|
84 if trigger_tuple[1] == callback: |
7ee15fbe8c08
core: added priority management in triggers
Goffi <goffi@goffi.org>
parents:
501
diff
changeset
|
85 self.__triggers[point_name].remove(trigger_tuple) |
7ee15fbe8c08
core: added priority management in triggers
Goffi <goffi@goffi.org>
parents:
501
diff
changeset
|
86 return |
7ee15fbe8c08
core: added priority management in triggers
Goffi <goffi@goffi.org>
parents:
501
diff
changeset
|
87 raise TriggerException("Trying to remove an unexisting trigger") |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
88 |
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
89 def point(self, point_name, *args, **kwargs): |
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
90 """This put a trigger point |
2499
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
91 |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
92 All the triggers for that point will be run |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
93 @param point_name: name of the trigger point |
2650
3a8e7ec4648a
tools (trigger, async_trigger): added no_cancel argument to point and asyncPoint when a trigger must not be cancellable
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
94 @param *args: args to transmit to trigger |
3a8e7ec4648a
tools (trigger, async_trigger): added no_cancel argument to point and asyncPoint when a trigger must not be cancellable
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
95 @param *kwargs: kwargs to transmit to trigger |
3a8e7ec4648a
tools (trigger, async_trigger): added no_cancel argument to point and asyncPoint when a trigger must not be cancellable
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
96 if "triggers_no_cancel" is present, it will be popup out |
3a8e7ec4648a
tools (trigger, async_trigger): added no_cancel argument to point and asyncPoint when a trigger must not be cancellable
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
97 when set to True, this argument don't let triggers stop |
3a8e7ec4648a
tools (trigger, async_trigger): added no_cancel argument to point and asyncPoint when a trigger must not be cancellable
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
98 the workflow |
2499
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
99 @return: True if the action must be continued, False else |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
100 """ |
590
56531f9e9ac7
Fix pep8 support in src/tools.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
588
diff
changeset
|
101 if point_name not in self.__triggers: |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
102 return True |
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
103 |
2650
3a8e7ec4648a
tools (trigger, async_trigger): added no_cancel argument to point and asyncPoint when a trigger must not be cancellable
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
104 can_cancel = not kwargs.pop('triggers_no_cancel', False) |
3a8e7ec4648a
tools (trigger, async_trigger): added no_cancel argument to point and asyncPoint when a trigger must not be cancellable
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
105 |
1347
ba41a81d14c2
frontends (QuickApp), tools (TriggerManager): frontends can also use triggers + add those for sending and receiving a message
souliane <souliane@mailoo.org>
parents:
993
diff
changeset
|
106 for priority, trigger in self.__triggers[point_name]: |
525
5431136501ab
core: Triggers can now frobid other triggers execution
Goffi <goffi@goffi.org>
parents:
516
diff
changeset
|
107 try: |
2650
3a8e7ec4648a
tools (trigger, async_trigger): added no_cancel argument to point and asyncPoint when a trigger must not be cancellable
Goffi <goffi@goffi.org>
parents:
2624
diff
changeset
|
108 if not trigger(*args, **kwargs) and can_cancel: |
525
5431136501ab
core: Triggers can now frobid other triggers execution
Goffi <goffi@goffi.org>
parents:
516
diff
changeset
|
109 return False |
5431136501ab
core: Triggers can now frobid other triggers execution
Goffi <goffi@goffi.org>
parents:
516
diff
changeset
|
110 except SkipOtherTriggers: |
5431136501ab
core: Triggers can now frobid other triggers execution
Goffi <goffi@goffi.org>
parents:
516
diff
changeset
|
111 break |
250
ad3b820651fa
Tools: new misc library, Trigger management implementation
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
112 return True |
2499
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
113 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
114 def return_point(self, point_name, *args, **kwargs): |
2499
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
115 """Like point but trigger must return (continue, return_value) |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
116 |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
117 All triggers for that point must return a tuple with 2 values: |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
118 - continue, same as for point, if False action must be finished |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
119 - return_value: value to return ONLY IF CONTINUE IS FALSE |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
120 @param point_name: name of the trigger point |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
121 @return: True if the action must be continued, False else |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
122 """ |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
123 |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
124 if point_name not in self.__triggers: |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
125 return True |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
126 |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
127 for priority, trigger in self.__triggers[point_name]: |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
128 try: |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
129 cont, ret_value = trigger(*args, **kwargs) |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
130 if not cont: |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
131 return False, ret_value |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
132 except SkipOtherTriggers: |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
133 break |
af4a38ebf52a
core (trigger): new returnPoint method:
Goffi <goffi@goffi.org>
parents:
2483
diff
changeset
|
134 return True, None |