1 # -----------------------------------------------------------------------------
2 # Copyright © 2023- The Spyder Development Team
4 # Released under the terms of the MIT License
5 # (see LICENSE.txt for details)
6 # -----------------------------------------------------------------------------
8 """Provides utility functions for use by QtPy itself."""
9 from functools
import wraps
10 from typing
import TYPE_CHECKING
15 from qtpy
.QtWidgets
import QAction
18 def _wrap_missing_optional_dep_error(
22 wrapper
=qtpy
.QtModuleNotInstalledError
,
25 """Create a __cause__-chained wrapper error for a missing optional dep."""
26 qtpy_error
= wrapper(**wrapper_kwargs
)
27 import_error
.__cause
__ = attr_error
28 qtpy_error
.__cause
__ = import_error
32 def getattr_missing_optional_dep(name
, module_name
, optional_names
):
33 """Wrap AttributeError in a special error if it matches."""
34 attr_error
= AttributeError(
35 f
"module {module_name!r} has no attribute {name!r}",
37 if name
in optional_names
:
38 return _wrap_missing_optional_dep_error(
40 **optional_names
[name
],
45 def possibly_static_exec(cls
, *args
, **kwargs
):
46 """Call `self.exec` when `self` is given or a static method otherwise."""
47 if not args
and not kwargs
:
48 # A special case (`cls.exec_()`) to avoid the function resolving error
50 if isinstance(args
[0], cls
):
51 if len(args
) == 1 and not kwargs
:
52 # A special case (`self.exec_()`) to avoid the function resolving error
54 return args
[0].exec(*args
[1:], **kwargs
)
56 return cls
.exec(*args
, **kwargs
)
59 def possibly_static_exec_(cls
, *args
, **kwargs
):
60 """Call `self.exec` when `self` is given or a static method otherwise."""
61 if not args
and not kwargs
:
62 # A special case (`cls.exec()`) to avoid the function resolving error
64 if isinstance(args
[0], cls
):
65 if len(args
) == 1 and not kwargs
:
66 # A special case (`self.exec()`) to avoid the function resolving error
67 return args
[0].exec_()
68 return args
[0].exec_(*args
[1:], **kwargs
)
70 return cls
.exec_(*args
, **kwargs
)
73 def add_action(self
, *args
, old_add_action
):
74 """Re-order arguments of `addAction` to backport compatibility with Qt>=6.3."""
75 from qtpy
.QtCore
import QObject
76 from qtpy
.QtGui
import QIcon
, QKeySequence
81 shortcut
: QKeySequence | QKeySequence
.StandardKey |
str |
int
90 (QKeySequence
, QKeySequence
.StandardKey
, str, int),
98 action
= old_add_action(self
, text
)
99 action
.setShortcut(shortcut
)
101 text
, shortcut
, receiver
= args
102 action
= old_add_action(self
, text
, receiver
)
103 action
.setShortcut(shortcut
)
105 text
, shortcut
, receiver
, member
= args
106 action
= old_add_action(self
, text
, receiver
, member
, shortcut
)
108 return old_add_action(self
, *args
)
117 (QKeySequence
, QKeySequence
.StandardKey
, str, int),
124 icon
, text
, shortcut
= args
125 action
= old_add_action(self
, icon
, text
)
126 action
.setShortcut(QKeySequence(shortcut
))
128 icon
, text
, shortcut
, receiver
= args
129 action
= old_add_action(self
, icon
, text
, receiver
)
130 action
.setShortcut(QKeySequence(shortcut
))
132 icon
, text
, shortcut
, receiver
, member
= args
133 action
= old_add_action(
139 QKeySequence(shortcut
),
142 return old_add_action(self
, *args
)
144 return old_add_action(self
, *args
)
147 def static_method_kwargs_wrapper(func
, from_kwarg_name
, to_kwarg_name
):
149 Helper function to manage `from_kwarg_name` to `to_kwarg_name` kwargs name changes in static methods.
151 Makes static methods accept the `from_kwarg_name` kwarg as `to_kwarg_name`.
156 def _from_kwarg_name_to_kwarg_name_(*args
, **kwargs
):
157 if from_kwarg_name
in kwargs
:
158 kwargs
[to_kwarg_name
] = kwargs
.pop(from_kwarg_name
)
159 return func(*args
, **kwargs
)
161 return _from_kwarg_name_to_kwarg_name_