def _get_case_attr_default_value(value: attr.Attribute) -> str:
    """Return the default value of a CaseDescription."""

    if value.default == attr.NOTHING:
        return ""

    default_value_string = " = "
    if isinstance(value.default, enum.Enum):
        default_value_string += (
            f"{value.default.__class__.__name__}.{value.default.name}")
    elif isinstance(value.default, attr.Factory):
        if value.default.factory is dict:
            default_value_string += "{}"
        elif value.default.factory is list:
            default_value_string += "[]"
        elif is_attrs(value.default.factory):
            default_value_string += f"{value.default.factory.__name__}()"
        else:
            assert False, "Unknown factory"  # pragma: no cover
    elif is_attrs(value.default):
        default_value_string += f"{value.default.__class__.__name__}()"
    else:
        default_value_string += f"{repr(value.default)}"

    return default_value_string
def list_formatted(value: Any) -> str:
    """
    Return a string with a cross-referencing link for the List class and to the refer type.
    """
    name = value.__args__[0].__name__
    list_with_ref = _get_list_reference()
    if is_attrs(value.__args__[0]):
        name = attrs_formatted(value.__args__[0])

    return f"{list_with_ref}[{name}]"
def list_formatted_for_schema(value: Any) -> str:
    """
    Return a string showing a list with the parameters used, if the parameter is an attrs class,
    a cross-referencing link will be added.
    """
    block_indentation = BASE_INDENT + INDENT
    argument = value.__args__[0]
    if is_attrs(argument):
        return f"\n{block_indentation}- {attrs_formatted_for_schema(argument)}"

    return f"\n{block_indentation}- {argument.__name__}"
def dict_formatted(value: Any) -> str:
    """
    Return a string with a cross-referencing link for the Dict class and to the refer type.
    """
    dict_with_reference = _get_dict_reference()
    referenced_value = value.__args__[1]
    if is_attrs(referenced_value):
        name = attrs_formatted(referenced_value)
    elif is_scalar(referenced_value):
        name = _get_scalar_reference()
    elif is_array(referenced_value):
        name = _get_array_reference()
    else:
        name = str(referenced_value).replace("typing.", "")

    return f"{dict_with_reference}[str, {name}]"
Пример #5
0
def convert_dict_to_valid_alfacase_format(
        case_description_dict: Dict[str, ATTRIBUTES],
        enable_flow_style_on_numpy: bool) -> Dict[str, Any]:
    """
    Convert all values of the dictionary to string.

    Note.: strict_yaml only allows "str" values on all attributes in order to render the YAML content.

    :param enable_flow_style_on_numpy:
        Signalize that numpy arrays should dumped with inline list ( pressure: [1, 2] ).

    """
    converted_dict = {}
    for key, value in case_description_dict.items():
        is_empty_dict = isinstance(value, dict) and not value
        ignore = key in IGNORED_PROPERTIES

        if is_empty_dict or value is None or ignore:
            continue

        if is_attrs(value):

            to_dict = partial(attr.asdict, recurse=False)

            if isinstance(value, list):
                converted_value = [
                    convert_dict_to_valid_alfacase_format(
                        to_dict(i), enable_flow_style_on_numpy) for i in value
                ]
            else:
                converted_value = convert_dict_to_valid_alfacase_format(
                    to_dict(value), enable_flow_style_on_numpy)

            if converted_value:
                converted_dict[key] = converted_value
            continue

        if isinstance(value, dict):
            converted_dict[key] = convert_dict_to_valid_alfacase_format(
                value, enable_flow_style_on_numpy)
            continue

        converted_dict[key] = _convert_value_to_valid_alfacase_format(
            value, enable_flow_style_on_numpy)

    return converted_dict
def test_convert_alfacase_to_description(alfacase_to_case_helper, class_, tmp_path):
    """
    Test to convert Alfacase from all classes of alfasim_core.simulation_models.case_description that needs a Alfacase schema
    """
    alfacase_test_config = ALFACASE_TEST_CONFIG_MAP[class_.__name__]
    file_path = tmp_path / "test_case.alfacase"
    description_obtained = alfacase_to_case_helper.generate_description(
        alfacase_test_config
    )
    description_obtained = (
        description_obtained[0]
        if alfacase_test_config.is_sequence
        else description_obtained
    )

    expected_dict = attr.asdict(alfacase_test_config.description_expected)

    description_obtained = (
        description_obtained
        if is_attrs(description_obtained)
        else description_obtained["FakeKey"]
    )
    obtained_dict = attr.asdict(description_obtained)

    # PvtModels that uses Tables has the full path, while YAML has the partial
    # The following inject the full path on the expected_dict, in order to test the obtained_dict
    def fill_pvt_table_path(values):
        if "pvt_models" in values:
            fill_pvt_table_path(values["pvt_models"])
        elif "tables" in values:
            for pvt_name in values["tables"]:
                values["tables"][pvt_name] = (
                    file_path.parent / values["tables"][pvt_name]
                )

        return values

    expected_dict = fill_pvt_table_path(expected_dict)
    # Check that generated test case is correct
    ensure_descriptions_are_equal(expected_dict, obtained_dict, IGNORED_PROPERTIES)

    # Ensure that all properties from the original Case is present in the generated test case
    alfacase_to_case_helper.ensure_description_has_all_properties(
        expected_description_class=class_, obtained_description_obj=description_obtained
    )
def dict_formatted_for_schema(value: Any) -> str:
    """
    Return a string showing a dict with the parameters used, if the parameter is class
    that has a sphinx reference (attr, Scalar, Array) a cross-referencing link will be added.
    """
    lines = f"\n{BASE_INDENT + INDENT}"
    lines += "string: "
    argument = value.__args__[1]

    if is_attrs(argument):
        lines += attrs_formatted_for_schema(argument)
    elif is_union(argument):
        lines += f"{' | '.join(i.__name__.replace('str', 'string') for i in argument.__args__)}"
    elif is_scalar(argument):
        lines += scalar_formatted_for_schema(argument, number_of_indent=2)
    elif is_array(argument):
        lines += array_formatted_for_schema(argument, number_of_indent=2)
    else:
        lines += argument.__name__
    return lines
def union_formatted_for_schema(value: Any) -> str:
    """
    All usages of union on CaseDescription are from the Optional module, so this function will
    return a string showing parameters with a label '# optional' indicating that this field could be
    is not mandatory.
    """
    parameter = value.__args__[0]
    if value.__args__ in ((str, type(None)), (Path, type(None))):
        name = "string"
    elif value.__args__ == (Array, type(None)):
        name = f"{INDENT}"
        name += array_formatted_for_schema(value)
    elif isinstance(parameter, enum.EnumMeta):
        name = f"{enum_formatted_for_schema(parameter)}"
    elif is_attrs(parameter):
        name = f"{attrs_formatted_for_schema(parameter)}"
    elif is_list(parameter):
        name = f"{INDENT}"
        name += list_formatted_for_schema(parameter)
    else:
        name = str(value).replace("typing.", "")
    return name
Пример #9
0
def convert_dict_to_valid_alfacase_format(
    case_description_dict: Dict[str, ATTRIBUTES],
    *,
    enable_flow_style_on_numpy: bool,
    remove_redundant_input_type_data: bool = True,
) -> Dict[str, Any]:
    """
    Convert all values of the dictionary to string.

    Note.: strict_yaml only allows "str" values on all attributes in order to render the YAML content.

    :param enable_flow_style_on_numpy:
        Signalize that numpy arrays should dumped with inline list ( pressure: [1, 2] ).

    :param remove_redundant_input_type_data:
        For transient entries remove input type selector, and the unused constant or curve entries.
    """
    transient_fields: Dict[str, MultiInputType] = {}
    converted_dict = {}
    for key, value in case_description_dict.items():
        is_empty_dict = isinstance(value, dict) and not value
        ignore = key in IGNORED_PROPERTIES

        if is_empty_dict or value is None or ignore:
            continue

        if remove_redundant_input_type_data and isinstance(
                value, constants.MultiInputType):
            assert key.endswith(constants.MULTI_INPUT_TYPE_SUFFIX)
            transient_fields[key] = value

        if is_attrs(value):

            to_dict = partial(attr.asdict, recurse=False)

            if isinstance(value, list):
                converted_value = [
                    convert_dict_to_valid_alfacase_format(
                        to_dict(i),
                        enable_flow_style_on_numpy=enable_flow_style_on_numpy,
                        remove_redundant_input_type_data=
                        remove_redundant_input_type_data,
                    ) for i in value
                ]
            else:
                converted_value = convert_dict_to_valid_alfacase_format(
                    to_dict(value),
                    enable_flow_style_on_numpy=enable_flow_style_on_numpy,
                    remove_redundant_input_type_data=
                    remove_redundant_input_type_data,
                )

            if converted_value:
                converted_dict[key] = converted_value
            continue

        if isinstance(value, dict):
            converted_dict[key] = convert_dict_to_valid_alfacase_format(
                value,
                enable_flow_style_on_numpy=enable_flow_style_on_numpy,
                remove_redundant_input_type_data=
                remove_redundant_input_type_data,
            )
            continue

        converted_dict[key] = _convert_value_to_valid_alfacase_format(
            value, enable_flow_style_on_numpy)

    if remove_redundant_input_type_data:
        for key, multi_input_type in transient_fields.items():
            constant_key = key[:-len(constants.MULTI_INPUT_TYPE_SUFFIX)]
            curve_key = f"{constant_key}_curve"

            converted_dict.pop(key, None)
            if multi_input_type == constants.MultiInputType.Constant:
                converted_dict.pop(curve_key, None)
            elif multi_input_type == constants.MultiInputType.Curve:
                converted_dict.pop(constant_key, None)
            else:  # pragma: no cover
                raise AssertionError(
                    f"unexpected value {key}: {multi_input_type}")

    return converted_dict