Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate user.me() returning None #78

Merged
merged 3 commits into from Feb 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGES.rst
Expand Up @@ -4,6 +4,13 @@ Change Log
Unreleased
----------

**Deprecated**

* :meth:`.me` will no longer return ``None`` when called in read-only mode starting in
Async PRAW 8. A ``DeprecationWarning`` will be issued. To switch forward to the Async
PRAW 8 behavior set ``praw8_raise_exception_on_me=True`` in your
``asyncpraw.Reddit(...)`` call.

7.1.1 (2021/02/11)
------------------

Expand Down
4 changes: 4 additions & 0 deletions asyncpraw/exceptions.py
Expand Up @@ -218,6 +218,10 @@ class MissingRequiredAttributeException(ClientException):
"""Indicate exceptions caused by not including a required attribute."""


class ReadOnlyException(ClientException):
"""Raised when a method call requires :attr:`.read_only` mode to be disabled."""


class TooLargeMediaException(ClientException):
"""Indicate exceptions from uploading media that's too large."""

Expand Down
26 changes: 21 additions & 5 deletions asyncpraw/models/user.py
@@ -1,7 +1,9 @@
"""Provides the User class."""
from typing import TYPE_CHECKING, AsyncIterator, Dict, 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 AsyncPRAWBase
Expand Down Expand Up @@ -118,18 +120,32 @@ async def me(
) -> Optional["asyncpraw.models.Redditor"]: # pylint: disable=invalid-name
"""Return a :class:`.Redditor` instance for the authenticated user.

In :attr:`~asyncpraw.Reddit.read_only` mode, this method returns ``None``.

:param use_cache: When true, and if this function has been previously
called, returned the cached version (default: True).
: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 read-only mode this method returns ``None``. In Async PRAW 8 this method
will raise :class:`.ReadOnlyException` when called in read-only mode. To
operate in Async PRAW 8 mode, set the config variable
``praw8_raise_exception_on_me`` to True.

"""
if self._reddit.read_only:
return None
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 Async 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 = await self._reddit.get(API_PATH["me"])
self._me = Redditor(self._reddit, _data=user_data)
Expand Down
18 changes: 17 additions & 1 deletion tests/unit/models/test_user.py
@@ -1,10 +1,26 @@
import pytest

from asyncpraw import Reddit
from asyncpraw.exceptions import ReadOnlyException
from asyncpraw.models import User

from .. import UnitTest


class TestUser(UnitTest):
async def test_me__in_read_only_mode(self):
self.reddit = Reddit(
client_id="dummy",
client_secret="dummy",
praw8_raise_exception_on_me=True,
user_agent="dummy",
)
self.reddit._core._requestor._http = None
assert self.reddit.read_only
user = User(self.reddit)
assert await user.me() is None
with pytest.raises(ReadOnlyException):
await user.me()

async def test_me__in_read_only_mode__deprecated(self):
assert self.reddit.read_only
assert await User(self.reddit).me() is None
4 changes: 4 additions & 0 deletions tests/unit/test_deprecations.py
Expand Up @@ -78,6 +78,10 @@ async def test_gild_method(self):
await submission.gild()
assert excinfo.value.args[0] == "`.gild` has been renamed to `.award`."

async def test_reddit_user_me_read_only(self):
with pytest.raises(DeprecationWarning):
await self.reddit.user.me()

def test_synchronous_context_manager(self):
with pytest.raises(DeprecationWarning) as excinfo:
with self.reddit:
Expand Down