code: def test_register_constructor_function_performs_validation():
      registry = DatasetRegistry()
  
      def from_good_function(
          # pylint: disable=unused-argument
          path: str,
          name: Optional[str] = None,
          digest: Optional[str] = None,
      ) -> Dataset:
          pass
  
      registry.register_constructor(from_good_function)
  
      def bad_name_fn(
          # pylint: disable=unused-argument
          name: Optional[str] = None,
          digest: Optional[str] = None,
      ) -> Dataset:
          pass
  
      with pytest.raises(
          MlflowException, match="Constructor name must start with"
      ):
          registry.register_constructor(bad_name_fn)
  
      with pytest.raises(
          MlflowException, match="Constructor name must start with"
      ):
          registry.register_constructor(
              constructor_fn=from_good_function,
              constructor_name="bad_name",
          )
  
      def from_no_name_fn(
          digest: Optional[
              str
          ] = None,  # pylint: disable=unused-argument
      ) -> Dataset:
          pass
  
      with pytest.raises(
          MlflowException,
          match="must define an optional parameter named 'name'",
      ):
          registry.register_constructor(from_no_name_fn)
  
      def from_no_digest_fn(
          name: Optional[str] = None,  # pylint: disable=unused-argument
      ) -> Dataset:
          pass
  
      with pytest.raises(
          MlflowException,
          match="must define an optional parameter named 'digest'",
      ):
          registry.register_constructor(from_no_digest_fn)
  
      def from_bad_return_type_fn(
          # pylint: disable=unused-argument
          path: str,
          name: Optional[str] = None,
          digest: Optional[str] = None,
      ) -> str:
          pass
  
      with pytest.raises(
          MlflowException,
          match="must have a return type annotation.*Dataset",
      ):
          registry.register_constructor(from_bad_return_type_fn)
  
      def from_no_return_type_fn(
          # pylint: disable=unused-argument
          path: str,
          name: Optional[str] = None,
          digest: Optional[str] = None,
      ):
          pass
  
      with pytest.raises(
          MlflowException,
          match="must have a return type annotation.*Dataset",
      ):
          registry.register_constructor(from_no_return_type_fn)
  
file_path: mlflow/tests/data/test_dataset_registry.py
imports: from typing import Optional
  from unittest import mock
  import pytest
  import mlflow.data
  from mlflow.data.dataset import Dataset
  from mlflow.data.dataset_registry import DatasetRegistry, register_constructor
  from mlflow.data.dataset_source_registry import DatasetSourceRegistry, resolve_dataset_source
  from mlflow.exceptions import MlflowException
  from tests.resources.data.dataset import TestDataset
  from tests.resources.data.dataset_source import TestDatasetSource
label_desc: Use image node_id 3 for calling a global function with example usage: test_register_constructor_function_performs_validation() without return types