6
6
7
7
import inspect
8
8
import warnings
9
- from typing import Any , Callable , Dict , Optional , Sequence , TypeVar , Union , overload
9
+ from typing import Any , Callable , Dict , Optional , TypeVar , Union , overload
10
10
11
11
from magicgui .application import AppRef
12
12
from magicgui .events import EventEmitter
@@ -46,11 +46,6 @@ class FunctionGui(Container):
46
46
Will be passed to `magic_signature` by default ``None``
47
47
name : str, optional
48
48
A name to assign to the Container widget, by default `function.__name__`
49
- bind : dict, optional
50
- A mapping of parameter names to values. Values supplied here will be permanently
51
- bound to the corresponding parameters: their widgets will be hidden from the GUI
52
- and the value will be used for the corresponding parameter when calling the
53
- function.
54
49
55
50
Raises
56
51
------
@@ -72,10 +67,8 @@ def __init__(
72
67
result_widget : bool = False ,
73
68
param_options : Optional [dict ] = None ,
74
69
name : str = None ,
75
- bind : Dict [str , Any ] = None ,
76
70
** kwargs ,
77
71
):
78
- bind = bind or dict ()
79
72
# consume extra Widget keywords
80
73
extra = set (kwargs ) - {"annotation" , "gui_only" }
81
74
if extra :
@@ -94,8 +87,6 @@ def __init__(
94
87
self ._param_options = param_options
95
88
self .called = EventEmitter (self , type = "called" )
96
89
self ._result_name = ""
97
- self ._bound : Dict [str , Any ] = {}
98
- self .bind (bind )
99
90
self ._call_count : int = 0
100
91
101
92
self ._call_button : Optional [PushButton ] = None
@@ -128,36 +119,6 @@ def reset_call_count(self) -> None:
128
119
"""Reset the call count to 0."""
129
120
self ._call_count = 0
130
121
131
- def bind (self , kwargs : dict ):
132
- """Bind key/value pairs to the function signature.
133
-
134
- Values supplied here will be permanently bound to the corresponding parameters:
135
- their widgets will be hidden from the GUI and the value will be used for the
136
- corresponding parameter when the function is called.
137
-
138
- Parameters
139
- ----------
140
- kwargs : dict, optional
141
- A mapping of parameter names to values to bind.
142
- """
143
- self ._bound .update (kwargs )
144
- for name , value in kwargs .items ():
145
- getattr (self , name ).hide ()
146
-
147
- def unbind (self , args : Sequence ):
148
- """Unbind keys from the function signature.
149
-
150
- Parameters
151
- ----------
152
- args : sequence
153
- A sequence of parameter names. If any are currently bound to a value, the
154
- binding will be cleared and the widget will be shown.
155
- """
156
- for name in args :
157
- if name in self ._bound :
158
- del self ._bound [name ]
159
- getattr (self , name ).show ()
160
-
161
122
def __getattr__ (self , value ):
162
123
"""Catch deprecated _name_changed attribute."""
163
124
if value .endswith ("_changed" ):
@@ -206,9 +167,7 @@ def __call__(self, *args: Any, **kwargs: Any):
206
167
gui() # calls the original function with the current parameters
207
168
"""
208
169
sig = self .to_signature ()
209
- _kwargs = self ._bound .copy ()
210
- _kwargs .update (kwargs )
211
- bound = sig .bind (* args , ** _kwargs )
170
+ bound = sig .bind (* args , ** kwargs )
212
171
bound .apply_defaults ()
213
172
214
173
value = self ._function (* bound .args , ** bound .kwargs )
@@ -239,8 +198,8 @@ def result_name(self, value: str):
239
198
"""Set the result name of this FunctionGui widget."""
240
199
self ._result_name = value
241
200
242
- def copy (self , bind = None ) :
243
- """Return a copy of this FunctionGui, with optionally bound arguments ."""
201
+ def copy (self ) -> "FunctionGui" :
202
+ """Return a copy of this FunctionGui."""
244
203
return FunctionGui (
245
204
function = self ._function ,
246
205
call_button = bool (self ._call_button ),
@@ -250,11 +209,9 @@ def copy(self, bind=None):
250
209
auto_call = self ._auto_call ,
251
210
result_widget = bool (self ._result_widget ),
252
211
app = None ,
253
- bind = bind if bind is not None else self ._bound ,
254
212
)
255
213
256
- # Cache function guis bound to specific instances
257
- _instance_guis : Dict [int , FunctionGui ] = {}
214
+ _bound_instances : Dict [int , FunctionGui ] = {}
258
215
259
216
def __get__ (self , obj , objtype = None ) -> FunctionGui :
260
217
"""Provide descriptor protocol.
@@ -278,11 +235,16 @@ def __get__(self, obj, objtype=None) -> FunctionGui:
278
235
{'self': <__main__.MyClass object at 0x7fb610e455e0>, 'x': 34}
279
236
"""
280
237
if obj is not None :
281
- if id (obj ) not in self ._instance_guis :
238
+ obj_id = id (obj )
239
+ if obj_id not in self ._bound_instances :
282
240
method = getattr (obj .__class__ , self ._function .__name__ )
283
- params_names = list (inspect .signature (method ).parameters )
284
- self ._instance_guis [id (obj )] = self .copy (bind = {params_names [0 ]: obj })
285
- return self ._instance_guis [id (obj )]
241
+ p0 = list (inspect .signature (method ).parameters )[0 ]
242
+ prior , self ._param_options = self ._param_options , {p0 : {"bind" : obj }}
243
+ try :
244
+ self ._bound_instances [obj_id ] = self .copy ()
245
+ finally :
246
+ self ._param_options = prior
247
+ return self ._bound_instances [obj_id ]
286
248
return self
287
249
288
250
def __set__ (self , obj , value ):
@@ -328,7 +290,6 @@ def magicgui(
328
290
auto_call : bool = False ,
329
291
result_widget : bool = False ,
330
292
app : AppRef = None ,
331
- bind : Dict [str , Any ] = None ,
332
293
** param_options : dict ,
333
294
):
334
295
"""Return a :class:`FunctionGui` for ``function``.
@@ -354,11 +315,6 @@ def magicgui(
354
315
by default False
355
316
app : magicgui.Application or str, optional
356
317
A backend to use, by default ``None`` (use the default backend.)
357
- bind : dict, optional
358
- A mapping of parameter names to values. Values supplied here will be permanently
359
- bound to the corresponding parameters: their widgets will be hidden from the GUI
360
- and the value will be used for the corresponding parameter when calling the
361
- function.
362
318
363
319
**param_options : dict of dict
364
320
Any additional keyword arguments will be used as parameter-specific options.
@@ -405,7 +361,6 @@ def inner_func(func: Callable) -> FunctionGui:
405
361
auto_call = auto_call ,
406
362
result_widget = result_widget ,
407
363
app = app ,
408
- bind = bind ,
409
364
)
410
365
func_gui .__wrapped__ = func
411
366
return func_gui
0 commit comments