Coverage for bilby/core/utils/introspection.py: 97%
34 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-05-06 04:57 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-05-06 04:57 +0000
1import inspect
2import types
5def infer_parameters_from_function(func):
6 """ Infers the arguments of a function
7 (except the first arg which is assumed to be the dep. variable).
9 Throws out `*args` and `**kwargs` type arguments
11 Can deal with type hinting!
13 Parameters
14 ==========
15 func: function or method
16 The function or method for which the parameters should be inferred.
18 Returns
19 =======
20 list: A list of strings with the parameters
22 Raises
23 ======
24 ValueError
25 If the object passed to the function is neither a function nor a method.
27 Notes
28 =====
29 In order to handle methods the `type` of the function is checked, and
30 if a method has been passed the first *two* arguments are removed rather than just the first one.
31 This allows the reference to the instance (conventionally named `self`)
32 to be removed.
33 """
34 if isinstance(func, types.MethodType):
35 return infer_args_from_function_except_n_args(func=func, n=2)
36 elif isinstance(func, types.FunctionType):
37 return _infer_args_from_function_except_for_first_arg(func=func)
38 else:
39 raise ValueError("This doesn't look like a function.")
42def infer_args_from_method(method):
43 """ Infers all arguments of a method except for `self`
45 Throws out `*args` and `**kwargs` type arguments.
47 Can deal with type hinting!
49 Returns
50 =======
51 list: A list of strings with the parameters
52 """
53 return infer_args_from_function_except_n_args(func=method, n=1)
56def infer_args_from_function_except_n_args(func, n=1):
57 """ Inspects a function to find its arguments, and ignoring the
58 first n of these, returns a list of arguments from the function's
59 signature.
61 Parameters
62 ==========
63 func : function or method
64 The function from which the arguments should be inferred.
65 n : int
66 The number of arguments which should be ignored, staring at the beginning.
68 Returns
69 =======
70 parameters: list
71 A list of parameters of the function, omitting the first `n`.
73 Extended Summary
74 ================
75 This function is intended to allow the handling of named arguments
76 in both functions and methods; this is important, since the first
77 argument of an instance method will be the instance.
79 See Also
80 ========
81 infer_args_from_method: Provides the arguments for a method
82 infer_args_from_function: Provides the arguments for a function
83 infer_args_from_function_except_first_arg: Provides all but first argument of a function or method.
85 Examples
86 ========
88 .. code-block:: python
90 >>> def hello(a, b, c, d):
91 >>> pass
92 >>>
93 >>> infer_args_from_function_except_n_args(hello, 2)
94 ['c', 'd']
96 """
97 parameters = inspect.getfullargspec(func).args
98 del parameters[:n]
99 return parameters
102def _infer_args_from_function_except_for_first_arg(func):
103 return infer_args_from_function_except_n_args(func=func, n=1)
106def get_dict_with_properties(obj):
107 property_names = [p for p in dir(obj.__class__)
108 if isinstance(getattr(obj.__class__, p), property)]
109 dict_with_properties = obj.__dict__.copy()
110 for key in property_names:
111 dict_with_properties[key] = getattr(obj, key)
112 return dict_with_properties
115def get_function_path(func):
116 if hasattr(func, "__module__") and hasattr(func, "__name__"):
117 return "{}.{}".format(func.__module__, func.__name__)
118 else:
119 return func
122class PropertyAccessor(object):
123 """
124 Generic descriptor class that allows handy access of properties without long
125 boilerplate code. The properties of Interferometer are defined as instances
126 of this class.
128 This avoids lengthy code like
130 .. code-block:: python
132 @property
133 def length(self):
134 return self.geometry.length
136 @length_setter
137 def length(self, length)
138 self.geometry.length = length
140 in the Interferometer class
141 """
143 def __init__(self, container_instance_name, property_name):
144 self.property_name = property_name
145 self.container_instance_name = container_instance_name
147 def __get__(self, instance, owner):
148 return getattr(getattr(instance, self.container_instance_name), self.property_name)
150 def __set__(self, instance, value):
151 setattr(getattr(instance, self.container_instance_name), self.property_name, value)