Coverage for /Users/Newville/Codes/xraylarch/larch/closure.py: 76%
46 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 10:08 -0600
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 10:08 -0600
1#!/usr/bin/env python
3import inspect
5class Closure(object):
6 """Give a reference to a function with arguments so that it
7 can be called later, optionally changing the argument list.
9 The class provids a simple callback function which is then
10 executed when called as a function. It can be defined as:
12 >>>def my_action(x=None):
13 ... print 'my action: x = ', x
14 >>>c = Closure(my_action,x=1)
16 and used as:
17 >>>c()
18 my action: x = 1
19 >>>c(x=2)
20 my action: x = 2
22 The code is based on the Command class from
23 J. Grayson's Tkinter book.
24 """
25 def __init__(self, func=None, _name=None, _larch=None, **kwds):
26 self.func = func
27 self.kwds = kwds
28 self.__name__ = _name
29 if _name is None:
30 self.__name__ = self.func.__name__
32 self._larch = None
33 argspec = inspect.getfullargspec(self.func)
34 self._haskwargs = argspec.varkw is not None
35 self._hasvarargs = argspec.varargs is not None
36 self._argvars = argspec.args
37 if (_larch is not None and ('_larch' in argspec.args or
38 '_larch' in argspec.kwonlyargs)):
39 self._larch = _larch
40 self._nkws = 0
41 if argspec.defaults is not None:
42 self._nkws = len(argspec.defaults)
43 self._nargs = len(self._argvars) - self._nkws
44 self.argspec = argspec
46 def __repr__(self):
47 return "<function %s, file=%s>" % (self.__name__, self.__file__)
49 __str__ = __repr__
51 @property
52 def __doc__(self):
53 if self.func is not None:
54 return self.func.__doc__
56 @property
57 def __file__(self):
58 fname = getattr(self.func, '__filename__', 'unknown')
59 if fname in ('unknown', None) and hasattr(self.func, '__code__'):
60 fname = self.func.__code__.co_filename
61 return fname
63 def __call__(self, *args, **c_kwds):
64 if self.func is None:
65 return None
66 kwds = self.kwds.copy()
67 kwds.update(c_kwds)
68 ngot = len(args) + len(kwds)
69 nexp = self._nargs + self._nkws
70 if not self._haskwargs and not self._hasvarargs and (ngot > nexp):
71 exc_msg = "%s expected %i arguments, got %i "
72 raise TypeError(exc_msg % (self.__name__, nexp, ngot))
73 if self._larch is not None and kwds.get('_larch', None) is None:
74 kwds['_larch'] = self._larch
76 return self.func(*args, **kwds)