PyWebWinUI3 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pywebwinui3/__init__.py +3 -0
- pywebwinui3/core.py +176 -0
- pywebwinui3/event.py +147 -0
- pywebwinui3/qt.py +887 -0
- pywebwinui3/type.py +362 -0
- pywebwinui3/util.py +194 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.0.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.1.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.10.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.11.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.12.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.13.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.14.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.15.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.16.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.17.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.18.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.19.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.2.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.20.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.21.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.22.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.23.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.24.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.25.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.26.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.27.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.28.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.29.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.3.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.30.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.31.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.32.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.33.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.34.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.35.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.36.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.37.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.38.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.39.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.4.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.40.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.41.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.42.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.43.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.44.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.45.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.46.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.47.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.48.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.49.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.5.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.50.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.51.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.52.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.53.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.54.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.55.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.56.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.57.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.58.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.59.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.6.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.60.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.61.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.62.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.63.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.64.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.65.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.66.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.67.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.68.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.69.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.7.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.70.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.71.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.72.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.73.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.74.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.75.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.76.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.77.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.78.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.79.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.8.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.80.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.81.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.82.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.83.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.84.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.85.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.86.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.87.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.88.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.89.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.9.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.90.woff2 +0 -0
- pywebwinui3/web/Pretendard/PretendardVariable.subset.91.woff2 +0 -0
- pywebwinui3/web/Pretendard/Variable-dynamic-subset.min.css +927 -0
- pywebwinui3/web/SegoeFluentIcons.ttf +0 -0
- pywebwinui3/web/_app/env.js +1 -0
- pywebwinui3/web/_app/immutable/assets/2.wYBxhgNe.css +1 -0
- pywebwinui3/web/_app/immutable/chunks/BeVEiAlX.js +1 -0
- pywebwinui3/web/_app/immutable/chunks/C-ZTJ6AF.js +1 -0
- pywebwinui3/web/_app/immutable/chunks/D2X8AmeL.js +1 -0
- pywebwinui3/web/_app/immutable/chunks/DLxx5-LD.js +2 -0
- pywebwinui3/web/_app/immutable/chunks/DPxT1AeO.js +1 -0
- pywebwinui3/web/_app/immutable/chunks/DZb1s-qq.js +1 -0
- pywebwinui3/web/_app/immutable/chunks/DbLPBgK4.js +1 -0
- pywebwinui3/web/_app/immutable/chunks/d_V4Mktp.js +1 -0
- pywebwinui3/web/_app/immutable/chunks/pGvP_QvR.js +1 -0
- pywebwinui3/web/_app/immutable/entry/app.DgyHcM8N.js +2 -0
- pywebwinui3/web/_app/immutable/entry/start.D7vHaDGu.js +1 -0
- pywebwinui3/web/_app/immutable/nodes/0.DO1mLoyu.js +54 -0
- pywebwinui3/web/_app/immutable/nodes/1.DvyFB-Wy.js +1 -0
- pywebwinui3/web/_app/immutable/nodes/2.CrF9bZZd.js +94 -0
- pywebwinui3/web/_app/version.json +1 -0
- pywebwinui3/web/index.html +101 -0
- pywebwinui3-1.0.0.dist-info/METADATA +92 -0
- pywebwinui3-1.0.0.dist-info/RECORD +124 -0
- pywebwinui3-1.0.0.dist-info/WHEEL +5 -0
- pywebwinui3-1.0.0.dist-info/licenses/LICENSE +201 -0
- pywebwinui3-1.0.0.dist-info/licenses/NOTICE +13 -0
- pywebwinui3-1.0.0.dist-info/top_level.txt +1 -0
pywebwinui3/__init__.py
ADDED
pywebwinui3/core.py
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
import logging
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
from .event import Event
|
|
9
|
+
from .type import Status
|
|
10
|
+
from .util import AccentColorWatcher, SyncDict, loadPage
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger("pywebwinui3")
|
|
13
|
+
|
|
14
|
+
from .qt import WebviewAPI
|
|
15
|
+
|
|
16
|
+
DEFAULT_WINDOW_WIDTH = 900
|
|
17
|
+
DEFAULT_WINDOW_HEIGHT = 600
|
|
18
|
+
DEFAULT_WINDOW_MIN_WIDTH = 100
|
|
19
|
+
DEFAULT_WINDOW_MIN_HEIGHT = 100
|
|
20
|
+
ABSOLUTE_WINDOW_MIN_WIDTH = 1
|
|
21
|
+
ABSOLUTE_WINDOW_MIN_HEIGHT = 1
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class WindowEvents:
|
|
25
|
+
def __init__(self) -> None:
|
|
26
|
+
self.windowReady = Event()
|
|
27
|
+
self.closed = Event()
|
|
28
|
+
self.accentColorChange = Event()
|
|
29
|
+
self.themeChange = Event()
|
|
30
|
+
self.valueChange = Event()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class MainWindow:
|
|
34
|
+
def __init__(self, title: str, icon: str | None = None):
|
|
35
|
+
self.rootPath = Path(inspect.currentframe().f_back.f_code.co_filename).parent.resolve()
|
|
36
|
+
self.packagePath = Path(__file__).parent.resolve() / "web"
|
|
37
|
+
self._title = title
|
|
38
|
+
self._icon = icon
|
|
39
|
+
|
|
40
|
+
self.accent = AccentColorWatcher()
|
|
41
|
+
self.events = WindowEvents()
|
|
42
|
+
self.api = WebviewAPI(self, self._title, self._icon)
|
|
43
|
+
|
|
44
|
+
self.values = SyncDict(
|
|
45
|
+
{
|
|
46
|
+
"system_title": title,
|
|
47
|
+
"system_icon": icon,
|
|
48
|
+
"system_theme": "system",
|
|
49
|
+
"system_theme_resolved": self.accent.theme,
|
|
50
|
+
"system_accent": self.accent.palette,
|
|
51
|
+
"system_pages": None,
|
|
52
|
+
"system_settings": None,
|
|
53
|
+
"system_nofication": [],
|
|
54
|
+
"system_pin": False,
|
|
55
|
+
"system_window_width": 900,
|
|
56
|
+
"system_window_height": 600,
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
self.values.sync = self.api.queue_sync_value
|
|
60
|
+
|
|
61
|
+
self.events.accentColorChange = self.accent.event
|
|
62
|
+
self.events.themeChange = self.accent.theme_event
|
|
63
|
+
self.events.valueChange = self.values.event
|
|
64
|
+
self.events.accentColorChange += lambda palette: self.values.set("system_accent", palette)
|
|
65
|
+
self.events.themeChange += lambda theme: self.values.set("system_theme_resolved", theme)
|
|
66
|
+
|
|
67
|
+
def onValueChange(self, key):
|
|
68
|
+
def decorator(func):
|
|
69
|
+
self.events.valueChange += (key, func)
|
|
70
|
+
return func
|
|
71
|
+
|
|
72
|
+
return decorator
|
|
73
|
+
|
|
74
|
+
def onAccentColorChange(self):
|
|
75
|
+
def decorator(func):
|
|
76
|
+
self.events.accentColorChange += func
|
|
77
|
+
return func
|
|
78
|
+
|
|
79
|
+
return decorator
|
|
80
|
+
|
|
81
|
+
def onThemeChange(self):
|
|
82
|
+
def decorator(func):
|
|
83
|
+
self.events.themeChange += func
|
|
84
|
+
return func
|
|
85
|
+
|
|
86
|
+
return decorator
|
|
87
|
+
|
|
88
|
+
def onSetup(self):
|
|
89
|
+
def decorator(func):
|
|
90
|
+
self.events.windowReady += func
|
|
91
|
+
return func
|
|
92
|
+
|
|
93
|
+
return decorator
|
|
94
|
+
|
|
95
|
+
def onExit(self):
|
|
96
|
+
def decorator(func):
|
|
97
|
+
self.events.closed += func
|
|
98
|
+
return func
|
|
99
|
+
|
|
100
|
+
return decorator
|
|
101
|
+
|
|
102
|
+
def notice(self, level: Status, title: str, description: str, item: dict | None = None):
|
|
103
|
+
self.values["system_nofication"] = [
|
|
104
|
+
*(self.values["system_nofication"] or []),
|
|
105
|
+
[level, title, description, item],
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
def init(self) -> dict:
|
|
109
|
+
return dict(self.values)
|
|
110
|
+
|
|
111
|
+
def pin(self, state: bool):
|
|
112
|
+
state = bool(state)
|
|
113
|
+
self.values.set("system_pin", state, self.api is not None)
|
|
114
|
+
if self.api is not None:
|
|
115
|
+
self.api.set_on_top(state)
|
|
116
|
+
return state
|
|
117
|
+
|
|
118
|
+
def syncValue(self, key, value):
|
|
119
|
+
return self.values.set(key, value, False)
|
|
120
|
+
|
|
121
|
+
def addSettings(self, pageFile: str | Path | None = None, pageData: dict | None = None):
|
|
122
|
+
if pageFile and not pageData:
|
|
123
|
+
pageData = loadPage(pageFile)
|
|
124
|
+
logger.debug("Setting page: %s", pageData["attr"]["path"])
|
|
125
|
+
self.values["system_settings"] = pageData
|
|
126
|
+
|
|
127
|
+
def addPage(self, pageFile: str | Path | None = None, pageData: dict | None = None):
|
|
128
|
+
if pageFile and not pageData:
|
|
129
|
+
pageData = loadPage(pageFile)
|
|
130
|
+
logger.debug("Page added: %s", pageData["attr"]["path"])
|
|
131
|
+
self.values["system_pages"] = {
|
|
132
|
+
**(self.values["system_pages"] or {}),
|
|
133
|
+
pageData["attr"]["path"]: pageData,
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
def resolve_path(self, value: str | Path | None) -> Path | None:
|
|
137
|
+
if value is None:
|
|
138
|
+
return None
|
|
139
|
+
|
|
140
|
+
path = Path(value)
|
|
141
|
+
if path.is_absolute():
|
|
142
|
+
return path
|
|
143
|
+
|
|
144
|
+
root_candidate = self.rootPath / path
|
|
145
|
+
if root_candidate.exists():
|
|
146
|
+
return root_candidate.resolve()
|
|
147
|
+
|
|
148
|
+
package_candidate = self.packagePath / path
|
|
149
|
+
if package_candidate.exists():
|
|
150
|
+
return package_candidate.resolve()
|
|
151
|
+
|
|
152
|
+
return root_candidate.resolve()
|
|
153
|
+
|
|
154
|
+
def resolve_resource_url(self, value):
|
|
155
|
+
if not isinstance(value, (str, Path)):
|
|
156
|
+
return value
|
|
157
|
+
|
|
158
|
+
raw_value = str(value).strip()
|
|
159
|
+
if not raw_value:
|
|
160
|
+
return value
|
|
161
|
+
|
|
162
|
+
lowered = raw_value.lower()
|
|
163
|
+
if lowered.startswith(("http://", "https://", "file://", "data:", "qrc://", "qrc:", "about:")):
|
|
164
|
+
return raw_value
|
|
165
|
+
|
|
166
|
+
resolved = self.resolve_path(raw_value)
|
|
167
|
+
if resolved is None or not resolved.exists():
|
|
168
|
+
return raw_value
|
|
169
|
+
|
|
170
|
+
return resolved.as_uri()
|
|
171
|
+
|
|
172
|
+
def start(self, debug: bool = False, min_width=900, min_height=600):
|
|
173
|
+
# if self.api is not None and getattr(self.api, "_window", None) is not None:
|
|
174
|
+
self.api.set_window_minimum_size(min_width, min_height)
|
|
175
|
+
self.accent.start()
|
|
176
|
+
self.api.start(debug=debug)
|
pywebwinui3/event.py
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
import fnmatch
|
|
5
|
+
import logging
|
|
6
|
+
import traceback
|
|
7
|
+
from typing import Any, Callable
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger("pywebwinui3.eventmanager")
|
|
10
|
+
|
|
11
|
+
class Event:
|
|
12
|
+
def __init__(self) -> None:
|
|
13
|
+
self.items: list[Callable[..., Any]] = []
|
|
14
|
+
|
|
15
|
+
def set(self, *args: Any):
|
|
16
|
+
listeners = tuple(self.items)
|
|
17
|
+
if not listeners:
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
for func in listeners:
|
|
21
|
+
try:
|
|
22
|
+
func(*args)
|
|
23
|
+
except Exception:
|
|
24
|
+
logger.error(traceback.format_exc())
|
|
25
|
+
|
|
26
|
+
def __add__(self, item: Callable[..., Any]):
|
|
27
|
+
self.items.append(item)
|
|
28
|
+
return self
|
|
29
|
+
|
|
30
|
+
def __sub__(self, item: Callable[..., Any]):
|
|
31
|
+
self.items.remove(item)
|
|
32
|
+
return self
|
|
33
|
+
|
|
34
|
+
def __iadd__(self, item: Callable[..., Any]):
|
|
35
|
+
self.items.append(item)
|
|
36
|
+
return self
|
|
37
|
+
|
|
38
|
+
def __isub__(self, item: Callable[..., Any]):
|
|
39
|
+
self.items.remove(item)
|
|
40
|
+
return self
|
|
41
|
+
|
|
42
|
+
def __len__(self) -> int:
|
|
43
|
+
return len(self.items)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class PathEvent:
|
|
47
|
+
def __init__(self) -> None:
|
|
48
|
+
self.exact_items: dict[str, Event] = {}
|
|
49
|
+
self.pattern_items: dict[str, Event] = {}
|
|
50
|
+
self._compiled_patterns: dict[str, re.Pattern[str]] = {}
|
|
51
|
+
self._pattern_cache: dict[str, tuple[Event, ...]] = {}
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def _is_pattern(target: str) -> bool:
|
|
55
|
+
return any(char in target for char in "*?[]")
|
|
56
|
+
|
|
57
|
+
def _bucket(self, target: str) -> dict[str, Event]:
|
|
58
|
+
return self.pattern_items if self._is_pattern(target) else self.exact_items
|
|
59
|
+
|
|
60
|
+
def _clear_pattern_cache(self) -> None:
|
|
61
|
+
self._pattern_cache.clear()
|
|
62
|
+
|
|
63
|
+
def _compile_pattern(self, pattern: str) -> re.Pattern[str]:
|
|
64
|
+
regex = self._compiled_patterns.get(pattern)
|
|
65
|
+
if regex is None:
|
|
66
|
+
regex = re.compile(fnmatch.translate(pattern))
|
|
67
|
+
self._compiled_patterns[pattern] = regex
|
|
68
|
+
return regex
|
|
69
|
+
|
|
70
|
+
def _get_pattern_events(self, target: str) -> tuple[Event, ...]:
|
|
71
|
+
cached = self._pattern_cache.get(target)
|
|
72
|
+
if cached is not None:
|
|
73
|
+
return cached
|
|
74
|
+
|
|
75
|
+
matched_events: list[Event] = []
|
|
76
|
+
for key, event in tuple(self.pattern_items.items()):
|
|
77
|
+
try:
|
|
78
|
+
if self._compile_pattern(key).match(target):
|
|
79
|
+
matched_events.append(event)
|
|
80
|
+
except Exception:
|
|
81
|
+
logger.error(traceback.format_exc())
|
|
82
|
+
|
|
83
|
+
result = tuple(matched_events)
|
|
84
|
+
self._pattern_cache[target] = result
|
|
85
|
+
return result
|
|
86
|
+
|
|
87
|
+
def set(self, target: str, *args: Any):
|
|
88
|
+
if not self.exact_items and not self.pattern_items:
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
exact_event = self.exact_items.get(target)
|
|
92
|
+
if exact_event is not None:
|
|
93
|
+
try:
|
|
94
|
+
exact_event.set(target, *args)
|
|
95
|
+
except Exception:
|
|
96
|
+
logger.error(traceback.format_exc())
|
|
97
|
+
|
|
98
|
+
for event in self._get_pattern_events(target):
|
|
99
|
+
try:
|
|
100
|
+
event.set(target, *args)
|
|
101
|
+
except Exception:
|
|
102
|
+
logger.error(traceback.format_exc())
|
|
103
|
+
|
|
104
|
+
def __add__(self, item: list):
|
|
105
|
+
target, callback = item[0], item[1]
|
|
106
|
+
bucket = self._bucket(target)
|
|
107
|
+
bucket.setdefault(target, Event()).__iadd__(callback)
|
|
108
|
+
|
|
109
|
+
if self._is_pattern(target):
|
|
110
|
+
self._compiled_patterns.setdefault(target, self._compile_pattern(target))
|
|
111
|
+
self._clear_pattern_cache()
|
|
112
|
+
|
|
113
|
+
return self
|
|
114
|
+
|
|
115
|
+
def __sub__(self, item: list):
|
|
116
|
+
target, callback = item[0], item[1]
|
|
117
|
+
bucket = self._bucket(target)
|
|
118
|
+
bucket.setdefault(target, Event()).__isub__(callback)
|
|
119
|
+
|
|
120
|
+
if self._is_pattern(target):
|
|
121
|
+
self._clear_pattern_cache()
|
|
122
|
+
|
|
123
|
+
return self
|
|
124
|
+
|
|
125
|
+
def __iadd__(self, item: list):
|
|
126
|
+
target, callback = item[0], item[1]
|
|
127
|
+
bucket = self._bucket(target)
|
|
128
|
+
bucket.setdefault(target, Event()).__iadd__(callback)
|
|
129
|
+
|
|
130
|
+
if self._is_pattern(target):
|
|
131
|
+
self._compiled_patterns.setdefault(target, self._compile_pattern(target))
|
|
132
|
+
self._clear_pattern_cache()
|
|
133
|
+
|
|
134
|
+
return self
|
|
135
|
+
|
|
136
|
+
def __isub__(self, item: list):
|
|
137
|
+
target, callback = item[0], item[1]
|
|
138
|
+
bucket = self._bucket(target)
|
|
139
|
+
bucket.setdefault(target, Event()).__isub__(callback)
|
|
140
|
+
|
|
141
|
+
if self._is_pattern(target):
|
|
142
|
+
self._clear_pattern_cache()
|
|
143
|
+
|
|
144
|
+
return self
|
|
145
|
+
|
|
146
|
+
def __len__(self) -> int:
|
|
147
|
+
return len(self.exact_items) + len(self.pattern_items)
|