Source code for fgen.wrapping_strategies.enum

"""
Wrapping strategy for enum types

The enum values are passed as integers across the Python-Fortran interface.
"""
from __future__ import annotations

from collections.abc import Iterable
from pathlib import Path
from typing import Optional, Union

from attrs import define

from fgen.data_models import Method, Module, MultiReturn, Value
from fgen.jinja_environment import (
    JINJA_ENV,
    get_template_in_directory,
)
from fgen.wrapping_strategies.information_injection import (
    inject_wrapping_strategy_information,
)
from fgen.wrapping_strategies.passing_to_fortran_steps import (
    PassingToFortranSteps,
)
from fgen.wrapping_strategies.receiving_from_python_steps import (
    ReceivingFromPythonSteps,
)


[docs]@define class WrappingStrategyEnum: """ Wrapping strategy for enums """ int_value_suffix: str = "_int_value" """ Suffix to add to the variable name to indicate that this is the integer equivalent """ def get_fortran_wrapper_module_getter( # noqa: D102 self, value: Union[MultiReturn, Value] ) -> str: return f"iget_{value.definition.name}" def get_fortran_wrapper_module_setter( # noqa: D102 self, value: Union[MultiReturn, Value] ) -> str: return f"iset_{value.definition.name}" def get_fortran_wrapper_statement_declarations_getters_and_setters( # noqa: D102 self, value: Union[MultiReturn, Value] ) -> list[str]: return [ f"public :: {method_name}" for method_name in ( self.get_fortran_wrapper_module_getter(value), self.get_fortran_wrapper_module_setter(value), ) ] def get_fortran_wrapper_statement_declarations_for_returning_method_result_to_python( # noqa: E501, D102 self, method: Method, prefix: str ) -> list[str]: return [f"public :: {prefix}{method.name}"] def get_receiving_from_python_steps( # noqa: D102, PLR0913 self, value: Union[MultiReturn, Value], dynamic_unit: Optional[str] = None, providing_module: Optional[Module] = None, requesting_module: Optional[Module] = None, get_instance_callable_name: Optional[str] = None, ) -> ReceivingFromPythonSteps: return ReceivingFromPythonSteps( postprocessing_fortran_calls=None, fortran_wrapper_callable_parameters=( ( value.definition.name, value.definition.as_fortran_data_type().fortran_type_attribute_declaration, value, ), ), fortran_module_callable_args=(value,), ) def get_type_attribute_declaration_for_value_to_pass_to_original_fortran_module( # noqa: D102 self, value: Union[MultiReturn, Value] ) -> str: return ( value.definition.as_fortran_data_type().fortran_type_attribute_declaration ) def get_fortran_for_getter( # noqa: D102 self, value: Union[MultiReturn, Value], class_being_wrapped: str, value_manager_get_free_instance_number: Optional[str] = None, value_manager_get_instance: Optional[str] = None, ) -> str: template = get_template_in_directory( "fortran-for-getter.f90.jinja", Path(__file__).parent, JINJA_ENV, ) result = template.render( return_value=value, fortran_wrapper_module_callable=self.get_fortran_wrapper_module_getter( value ), class_being_wrapped=class_being_wrapped, fortran_module_attribute=value.definition.name, ) return inject_wrapping_strategy_information( result, value=value, wrapping_strategy=self, comment_character="!" ) def get_fortran_for_method_returning_wrapped_type( # noqa: D102, PLR0913 self, fortran_wrapper_module_callable: str, receiving_from_python_steps: ReceivingFromPythonSteps, return_value: Union[MultiReturn, Value], class_being_wrapped: str, method_name: str, return_value_manager_get_free_instance_number: Optional[str], return_value_manager_get_instance: Optional[str], ) -> str: template = get_template_in_directory( "fortran-for-method-returning-wrapped-type.f90.jinja", Path(__file__).parent, JINJA_ENV, ) input_params = ( receiving_from_python_steps.fortran_wrapper_callable_parameter_names ) result = template.render( fortran_wrapper_module_callable=fortran_wrapper_module_callable, return_value=return_value, input_params=input_params, receiving_from_python_steps=receiving_from_python_steps, class_being_wrapped=class_being_wrapped, method_name=method_name, ) return inject_wrapping_strategy_information( result, value=return_value, wrapping_strategy=self, comment_character="!" ) def get_python_user_facing_name( # noqa: D102 self, value: Union[MultiReturn, Value] ) -> str: return value.definition.name def get_python_post_verify_units_input_type_annotation( # noqa: D102 self, value: Union[MultiReturn, Value] ) -> str: return value.definition.as_fortran_data_type().python_equivalent_type_annotation def get_python_return_type_annotation( # noqa: D102 self, value: Union[MultiReturn, Value] ) -> str: return value.definition.as_fortran_data_type().python_equivalent_type_annotation def get_python_argument_declaration_type_annotation( # noqa: D102 self, value: Value ) -> str: return value.definition.as_fortran_data_type().python_equivalent_type_annotation def get_python_getter_docstring(self, value: Value) -> str: # noqa: D102 template = get_template_in_directory( "python-getter-docstring.py.jinja", Path(__file__).parent, JINJA_ENV ) result = template.render(attribute=value) return result def get_python_setter_docstring(self, value: Value) -> str: # noqa: D102 return f"Setter for ``{value.definition.name}``" def generate_python_for_fortran_return_value_processing( # noqa: D102 self, value: Union[MultiReturn, Value], fortran_module_callable: str, fortran_module_callable_args: Iterable[str], dynamic_unit: Optional[str], ) -> str: return_type = self.get_python_return_type_annotation(value) template = get_template_in_directory( "python-for-fortran-return-value-processing.py.jinja", Path(__file__).parent, JINJA_ENV, ) result = template.render( result_name=self.get_python_user_facing_name(value), fortran_module_callable=fortran_module_callable, fortran_module_callable_args=fortran_module_callable_args, return_type=return_type, int_value_suffix=self.int_value_suffix, ) return inject_wrapping_strategy_information( result, value=value, wrapping_strategy=self, comment_character="#" ) def get_passing_to_fortran_steps( # noqa: D102 self, value: Union[MultiReturn, Value], dynamic_unit: Optional[str], ) -> PassingToFortranSteps: argument_int_value = f"{value.definition.name}{self.int_value_suffix}" template = get_template_in_directory( "python-for-preparing-to-pass-to-fortran.py.jinja", Path(__file__).parent, JINJA_ENV, ) preparatory_python_calls = template.render( argument_user_facing=self.get_python_user_facing_name(value), argument_int_value=argument_int_value, ) return PassingToFortranSteps( preparatory_python_calls=inject_wrapping_strategy_information( preparatory_python_calls, value=value, wrapping_strategy=self, comment_character="#", ), fortran_module_callable_args=((value.definition.name, argument_int_value),), )