text: """Provides the User class."""
  from typing import TYPE_CHECKING, Dict, Iterator, List, Optional, Union
  from warnings import warn
  
  from ..const import API_PATH
  from ..exceptions import ReadOnlyException
  from ..models import Preferences
  from ..util.cache import cachedproperty
  from .base import PRAWBase
  from .listing.generator import ListingGenerator
  from .reddit.redditor import Redditor
  from .reddit.subreddit import Subreddit
  
  if TYPE_CHECKING:  # pragma: no cover
      import praw
  
  
  class User(PRAWBase):
      """The user class provides methods for the currently authenticated user."""
  
      @cachedproperty
      def preferences(self) -> "praw.models.Preferences":
          """Get an instance of :class:`~.Preferences`.
  
          The preferences can be accessed as a ``dict`` like so:
  
          .. code-block:: python
  
              preferences = reddit.user.preferences()
              print(preferences["show_link_flair"])
  
          Preferences can be updated via:
  
          .. code-block:: python
  
              reddit.user.preferences.update(show_link_flair=True)
  
          The :meth:`.Preferences.update` method returns the new state of the preferences
          as a ``dict``, which can be used to check whether a change went through. Changes
          with invalid types or parameter names fail silently.
  
          .. code-block:: python
  
              original_preferences = reddit.user.preferences()
              new_preferences = reddit.user.preferences.update(invalid_param=123)
              print(original_preferences == new_preferences)  # True, no change
  
          """
          return Preferences(self._reddit)
  
      def __init__(self, reddit: "praw.Reddit"):
          """Initialize a User instance.
  
          This class is intended to be interfaced with through ``reddit.user``.
  
          """
          super().__init__(reddit, _data=None)
  
      def blocked(self) -> List["praw.models.Redditor"]:
          """Return a RedditorList of blocked Redditors."""
          return self._reddit.get(API_PATH["blocked"])
  
      def contributor_subreddits(
          self, **generator_kwargs: Union[str, int, Dict[str, str]]
      ) -> Iterator["praw.models.Subreddit"]:
          """Return a :class:`.ListingGenerator` of contributor subreddits.
  
          These are subreddits in which the user is an approved user.
  
          Additional keyword arguments are passed in the initialization of
          :class:`.ListingGenerator`.
  
          To print a list of the subreddits that you are an approved user in, try:
  
          .. code-block:: python
  
              for subreddit in reddit.user.contributor_subreddits(limit=None):
                  print(str(subreddit))
  
          """
          return ListingGenerator(
              self._reddit, API_PATH["my_contributor"], **generator_kwargs
          )
  
      def friends(
          self, user: Optional[Union[str, "praw.models.Redditor"]] = None
      ) -> Union[List["praw.models.Redditor"], "praw.models.Redditor"]:
          """Return a RedditorList of friends or a Redditor in the friends list.
  
          :param user: Checks to see if you are friends with the Redditor. Either an
              instance of :class:`.Redditor` or a string can be given.
  
          :returns: A list of Redditors, or a Redditor if you are friends with the given
              Redditor. The Redditor also has friend attributes.
  
          :raises: An instance of :class:`.RedditAPIException` if you are not friends with
              the specified Redditor.
  
          """
          endpoint = (
              API_PATH["friends"]
              if user is None
              else API_PATH["friend_v1"].format(user=str(user))
          )
          return self._reddit.get(endpoint)
  
      def karma(self) -> Dict["praw.models.Subreddit", Dict[str, int]]:
          """Return a dictionary mapping subreddits to their karma.
  
          The returned dict contains subreddits as keys. Each subreddit key contains a
          sub-dict that have keys for ``comment_karma`` and ``link_karma``. The dict is
          sorted in descending karma order.
  
          .. note::
  
              Each key of the main dict is an instance of :class:`~.Subreddit`. It is
              recommended to iterate over the dict in order to retrieve the values,
              preferably through ``dict.items()``.
  
          """
          karma_map = {}
          for row in self._reddit.get(API_PATH["karma"])["data"]:
              subreddit = Subreddit(self._reddit, row["sr"])
              del row["sr"]
              karma_map[subreddit] = row
          return karma_map
  
      def me(
          self, use_cache: bool = True
      ) -> Optional["praw.models.Redditor"]:  # pylint: disable=invalid-name
          """Return a :class:`.Redditor` instance for the authenticated user.
  
          :param use_cache: When true, and if this function has been previously called,
              returned the cached version (default: True).
  
          .. note::
  
              If you change the Reddit instance's authorization, you might want to refresh
              the cached value. Prefer using separate Reddit instances, however, for
              distinct authorizations.
  
          .. deprecated:: 7.2
  
              In :attr:`.read_only` mode this method returns ``None``. In PRAW 8 this
              method will raise :class:`.ReadOnlyException` when called in
              :attr:`.read_only` mode. To operate in PRAW 8 mode, set the config variable
              ``praw8_raise_exception_on_me`` to ``True``.
  
          """
          if self._reddit.read_only:
              if not self._reddit.config.custom.get("praw8_raise_exception_on_me"):
                  warn(
                      "The `None` return value is deprecated, and will raise a"
                      " `ReadOnlyException` beginning with PRAW 8. See documentation for"
                      " forward compatibility options.",
                      category=DeprecationWarning,
                      stacklevel=2,
                  )
                  return None
              raise ReadOnlyException("`user.me()` does not work in read_only mode")
          if "_me" not in self.__dict__ or not use_cache:
              user_data = self._reddit.get(API_PATH["me"])
              self._me = Redditor(self._reddit, _data=user_data)
          return self._me
  
      def moderator_subreddits(
          self, **generator_kwargs: Union[str, int, Dict[str, str]]
      ) -> Iterator["praw.models.Subreddit"]:
          """Return a :class:`.ListingGenerator` subreddits that the user moderates.
  
          Additional keyword arguments are passed in the initialization of
          :class:`.ListingGenerator`.
  
          To print a list of the names of the subreddits you moderate, try:
  
          .. code-block:: python
  
              for subreddit in reddit.user.moderator_subreddits(limit=None):
                  print(str(subreddit))
  
          .. seealso::
  
              :meth:`.Redditor.moderated`
  
          """
          return ListingGenerator(
              self._reddit, API_PATH["my_moderator"], **generator_kwargs
          )
  
      def multireddits(self) -> List["praw.models.Multireddit"]:
          """Return a list of multireddits belonging to the user."""
          return self._reddit.get(API_PATH["my_multireddits"])
  
      def subreddits(
          self, **generator_kwargs: Union[str, int, Dict[str, str]]
      ) -> Iterator["praw.models.Subreddit"]:
          """Return a :class:`.ListingGenerator` of subreddits the user is subscribed to.
  
          Additional keyword arguments are passed in the initialization of
          :class:`.ListingGenerator`.
  
          To print a list of the subreddits that you are subscribed to, try:
  
          .. code-block:: python
  
              for subreddit in reddit.user.subreddits(limit=None):
                  print(str(subreddit))
  
          """
          return ListingGenerator(
              self._reddit, API_PATH["my_subreddits"], **generator_kwargs
          )
  
      def trusted(self) -> List["praw.models.Redditor"]:
          """Return a RedditorList of trusted Redditors.
  
          To display the usernames of your trusted users and the times at which you
          decided to trust them, try:
  
          .. code-block:: python
  
              trusted_users = reddit.user.trusted()
              for user in trusted_users:
                  print(f"User: {user.name}, time: {user.date}")
  
          """
          return self._reddit.get(API_PATH["trusted"])
  