Repository: Project-MONAI/MONAI
File: monai/networks/layers/factories.py (Python)

Code before:

    def __init__(self) -> None:
        self.factories: dict[str, Callable] = {}

    def add(self, name: str, func: Callable) -> None:
        """
        Add the factory function to this object under the given name.
        """

        self.factories[name.upper()] = func
        self.__doc__ = (
            "The supported member"
            + ("s are: " if len(self.names) > 1 else " is: ")
            + ", ".join(f"``{name}``" for name in self.names)
            + ".\nPlease see :py:class:`monai.networks.layers.split_args` for additional args parsing."
        )

    def get_constructor(self, factory_name: str, *args) -> Any:
        """
        Get the constructor for the given factory name and arguments.

        Raises:
            TypeError: When ``factory_name`` is not a ``str``.

        """

        if not isinstance(factory_name, str):
            raise TypeError(f"factory_name must a str but is {type(factory_name).__name__}.")

        func = look_up_option(factory_name.upper(), self.factories)
        return func(*args)

    def __getitem__(self, args) -> Any:
        """
        Get the given name or name/arguments pair. If `args` is a callable it is assumed to be the constructor
        itself and is returned, otherwise it should be the factory name or a pair containing the name and arguments.
        """

        # `args[0]` is actually a type or constructor
        if callable(args):
            return args

        # `args` is a factory name or a name with arguments
        if isinstance(args, str):
            name_obj, args = args, ()
        else:
            name_obj, *args = args

        return self.get_constructor(name_obj, *args)

    def __getattr__(self, key):

Review comment (suggestion):
I would also leave this method here if the class inherits from `ComponentStore` and leave it's name so that it's clearer what it is decorating.

Code after:

    def __init__(self, name: str, description: str) -> None:
        super().__init__(name, description)
        self.__doc__ = (
            f"Layer Factory '{name}': {description}\n".strip()
            + "\nPlease see :py:class:`monai.networks.layers.split_args` for additional args parsing."
            + "\n\nThe supported members are:"
        )

    def add_factory_callable(self, name: str, func: Callable, desc: str | None = None) -> None:
        """
        Add the factory function to this object under the given name, with optional description.
        """
        description: str = desc or func.__doc__ or ""
        self.add(name.upper(), description, func)
        # append name to the docstring
        assert self.__doc__ is not None
        self.__doc__ += f"{', ' if len(self.names)>1 else ' '}``{name}``"

    def add_factory_class(self, name: str, cls: type, desc: str | None = None) -> None:
        """
        Adds a factory function which returns the supplied class under the given name, with optional description.
        """
        self.add_factory_callable(name, lambda x=None: cls, desc)

    def factory_function(self, name: str) -> Callable:
        """
        Decorator for adding a factory function with the given name.
        """

        def _add(func: Callable) -> Callable:
            self.add_factory_callable(name, func)
            return func

        return _add

    def get_constructor(self, factory_name: str, *args) -> Any:
        """
        Get the constructor for the given factory name and arguments.

        Raises:
            TypeError: When ``factory_name`` is not a ``str``.

        """

        if not isinstance(factory_name, str):
            raise TypeError(f"factory_name must a str but is {type(factory_name).__name__}.")

        component = look_up_option(factory_name.upper(), self.components)

        return component.value(*args)