def test_dynamic_shape_partial_inputs(self, backend, compute_unit, specify_input):
        """
        The `inputs` param in `ct.convert` is partially provided, where the TF model has two inputs
        while we only provide one in `inputs` param. So another input in the TF model with `None`
        dim will have a range shape where lower-bound/default/upper-bound are sanitized to finite
        numbers and warns users.
        """
        convert_to = backend[0]
        last_dim = 16 if specify_input == "input_1" else 4
        inputs = [
            ct.TensorType(
                shape=ct.Shape(
                    shape=(
                        1,
                        3,
                        ct.RangeDim(2, 10, default=8),
                        ct.RangeDim(4, 20, default=last_dim),
                    )
                ),
                name=specify_input,
            )
        ]

        if convert_to == "mlprogram":
            with pytest.warns(
                UserWarning,
                match="Some dimensions in the input shape are unknown, hence they are set to "
                "flexible ranges with lower bound and default value = 1, and upper bound = 2. "
                "To set different values for the default shape and upper bound, please use "
                "the ct.RangeDim.*",
            ):
                mlmodel = ct.convert(
                    self.model,
                    source="tensorflow",
                    inputs=inputs,
                    convert_to=convert_to,
                    compute_units=compute_unit,
                )
        else:
            mlmodel = ct.convert(
                self.model,
                source="tensorflow",
                inputs=inputs,
                convert_to=convert_to,
                compute_units=compute_unit,
            )

        spec = mlmodel.get_spec()
        # Notice the input in spec is not ordered, so need to use name to find input_1 and input_2.
        for input_spec in spec.description.input:
            if input_spec.name == "input_1":
                input_1_spec = input_spec
            elif input_spec.name == "input_2":
                input_2_spec = input_spec
        assert (
            list(input_1_spec.type.multiArrayType.shape) == [1, 3, 8, 16]
            if specify_input == "input_1"
            else [1, 1, 1, 16]
        )
        assert (
            list(input_2_spec.type.multiArrayType.shape) == [1, 3, 8, 4]
            if specify_input == "input_2"
            else [1, 1, 1, 4]
        )
        assert (
            input_1_spec.type.multiArrayType.shapeRange.sizeRanges[2].lowerBound == 2
            if specify_input == "input_1"
            else 1
        )
        assert (
            input_2_spec.type.multiArrayType.shapeRange.sizeRanges[2].lowerBound == 2
            if specify_input == "input_2"
            else 1
        )
        default_upper_bound = -1 if convert_to == "neuralnetwork" else 2
        assert (
            input_1_spec.type.multiArrayType.shapeRange.sizeRanges[2].upperBound == 10
            if specify_input == "input_1"
            else default_upper_bound
        )
        assert (
            input_2_spec.type.multiArrayType.shapeRange.sizeRanges[2].upperBound == 10
            if specify_input == "input_2"
            else default_upper_bound
        )

        The `inputs` param in `ct.convert` is partially provided, where the TF model has two inputs
        while we only provide one in `inputs` param. So another input in the TF model with `None`
        dim will have a range shape where lower-bound/default/upper-bound are sanitized to finite
        numbers and warns users.
        
coremltools/converters/mil/test_inputs_outputs_shape.py