77
88from aiida .common .datastructures import CalcInfo , CodeInfo
99from aiida .common .folders import Folder
10+ from aiida .common .lang import override
1011from aiida .engine import CalcJob , CalcJobProcessSpec
1112from aiida .orm import (
1213 Data ,
@@ -37,17 +38,14 @@ class PythonJob(CalcJob):
3738 _DEFAULT_INPUT_FILE = "script.py"
3839 _DEFAULT_OUTPUT_FILE = "aiida.out"
3940 _DEFAULT_PARENT_FOLDER_NAME = "./parent_folder/"
41+ _SOURCE_CODE_KEY = "source_code"
4042
4143 @classmethod
4244 def define (cls , spec : CalcJobProcessSpec ) -> None : # type: ignore[override]
4345 """Define the process specification, including its inputs, outputs and known exit codes."""
4446 super ().define (spec )
45- spec .input_namespace ("function_data" )
46- spec .input ("function_data.name" , valid_type = Str , serializer = to_aiida_type )
47- spec .input ("function_data.source_code" , valid_type = Str , serializer = to_aiida_type , required = False )
47+ spec .input_namespace ("function_data" , dynamic = True , required = True )
4848 spec .input ("function_data.outputs" , valid_type = List , serializer = to_aiida_type , required = False )
49- spec .input ("function_data.pickled_function" , valid_type = Data , required = False )
50- spec .input ("function_data.mode" , valid_type = Str , serializer = to_aiida_type , required = False )
5149 spec .input ("process_label" , valid_type = Str , serializer = to_aiida_type , required = False )
5250 spec .input_namespace ("function_inputs" , valid_type = Data , required = False )
5351 spec .input (
@@ -175,13 +173,9 @@ def define(cls, spec: CalcJobProcessSpec) -> None: # type: ignore[override]
175173 def get_function_name (self ) -> str :
176174 """Return the name of the function to run."""
177175 if "name" in self .inputs .function_data :
178- name = self .inputs .function_data .name . value
176+ name = self .inputs .function_data .name
179177 else :
180- try :
181- name = self .inputs .function_data .pickled_function .value .__name__
182- except AttributeError :
183- # If a user doesn't specify name, fallback to something generic
184- name = "anonymous_function"
178+ name = "anonymous_function"
185179 return name
186180
187181 def _build_process_label (self ) -> str :
@@ -192,6 +186,13 @@ def _build_process_label(self) -> str:
192186 name = self .get_function_name ()
193187 return f"PythonJob<{ name } >"
194188
189+ @override
190+ def _setup_db_record (self ) -> None :
191+ """Set up the database record for the process."""
192+ super ()._setup_db_record ()
193+ if "source_code" in self .inputs .function_data :
194+ self .node .base .attributes .set (self ._SOURCE_CODE_KEY , self .inputs .function_data .source_code )
195+
195196 def on_create (self ) -> None :
196197 """Called when a Process is created."""
197198 super ().on_create ()
@@ -223,19 +224,13 @@ def prepare_for_submission(self, folder: Folder) -> CalcInfo:
223224 else :
224225 parent_folder_name = self ._DEFAULT_PARENT_FOLDER_NAME
225226
226- function_data = self .inputs .function_data
227-
228227 # Build the Python script
229- source_code = function_data .get ("source_code" )
230- if "pickled_function" in self .inputs .function_data :
231- pickled_function = self .inputs .function_data .pickled_function .get_serialized_value ()
232- else :
233- pickled_function = None
234- # Generate script.py content
228+ source_code = self .node .base .attributes .get (self ._SOURCE_CODE_KEY , None )
229+ pickled_function = self .inputs .function_data .pickled_function
235230 function_name = self .get_function_name () # or some user-defined name
236231 script_content = generate_script_py (
237232 pickled_function = pickled_function ,
238- source_code = source_code . value if source_code else None ,
233+ source_code = source_code ,
239234 function_name = function_name ,
240235 )
241236
0 commit comments