Repository: matplotlib/matplotlib
File: lib/matplotlib/artist.py (Python)

Code before:

        Parameters
        ----------
        props : dict
            Dictionary of properties (keys) and their new values.

        Returns
        -------
        list
            A list of return values from the configured setters.

        Notes
        -----
        This method is similar to `.Artist.set`, but differs in two ways:

        1. **No Normalization**: It does not normalize property names. It only
           supports properties where a corresponding ``set_<prop>`` method
           explicitly exists.
        2. **No Validation**: It does not check for duplicate aliases. If both
           an alias and its full name are passed (e.g., ``{'lw': 1, 'linewidth': 2}``),
           the last value in the dictionary takes precedence, whereas `.set` would
           raise an error.

        For example, if an Artist defines ``set_property`` but not ``set_alias``,
        ``set(alias=1)`` will work (via normalization), whereas
        ``update({'alias': 1})`` will fail.
        """
        return self._update_props(
            props, "{cls.__name__!r} object has no property {prop_name!r}")

    def _internal_update(self, kwargs):
        """
        Update artist properties without prenormalizing them, but generating
        errors as if calling `set`.

        The lack of prenormalization is to maintain backcompatibility.
        """
        return self._update_props(
            kwargs, "{cls.__name__}.set() got an unexpected keyword argument "
            "{prop_name!r}")

    def set(self, **kwargs):
        # docstring and signature are auto-generated via
        # Artist._update_set_signature_and_docstring() at the end of the
        # module.
        return self._internal_update(cbook.normalize_kwargs(kwargs, self))

    @contextlib.contextmanager
    def _cm_set(self, **kwargs):
        """
        `.Artist.set` context-manager that restores original values at exit.

Review comment (suggestion):
```suggestion
```
Not needed anymore. The admonition contains the relevant information.

Code after:

        .. admonition:: Discouraged

            This method exists for historic reasons. Please use `.Artist.set` instead.
            ``artist.update(props)`` is nowadays almost identical to
            ``artist.set(**props)`` with the only difference that ``set`` will
            additionally check that a property is not specified multiple times
            through aliases.

        Parameters
        ----------
        props : dict
            Dictionary of properties (keys) and their new values.

        Returns
        -------
        list
            A list of return values from the configured setters.

        """
        return self._update_props(
            props, "{cls.__name__!r} object has no property {prop_name!r}")

    def _internal_update(self, kwargs):
        """
        Update artist properties without prenormalizing them, but generating
        errors as if calling `set`.

        The lack of prenormalization is to maintain backcompatibility.
        """
        return self._update_props(
            kwargs, "{cls.__name__}.set() got an unexpected keyword argument "
            "{prop_name!r}")

    def set(self, **kwargs):
        # docstring and signature are auto-generated via
        # Artist._update_set_signature_and_docstring() at the end of the
        # module.
        return self._internal_update(cbook.normalize_kwargs(kwargs, self))

    @contextlib.contextmanager
    def _cm_set(self, **kwargs):
        """
        `.Artist.set` context-manager that restores original values at exit.
        """
        orig_vals = {k: getattr(self, f"get_{k}")() for k in kwargs}
        try:
            self.set(**kwargs)
            yield
        finally:
            self.set(**orig_vals)