def add_multiarray_ndshape_enumeration(spec, feature_name, enumerated_shapes):
    """
    Annotate an input or output MLMultiArray feature in a neural network spec
    to accommodate a range of shapes.

    Add provided enumerated shapes to the list of shapes already present.

    This method is different from ``add_enumerated_multiarray_shapes``, which is applicable
    for rank 5 mapping, SBCHW, and arrays.

    :param spec: MLModel
        The MLModel spec containing the feature

    :param feature_name: str
        The name of the feature for which to add shape range
        information. If the feature is not found in the input or output
        descriptions then an exception is thrown

    :param enumerated_shapes: List[Tuple(int)]
        list of shapes, where each shape is specified as a tuple of integers.


    Examples
    --------
    .. sourcecode:: python

        import coremltools
        from coremltools.models.neural_network import flexible_shape_utils

        spec = coremltools.utils.load_spec("mymodel.mlmodel")
        # say, the default shape of "my_multiarray_featurename" is (2,3)
        flexible_shape_utils.add_multiarray_ndshape_enumeration(
            spec, feature_name="my_multiarray_featurename", enumerated_shapes=[(2, 4), (2, 6)]
        )

    :return:
        None. The spec is updated.
    """
    feature = _get_feature(spec, feature_name)
    _add_multiarray_ndshape_enumeration_for_feature(feature, enumerated_shapes)

    # Bump up specification version
    spec.specificationVersion = max(
        _MINIMUM_NDARRAY_SPEC_VERSION, spec.specificationVersion
    )

    Annotate an input or output MLMultiArray feature in a neural network spec
    to accommodate a range of shapes.

    Add provided enumerated shapes to the list of shapes already present.

    This method is different from ``add_enumerated_multiarray_shapes``, which is applicable
    for rank 5 mapping, SBCHW, and arrays.

    :param spec: MLModel
        The MLModel spec containing the feature

    :param feature_name: str
        The name of the feature for which to add shape range
        information. If the feature is not found in the input or output
        descriptions then an exception is thrown

    :param enumerated_shapes: List[Tuple(int)]
        list of shapes, where each shape is specified as a tuple of integers.


    Examples
    --------
    .. sourcecode:: python

        import coremltools
        from coremltools.models.neural_network import flexible_shape_utils

        spec = coremltools.utils.load_spec("mymodel.mlmodel")
        # say, the default shape of "my_multiarray_featurename" is (2,3)
        flexible_shape_utils.add_multiarray_ndshape_enumeration(
            spec, feature_name="my_multiarray_featurename", enumerated_shapes=[(2, 4), (2, 6)]
        )

    :return:
        None. The spec is updated.
    
coremltools/models/neural_network/flexible_shape_utils.py