From 36421b732641959064e36335fa4e485488232946 Mon Sep 17 00:00:00 2001 From: Alexander Goscinski Date: Fri, 27 Feb 2026 19:31:55 +0100 Subject: [PATCH] Make the recursion limit workaround dependent on the aiida-core version With aiida-core v2.8.0 we switched from nest-asyncio to greenlet and therefore do not need to dynamically increase the recursion limit anymore. --- src/aiida_pythonjob/decorator.py | 41 +++++++++++++++++++------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/aiida_pythonjob/decorator.py b/src/aiida_pythonjob/decorator.py index e89b573..1c788b4 100644 --- a/src/aiida_pythonjob/decorator.py +++ b/src/aiida_pythonjob/decorator.py @@ -7,16 +7,24 @@ import typing as t from typing import List -from aiida.engine.processes.functions import FunctionType, get_stack_size +import aiida +from aiida.engine.processes.functions import FunctionType from aiida.manage import get_manager from aiida.orm import ProcessNode from node_graph.socket_spec import SocketSpec +from packaging.version import parse as parse_version from aiida_pythonjob.calculations.pyfunction import PyFunction from aiida_pythonjob.launch import create_inputs, prepare_pyfunction_inputs LOGGER = logging.getLogger(__name__) +_AIIDA_VERSION = parse_version(aiida.__version__) +_NEEDS_RECURSION_LIMIT_WORKAROUND = _AIIDA_VERSION < parse_version("2.8.0") + +if _NEEDS_RECURSION_LIMIT_WORKAROUND: + from aiida.engine.processes.functions import get_stack_size + # The following code is modified from the aiida-core.engine.processes.functions module def pyfunction( @@ -42,25 +50,26 @@ def run_get_node(*args, **kwargs) -> tuple[dict[str, t.Any] | None, "ProcessNode :param kwargs: input keyword arguments to construct the FunctionProcess :return: tuple of the outputs of the process and the process node """ - frame_delta = 1000 - frame_count = get_stack_size() - stack_limit = sys.getrecursionlimit() - LOGGER.info("Executing process function, current stack status: %d frames of %d", frame_count, stack_limit) - - # If the current frame count is more than 80% of the stack limit, or comes within 200 frames, increase the - # stack limit by ``frame_delta``. - if frame_count > min(0.8 * stack_limit, stack_limit - 200): - LOGGER.warning( - "Current stack contains %d frames which is close to the limit of %d. Increasing the limit by %d", - frame_count, - stack_limit, - frame_delta, + if _NEEDS_RECURSION_LIMIT_WORKAROUND: + frame_delta = 1000 + frame_count = get_stack_size() + stack_limit = sys.getrecursionlimit() + LOGGER.info( + "Executing process function, current stack status: %d frames of %d", frame_count, stack_limit ) - sys.setrecursionlimit(stack_limit + frame_delta) + + if frame_count > min(0.8 * stack_limit, stack_limit - 200): + LOGGER.warning( + "Current stack contains %d frames which is close to the limit of %d. Increasing the limit by %d", + frame_count, + stack_limit, + frame_delta, + ) + sys.setrecursionlimit(stack_limit + frame_delta) manager = get_manager() runner = manager.get_runner() - # # Remove all the known inputs from the kwargs + # Remove all the known inputs from the kwargs outputs_spec = kwargs.pop("outputs_spec", None) or outputs inputs_spec = kwargs.pop("inputs_spec", None) or inputs metadata = kwargs.pop("metadata", None)