7
7
# For further information on the license, see the LICENSE.txt file #
8
8
# For further information please visit http://www.aiida.net #
9
9
###########################################################################
10
- # pylint: disable=cell-var-from-loop
11
10
"""Convenience classes to help building the input dictionaries for Processes."""
12
11
import collections
13
12
13
+ from aiida .orm import Node
14
14
from aiida .engine .processes .ports import PortNamespace
15
15
16
16
__all__ = ('ProcessBuilder' , 'ProcessBuilderNamespace' )
@@ -37,6 +37,10 @@ def __init__(self, port_namespace):
37
37
self ._valid_fields = []
38
38
self ._data = {}
39
39
40
+ # The name and port objects have to be passed to the defined functions as defaults for
41
+ # their arguments, because this way the content at the time of defining the method is
42
+ # saved. If they are used directly in the body, it will try to capture the value from
43
+ # its enclosing scope at the time of being called.
40
44
for name , port in port_namespace .items ():
41
45
42
46
self ._valid_fields .append (name )
@@ -48,14 +52,14 @@ def fgetter(self, name=name):
48
52
return self ._data .get (name )
49
53
elif port .has_default ():
50
54
51
- def fgetter (self , name = name , default = port .default ):
55
+ def fgetter (self , name = name , default = port .default ): # pylint: disable=cell-var-from-loop
52
56
return self ._data .get (name , default )
53
57
else :
54
58
55
59
def fgetter (self , name = name ):
56
60
return self ._data .get (name , None )
57
61
58
- def fsetter (self , value ):
62
+ def fsetter (self , value , name = name ):
59
63
self ._data [name ] = value
60
64
61
65
fgetter .__doc__ = str (port )
@@ -112,6 +116,9 @@ def __setitem__(self, item, value):
112
116
def __delitem__ (self , item ):
113
117
self ._data .__delitem__ (item )
114
118
119
+ def __delattr__ (self , item ):
120
+ self ._data .__delitem__ (item )
121
+
115
122
def _update (self , * args , ** kwds ):
116
123
"""Update the values of the builder namespace passing a mapping as argument or individual keyword value pairs.
117
124
@@ -160,8 +167,6 @@ def _prune(self, value):
160
167
:param value: a nested mapping of port values
161
168
:return: the same mapping but without any nested namespace that is completely empty.
162
169
"""
163
- from aiida .orm import Node
164
-
165
170
if isinstance (value , collections .abc .Mapping ) and not isinstance (value , Node ):
166
171
result = {}
167
172
for key , sub_value in value .items ():
@@ -174,7 +179,7 @@ def _prune(self, value):
174
179
return value
175
180
176
181
177
- class ProcessBuilder (ProcessBuilderNamespace ):
182
+ class ProcessBuilder (ProcessBuilderNamespace ): # pylint: disable=too-many-ancestors
178
183
"""A process builder that helps setting up the inputs for creating a new process."""
179
184
180
185
def __init__ (self , process_class ):
@@ -188,4 +193,5 @@ def __init__(self, process_class):
188
193
189
194
@property
190
195
def process_class (self ):
196
+ """Return the process class for which this builder is constructed."""
191
197
return self ._process_class
0 commit comments