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

General cleanup #1988

Merged
merged 1 commit into from
Oct 22, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,4 @@ repos:
- repo: https://github.com/LilSpazJoekp/docstrfmt
hooks:
- id: docstrfmt
require_serial: true
rev: v1.5.1
2 changes: 1 addition & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Change Log
==========

PRAW follows `semantic versioning <http://semver.org/>`_.
PRAW follows `semantic versioning <https://semver.org/>`_.

Unreleased
----------
Expand Down
15 changes: 9 additions & 6 deletions praw/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import sys
from pathlib import Path
from threading import Lock
from typing import Any

from .exceptions import ClientException

Expand All @@ -32,13 +33,13 @@ class Config:
}

@staticmethod
def _config_boolean(item: bool | str) -> bool: # noqa: ANN001
def _config_boolean(item: bool | str) -> bool:
if isinstance(item, bool):
return item
return item.lower() in {"1", "yes", "true", "on"}

@classmethod
def _load_config(cls, *, config_interpolation: str | None = None): # noqa: ANN001
def _load_config(cls, *, config_interpolation: str | None = None):
"""Attempt to load settings from various praw.ini files."""
if config_interpolation is not None:
interpolator_class = cls.INTERPOLATION_LEVEL[config_interpolation]()
Expand Down Expand Up @@ -97,17 +98,19 @@ def __init__(

self._initialize_attributes()

def _fetch(self, key): # noqa: ANN001
def _fetch(self, key: str) -> Any:
value = self.custom[key]
del self.custom[key]
return value

def _fetch_default(self, key, *, default=None): # noqa: ANN001
def _fetch_default(
self, key: str, *, default: bool | float | str | None = None
) -> Any:
if key not in self.custom:
return default
return self._fetch(key)

def _fetch_or_not_set(self, key): # noqa: ANN001
def _fetch_or_not_set(self, key: str) -> Any | _NotSet:
if key in self._settings: # Passed in values have the highest priority
return self._fetch(key)

Expand All @@ -117,7 +120,7 @@ def _fetch_or_not_set(self, key): # noqa: ANN001
# Environment variables have higher priority than praw.ini settings
return env_value or ini_value or self.CONFIG_NOT_SET

def _initialize_attributes(self): # noqa: ANN001
def _initialize_attributes(self):
self._short_url = self._fetch_default("short_url") or self.CONFIG_NOT_SET
self.check_for_async = self._config_boolean(
self._fetch_default("check_for_async", default=True)
Expand Down
1 change: 0 additions & 1 deletion praw/endpoints.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""List of API endpoints PRAW knows about."""
# flake8: noqa
# fmt: off
API_PATH = {
"about_edited": "r/{subreddit}/about/edited/",
Expand Down
11 changes: 6 additions & 5 deletions praw/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
"""
from __future__ import annotations

from typing import Any
from warnings import warn

from .util import _deprecate_args


class PRAWException(Exception): # noqa: N818
class PRAWException(Exception):
"""The base PRAW Exception that all other exception classes extend."""


Expand Down Expand Up @@ -79,7 +80,7 @@ class ClientException(PRAWException):
class DuplicateReplaceException(ClientException):
"""Indicate exceptions that involve the replacement of :class:`.MoreComments`."""

def __init__(self) -> None:
def __init__(self):
"""Initialize a :class:`.DuplicateReplaceException` instance."""
super().__init__(
"A duplicate comment has been detected. Are you attempting to call"
Expand All @@ -101,7 +102,7 @@ def __init__(self, template_id: str):
class InvalidImplicitAuth(ClientException):
"""Indicate exceptions where an implicit auth type is used incorrectly."""

def __init__(self) -> None:
def __init__(self):
"""Initialize an :class:`.InvalidImplicitAuth` instance."""
super().__init__("Implicit authorization can only be used with installed apps.")

Expand Down Expand Up @@ -189,7 +190,7 @@ def __init__(self, message: str, exception: Exception | None):
class MediaPostFailed(WebSocketException):
"""Indicate exceptions where media uploads failed.."""

def __init__(self) -> None:
def __init__(self):
"""Initialize a :class:`.MediaPostFailed` instance."""
super().__init__(
"The attempted media upload action has failed. Possible causes include the"
Expand Down Expand Up @@ -287,7 +288,7 @@ def __init__(
self.items = self.parse_exception_list(items)
super().__init__(*self.items)

def _get_old_attr(self, attrname): # noqa: ANN001
def _get_old_attr(self, attrname: str) -> Any:
warn(
f"Accessing attribute '{attrname}' through APIException is deprecated."
" This behavior will be removed in PRAW 8.0. Check out"
Expand Down
2 changes: 1 addition & 1 deletion praw/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class PRAWBase:

@staticmethod
def _safely_add_arguments(
*, arguments, key, **new_arguments # noqa: ANN001,ANN003,ANN205
*, arguments: dict[str, Any], key: str, **new_arguments: Any
):
"""Replace arguments[key] with a deepcopy and update.
Expand Down
42 changes: 23 additions & 19 deletions praw/models/comment_forest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ class CommentForest:
"""

@staticmethod
def _gather_more_comments(tree, *, parent_tree=None): # noqa: ANN001,ANN205
def _gather_more_comments(
tree: list[praw.models.MoreComments],
*,
parent_tree: list[praw.models.MoreComments] | None = None,
) -> list[MoreComments]:
"""Return a list of :class:`.MoreComments` objects obtained from tree."""
more_comments = []
queue = [(None, x) for x in tree]
Expand Down Expand Up @@ -57,27 +61,11 @@ def __getitem__(self, index: int) -> praw.models.Comment:
"""
return self._comments[index]

def __init__(
self,
submission: praw.models.Submission,
comments: list[praw.models.Comment] | None = None,
):
"""Initialize a :class:`.CommentForest` instance.

:param submission: An instance of :class:`.Submission` that is the parent of the
comments.
:param comments: Initialize the forest with a list of comments (default:
``None``).

"""
self._comments = comments
self._submission = submission

def __len__(self) -> int:
"""Return the number of top-level comments in the forest."""
return len(self._comments)

def _insert_comment(self, comment): # noqa: ANN001
def _insert_comment(self, comment: praw.models.Comment):
if comment.name in self._submission._comments_by_id:
raise DuplicateReplaceException
comment.submission = self._submission
Expand All @@ -91,7 +79,7 @@ def _insert_comment(self, comment): # noqa: ANN001
parent = self._submission._comments_by_id[comment.parent_id]
parent.replies._comments.append(comment)

def _update(self, comments): # noqa: ANN001
def _update(self, comments: list[praw.models.Comment]):
self._comments = comments
for comment in comments:
comment.submission = self._submission
Expand All @@ -114,6 +102,22 @@ def list( # noqa: A003
queue.extend(comment.replies)
return comments

def __init__(
self,
submission: praw.models.Submission,
comments: list[praw.models.Comment] | None = None,
):
"""Initialize a :class:`.CommentForest` instance.

:param submission: An instance of :class:`.Submission` that is the parent of the
comments.
:param comments: Initialize the forest with a list of comments (default:
``None``).

"""
self._comments = comments
self._submission = submission

@_deprecate_args("limit", "threshold")
def replace_more(
self, *, limit: int | None = 32, threshold: int = 0
Expand Down
19 changes: 11 additions & 8 deletions praw/models/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ def __call__(
) -> list[praw.models.Draft] | praw.models.Draft:
"""Return a list of :class:`.Draft` instances.

:param draft_id: When provided, return :class:`.Draft` instance (default:
``None``).
:param draft_id: When provided, this returns a :class:`.Draft` instance
(default: ``None``).

:returns: A :class:`.Draft` instance if ``draft_id`` is provided. Otherwise, a
list of :class:`.Draft` objects.
Expand All @@ -54,7 +54,7 @@ def __call__(
return Draft(self._reddit, id=draft_id)
return self._draft_list()

def _draft_list(self) -> list[praw.models.Draft]: # noqa: ANN001
def _draft_list(self) -> list[praw.models.Draft]:
"""Get a list of :class:`.Draft` instances.

:returns: A list of :class:`.Draft` instances.
Expand Down Expand Up @@ -139,9 +139,7 @@ def create(
class LiveHelper(PRAWBase):
r"""Provide a set of functions to interact with :class:`.LiveThread`\ s."""

def __call__(
self, id: str
) -> praw.models.LiveThread: # pylint: disable=invalid-name,redefined-builtin
def __call__(self, id: str) -> praw.models.LiveThread:
"""Return a new lazy instance of :class:`.LiveThread`.

This method is intended to be used as:
Expand Down Expand Up @@ -193,8 +191,13 @@ def info(self, ids: list[str]) -> Generator[praw.models.LiveThread, None, None]:

:returns: A generator that yields :class:`.LiveThread` instances.

Live threads that cannot be matched will not be generated. Requests will be
issued in batches for each 100 IDs.
:raises: ``prawcore.ServerError`` if invalid live threads are requested.

Requests will be issued in batches for each 100 IDs.

.. note::

This method doesn't support IDs for live updates.

.. warning::

Expand Down
6 changes: 3 additions & 3 deletions praw/models/listing/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def __init__(
self.url = url
self.yielded = 0

def __iter__(self): # noqa: ANN204
def __iter__(self) -> Any:
"""Permit :class:`.ListingGenerator` to operate as an iterator."""
return self

Expand All @@ -68,7 +68,7 @@ def __next__(self) -> Any:
self.yielded += 1
return self._listing[self._list_index - 1]

def _extract_sublist(self, listing): # noqa: ANN001
def _extract_sublist(self, listing: dict[str, Any] | list[Any]):
if isinstance(listing, list):
return listing[1] # for submission duplicates
if isinstance(listing, dict):
Expand All @@ -82,7 +82,7 @@ def _extract_sublist(self, listing): # noqa: ANN001
raise ValueError(msg)
return listing

def _next_batch(self): # noqa: ANN001
def _next_batch(self):
if self._exhausted:
raise StopIteration

Expand Down
4 changes: 2 additions & 2 deletions praw/models/listing/mixins/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class BaseListingMixin(PRAWBase):
VALID_TIME_FILTERS = {"all", "day", "hour", "month", "week", "year"}

@staticmethod
def _validate_time_filter(time_filter): # noqa: ANN001
def _validate_time_filter(time_filter: str):
"""Validate ``time_filter``.

:raises: :py:class:`ValueError` if ``time_filter`` is not valid.
Expand All @@ -28,7 +28,7 @@ def _validate_time_filter(time_filter): # noqa: ANN001
msg = f"'time_filter' must be one of: {valid_time_filters}"
raise ValueError(msg)

def _prepare(self, *, arguments, sort): # noqa: ANN001
def _prepare(self, *, arguments: dict[str, Any], sort: str) -> str:
"""Fix for :class:`.Redditor` methods that use a query param rather than subpath."""
if self.__dict__.get("_listing_use_sort"):
self._safely_add_arguments(arguments=arguments, key="params", sort=sort)
Expand Down
2 changes: 1 addition & 1 deletion praw/models/listing/mixins/subreddit.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class CommentHelper(PRAWBase):
"""Provide a set of functions to interact with a :class:`.Subreddit`'s comments."""

@property
def _path(self) -> str: # noqa: ANN001
def _path(self) -> str:
return urljoin(self.subreddit._path, "comments/")

def __call__(
Expand Down
4 changes: 2 additions & 2 deletions praw/models/mod_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class ModAction(PRAWBase):
@property
def mod(self) -> praw.models.Redditor:
"""Return the :class:`.Redditor` who the action was issued by."""
return self._reddit.redditor(self._mod) # pylint: disable=no-member
return self._reddit.redditor(self._mod)

@mod.setter
def mod(self, value: str | praw.models.Redditor):
self._mod = value # pylint: disable=attribute-defined-outside-init
self._mod = value
2 changes: 1 addition & 1 deletion praw/models/mod_notes.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def _bulk_generator(
for note_dict in response["mod_notes"]:
yield self._reddit._objector.objectify(note_dict)

def _ensure_attribute(self, error_message: str, **attributes: Any): # noqa: ANN001
def _ensure_attribute(self, error_message: str, **attributes: Any) -> Any:
attribute, _value = attributes.popitem()
value = _value or getattr(self, attribute, None)
if value is None:
Expand Down
8 changes: 4 additions & 4 deletions praw/models/reddit/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class RedditBase(PRAWBase):
"""Base class that represents actual Reddit objects."""

@staticmethod
def _url_parts(url): # noqa: ANN001,ANN205
def _url_parts(url: str) -> list[str]:
parsed = urlparse(url)
if not parsed.netloc:
raise InvalidURL(url)
Expand Down Expand Up @@ -79,15 +79,15 @@ def __str__(self) -> str:
"""Return a string representation of the instance."""
return getattr(self, self.STR_FIELD)

def _fetch(self): # pragma: no cover
def _fetch(self):
self._fetched = True

def _fetch_data(self): # noqa: ANN001
def _fetch_data(self):
name, fields, params = self._fetch_info()
path = API_PATH[name].format(**fields)
return self._reddit.request(method="GET", params=params, path=path)

def _reset_attributes(self, *attributes): # noqa: ANN001,ANN002
def _reset_attributes(self, *attributes: str):
for attribute in attributes:
if attribute in self.__dict__:
del self.__dict__[attribute]
Expand Down
10 changes: 5 additions & 5 deletions praw/models/reddit/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def __init__(self, reddit: praw.Reddit, collection_id: str):
super().__init__(reddit, _data=None)
self.collection_id = collection_id

def _post_fullname(self, post): # noqa: ANN001
def _post_fullname(self, post: str | praw.models.Submission) -> str:
"""Get a post's fullname.

:param post: A fullname, a :class:`.Submission`, a permalink, or an ID.
Expand Down Expand Up @@ -240,7 +240,7 @@ def __init__(
@_deprecate_args("title", "description", "display_layout")
def create(
self, *, description: str, display_layout: str | None = None, title: str
) -> praw.models.Collection:
) -> Collection:
"""Create a new :class:`.Collection`.

The authenticated account must have appropriate moderator permissions in the
Expand Down Expand Up @@ -523,7 +523,7 @@ def __setattr__(self, attribute: str, value: Any) -> None:
value = self._reddit._objector.objectify(value)
super().__setattr__(attribute, value)

def _fetch(self): # noqa: ANN001
def _fetch(self):
data = self._fetch_data()
try:
self._reddit._objector.check_error(data)
Expand All @@ -536,9 +536,9 @@ def _fetch(self): # noqa: ANN001

other = type(self)(self._reddit, _data=data)
self.__dict__.update(other.__dict__)
self._fetched = True
super()._fetch()

def _fetch_info(self): # noqa: ANN001
def _fetch_info(self):
return "collection", {}, self._info_params

def follow(self):
Expand Down
Loading
Loading