Skip to content

Commit

Permalink
Merge fdc13e1 into 3b50870
Browse files Browse the repository at this point in the history
  • Loading branch information
LilSpazJoekp committed Jan 25, 2021
2 parents 3b50870 + fdc13e1 commit cf0f5e8
Show file tree
Hide file tree
Showing 21 changed files with 102 additions and 92 deletions.
21 changes: 19 additions & 2 deletions asyncpraw/models/reddit/base.py
Expand Up @@ -49,14 +49,31 @@ def __hash__(self) -> int:
"""Return the hash of the current instance."""
return hash(self.__class__.__name__) ^ hash(str(self).lower())

def __init__(self, reddit: "Reddit", _data: Optional[Dict[str, Any]]):
def __init__(
self,
reddit: "Reddit",
_data: Optional[Dict[str, Any]],
_extra_attribute_to_check: Optional[str] = None,
_fetched: bool = False,
_str_field: bool = True,
):
"""Initialize a RedditBase instance (or a subclass).
:param reddit: An instance of :class:`~.Reddit`.
"""
super().__init__(reddit, _data=_data)
self._fetched = False
self._fetched = _fetched
if _str_field and self.STR_FIELD not in self.__dict__:
if (
_extra_attribute_to_check is not None
and _extra_attribute_to_check in self.__dict__
):
return
raise ValueError(
f"An invalid value was specified for {self.STR_FIELD}. Check that the "
f"argument for the {self.STR_FIELD} parameter is not empty."
)

def __repr__(self) -> str:
"""Return an object initialization representation of the instance."""
Expand Down
8 changes: 4 additions & 4 deletions asyncpraw/models/reddit/collections.py
Expand Up @@ -112,19 +112,19 @@ def __init__(
:param collection_id: The ID of the Collection (optional).
:param permalink: The permalink of the Collection (optional).
"""
super().__init__(reddit, _data)

if (_data, collection_id, permalink).count(None) != 2:
raise TypeError(
"Exactly one of _data, collection_id, or permalink must be provided."
)

if permalink is not None:
if permalink:
collection_id = self._url_parts(permalink)[4]

if collection_id is not None:
if collection_id:
self.collection_id = collection_id # set from _data otherwise

super().__init__(reddit, _data)

self._info_params = {
"collection_id": self.collection_id,
"include_links": True,
Expand Down
13 changes: 7 additions & 6 deletions asyncpraw/models/reddit/comment.py
@@ -1,10 +1,6 @@
"""Provide the Comment class."""
from typing import TYPE_CHECKING, Any, Dict, Optional, Union

from ...const import API_PATH
from ...exceptions import ClientException, InvalidURL
from ...util.cache import cachedproperty
from ..comment_forest import CommentForest
from .base import RedditBase
from .mixins import (
FullnameMixin,
Expand All @@ -13,6 +9,10 @@
UserContentMixin,
)
from .redditor import Redditor
from ..comment_forest import CommentForest
from ...const import API_PATH
from ...exceptions import ClientException, InvalidURL
from ...util.cache import cachedproperty

if TYPE_CHECKING: # pragma: no cover
from ... import Reddit
Expand Down Expand Up @@ -170,15 +170,16 @@ def __init__(
"""Construct an instance of the Comment object."""
if (id, url, _data).count(None) != 2:
raise TypeError("Exactly one of `id`, `url`, or `_data` must be provided.")
fetched = False
self._replies = []
self._submission = None
super().__init__(reddit, _data=_data)
if id:
self.id = id
elif url:
self.id = self.id_from_url(url)
else:
self._fetched = True
fetched = True
super().__init__(reddit, _data=_data, _fetched=fetched)

def __setattr__(
self,
Expand Down
9 changes: 4 additions & 5 deletions asyncpraw/models/reddit/live.py
Expand Up @@ -403,11 +403,11 @@ def __init__(
:param reddit: An instance of :class:`.Reddit`.
:param id: A live thread ID, e.g., ``"ukaeu1ik4sw5"``
"""
if bool(id) == bool(_data):
if (id, _data).count(None) != 1:
raise TypeError("Either `id` or `_data` must be provided.")
super().__init__(reddit, _data=_data)
if id:
self.id = id
super().__init__(reddit, _data=_data)

def _fetch_info(self):
return ("liveabout", {"id": self.id}, None)
Expand Down Expand Up @@ -744,12 +744,11 @@ def __init__(
# Since _data (part of JSON returned from reddit) have no
# thread ID, self._thread must be set by the caller of
# LiveUpdate(). See the code of LiveThread.updates() for example.
super().__init__(reddit, _data=_data)
self._fetched = True
super().__init__(reddit, _data=_data, _fetched=True)
elif thread_id and update_id:
self.id = update_id
super().__init__(reddit, _data=None)
self._thread = LiveThread(self._reddit, thread_id)
self.id = update_id
else:
raise TypeError(
"Either `thread_id` and `update_id`, or `_data` must be provided."
Expand Down
3 changes: 1 addition & 2 deletions asyncpraw/models/reddit/message.py
Expand Up @@ -80,8 +80,7 @@ def _kind(self) -> str:

def __init__(self, reddit: "Reddit", _data: Dict[str, Any]):
"""Construct an instance of the Message object."""
super().__init__(reddit, _data=_data)
self._fetched = True
super().__init__(reddit, _data=_data, _fetched=True)

async def delete(self):
"""Delete the message.
Expand Down
3 changes: 2 additions & 1 deletion asyncpraw/models/reddit/modmail.py
Expand Up @@ -134,13 +134,14 @@ def __init__(
(default: False).
"""
super().__init__(reddit, _data=_data)
if bool(id) == bool(_data):
raise TypeError("Either `id` or `_data` must be provided.")

if id:
self.id = id

super().__init__(reddit, _data=_data)

self._info_params = {"markRead": "true"} if mark_read else None

def _build_conversation_list(self, other_conversations):
Expand Down
2 changes: 1 addition & 1 deletion asyncpraw/models/reddit/redditor.py
Expand Up @@ -147,12 +147,12 @@ def __init__(
assert (
isinstance(_data, dict) and "name" in _data
), "Please file a bug with Async PRAW"
super().__init__(reddit, _data=_data)
self._listing_use_sort = True
if name:
self.name = name
elif fullname:
self._fullname = fullname
super().__init__(reddit, _data=_data, _extra_attribute_to_check="_fullname")

async def _fetch_username(self, fullname):
response = await self._reddit.get(
Expand Down
3 changes: 2 additions & 1 deletion asyncpraw/models/reddit/removal_reasons.py
Expand Up @@ -84,7 +84,8 @@ def __init__(
if (id, _data).count(None) != 1:
raise ValueError("Either id or _data needs to be given.")

self.id = id
if id:
self.id = id
self.subreddit = subreddit
super().__init__(reddit, _data=_data)

Expand Down
3 changes: 2 additions & 1 deletion asyncpraw/models/reddit/rules.py
Expand Up @@ -81,7 +81,8 @@ def __init__(
"""Construct an instance of the Rule object."""
if (short_name, _data).count(None) != 1:
raise ValueError("Either short_name or _data needs to be given.")
self.short_name = short_name
if short_name:
self.short_name = short_name
# Note: The subreddit parameter can be None, because the objector
# does not know this info. In that case, it is the responsibility of
# the caller to set the `subreddit` property on the returned value.
Expand Down
7 changes: 4 additions & 3 deletions asyncpraw/models/reddit/submission.py
Expand Up @@ -556,17 +556,18 @@ def __init__(
"""
if (id, url, _data).count(None) != 2:
raise TypeError("Exactly one of `id`, `url`, or `_data` must be provided.")
super().__init__(reddit, _data=_data)
self.comment_limit = 2048

# Specify the sort order for ``comments``
self.comment_sort = "confidence"

if id is not None:
if id:
self.id = id
elif url is not None:
elif url:
self.id = self.id_from_url(url)

super().__init__(reddit, _data=_data)

self._comments_by_id = {}

def __setattr__(self, attribute: str, value: Any):
Expand Down
4 changes: 2 additions & 2 deletions asyncpraw/models/reddit/subreddit.py
Expand Up @@ -577,11 +577,11 @@ def __init__(self, reddit, display_name=None, _data=None):
``await reddit.subreddit("subreddit_name")``
"""
if bool(display_name) == bool(_data):
if (display_name, _data).count(None) != 1:
raise TypeError("Either `display_name` or `_data` must be provided.")
super().__init__(reddit, _data=_data)
if display_name:
self.display_name = display_name
super().__init__(reddit, _data=_data)
self._path = API_PATH["subreddit"].format(subreddit=self)

async def _convert_to_fancypants(self, markdown_text: str):
Expand Down
2 changes: 1 addition & 1 deletion asyncpraw/models/reddit/wikipage.py
Expand Up @@ -191,7 +191,7 @@ def __init__(
self.name = name
self._revision = revision
self.subreddit = subreddit
super().__init__(reddit, _data=_data)
super().__init__(reddit, _data=_data, _str_field=False)

def __repr__(self) -> str:
"""Return an object initialization representation of the instance."""
Expand Down
31 changes: 18 additions & 13 deletions tests/unit/models/reddit/test_collections.py
Expand Up @@ -3,16 +3,15 @@

from asyncpraw.models import Collection
from asyncpraw.models.reddit.collections import SubredditCollections

from ... import UnitTest


class TestCollection(UnitTest):
def test_eq(self):
uuid = "fake_uuid"
permalink = "https://reddit.com/r/subreddit/collection/" + uuid
collection1 = Collection(None, collection_id=uuid)
collection2 = Collection(None, permalink=permalink)
collection1 = Collection(self.reddit, collection_id=uuid)
collection2 = Collection(self.reddit, permalink=permalink)
assert collection1 == collection2
assert collection2 == collection2
assert collection1 == collection1
Expand All @@ -21,44 +20,50 @@ def test_eq(self):

def test_init(self):
uuid = "fake_uuid"
assert uuid == Collection(None, collection_id=uuid).collection_id
assert uuid == Collection(self.reddit, collection_id=uuid).collection_id
permalink = "https://reddit.com/r/subreddit/collection/" + uuid
assert uuid == Collection(None, permalink=permalink).collection_id
assert uuid == Collection(self.reddit, permalink=permalink).collection_id

def test_init_bad(self):
with pytest.raises(TypeError):
Collection(None)
Collection(self.reddit)
with pytest.raises(TypeError):
Collection(None, _data=dict(), collection_id="")
Collection(self.reddit, _data=dict(), collection_id="")
with pytest.raises(TypeError):
Collection(None, collection_id="fake_uuid", permalink="")
Collection(self.reddit, collection_id="fake_uuid", permalink="")
with pytest.raises(TypeError):
Collection(
None,
_data={"collection_id": "fake_uuid"},
collection_id="fake_uuid",
permalink="https://reddit.com/r/sub/collection/fake_uuid",
)
with pytest.raises(ValueError):
Collection(self.reddit, collection_id="")
with pytest.raises(ValueError):
Collection(self.reddit, permalink="")

def test_repr(self):
collection = Collection(None, collection_id="fake_uuid")
collection = Collection(self.reddit, collection_id="fake_uuid")
assert "Collection(collection_id='fake_uuid')" == repr(collection)

def test_str(self):
collection = Collection(None, collection_id="fake_uuid")
collection = Collection(self.reddit, collection_id="fake_uuid")
assert "fake_uuid" == str(collection)

def test_neq(self):
collection1 = Collection(None, collection_id="1")
collection2 = Collection(None, collection_id="2")
collection1 = Collection(self.reddit, collection_id="1")
collection2 = Collection(self.reddit, collection_id="2")
assert collection1 != collection2
assert "1" != collection2
assert "2" != collection1


class TestSubredditCollections(UnitTest):
async def test_call(self):
collections = SubredditCollections(None, None)
collections = SubredditCollections(
self.reddit, self.reddit.subreddit("placeholder")
)
with pytest.raises(TypeError):
await collections()
with pytest.raises(TypeError):
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/models/reddit/test_comment.py
Expand Up @@ -46,6 +46,11 @@ def test_construct_failure(self):
Comment(self.reddit, "dummy", "dummy", {"id": "dummy"})
assert str(excinfo.value) == message

with pytest.raises(ValueError):
Comment(self.reddit, "")
with pytest.raises(ValueError):
Comment(self.reddit, url="")

def test_construct_from_url(self):
url = "https://reddit.com/comments/2gmzqe/_/cklhv0f/"
assert Comment(self.reddit, url=url) == "cklhv0f"
Expand Down
3 changes: 3 additions & 0 deletions tests/unit/models/reddit/test_live.py
Expand Up @@ -33,6 +33,9 @@ def test_construct_failure(self):
LiveThread(self.reddit, id="dummy", _data={"id": "dummy"})
assert str(excinfo.value) == message

with pytest.raises(ValueError):
LiveThread(self.reddit, "")

def test_contrib(self):
thread_id = "ukaeu1ik4sw5"
thread = LiveThread(self.reddit, thread_id)
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/models/reddit/test_redditor.py
Expand Up @@ -48,6 +48,11 @@ def test_construct_failure(self):
with pytest.raises(AssertionError):
Redditor(self.reddit, _data={"notname": "dummy"})

with pytest.raises(ValueError):
Redditor(self.reddit, "")
with pytest.raises(ValueError):
Redditor(self.reddit, fullname="")

def test_fullname(self):
redditor = Redditor(self.reddit, _data={"name": "name", "id": "dummy"})
assert redditor.fullname == "t2_dummy"
Expand Down
6 changes: 6 additions & 0 deletions tests/unit/models/reddit/test_removal_reasons.py
Expand Up @@ -46,6 +46,12 @@ def test_exception(self):
id="test",
_data={},
)
with pytest.raises(ValueError):
RemovalReason(self.reddit, subreddit=self.reddit.subreddit("a"), id="")
with pytest.raises(ValueError):
RemovalReason(
self.reddit, subreddit=self.reddit.subreddit("a"), reason_id=""
)

async def test__get(self):
subreddit = Subreddit(self.reddit, display_name="a")
Expand Down
5 changes: 4 additions & 1 deletion tests/unit/models/reddit/test_rules.py
@@ -1,7 +1,6 @@
import pytest

from asyncpraw.models import Rule, Subreddit

from ... import UnitTest


Expand All @@ -10,6 +9,10 @@ class TestRules(UnitTest):
def subreddit(self):
return Subreddit(self.reddit, display_name=pytest.placeholders.test_subreddit)

def test_empty_value(self):
with pytest.raises(ValueError):
Rule(self.reddit, self.subreddit, short_name="")

def test_no_data(self):
with pytest.raises(ValueError) as excinfo:
Rule(self.reddit, self.subreddit)
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/models/reddit/test_submission.py
Expand Up @@ -42,6 +42,11 @@ def test_construct_failure(self):
Submission(self.reddit, "dummy", "dummy", {"id": "dummy"})
assert str(excinfo.value) == message

with pytest.raises(ValueError):
Submission(self.reddit, "")
with pytest.raises(ValueError):
Submission(self.reddit, url="")

def test_construct_from_url(self):
assert Submission(self.reddit, url="http://my.it/2gmzqe") == "2gmzqe"

Expand Down

0 comments on commit cf0f5e8

Please sign in to comment.