diff --git a/poetry.lock b/poetry.lock index 7a7931a..f61eb9c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -203,6 +203,20 @@ dev = ["asyncprawcore[lint]", "asyncprawcore[test]", "packaging"] lint = ["pre-commit", "ruff (==0.1.*)"] test = ["mock (==4.*)", "pytest (==7.*)", "pytest-asyncio (==0.18.*)", "pytest-vcr (==1.*)", "urllib3 (==1.*)", "vcrpy (==4.2.1)"] +[[package]] +name = "asyncprawcore-stubs" +version = "0.0.1" +description = "Python stubs for AsyncPRAWCore, a Low-level asynchronous communication layer for Async PRAW" +optional = false +python-versions = "<4.0,>=3.9" +files = [ + {file = "asyncprawcore_stubs-0.0.1-py3-none-any.whl", hash = "sha256:fab05bbd513b269b2598ff95ce35e0f616cc88b5b72375e788ec892518495a5a"}, + {file = "asyncprawcore_stubs-0.0.1.tar.gz", hash = "sha256:81f9490005c3e62fd713fa4a0cc3fc0d82308931c8575f073c2c5349b67d3fd2"}, +] + +[package.dependencies] +aiohttp = ">=3.9.3,<4.0.0" + [[package]] name = "attrs" version = "23.2.0" @@ -1434,4 +1448,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "42ff3bd8faaf6f5204009c411bc505159ea542255298955426d797e418631296" +content-hash = "40b340873e2f22654a606610c2bb2eac3bb2b63c851e8e5c13c0b3bae3b54d16" diff --git a/pyproject.toml b/pyproject.toml index a039a93..4205067 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ python = "^3.9" asyncpraw = "^7.7.1" asyncprawcore = "^2.4.0" typing-extensions = "^4.10.0" +asyncprawcore-stubs = "^0.0.1" [tool.poetry.group.typing.dependencies] diff --git a/src/asyncpraw-stubs/models/__init__.pyi b/src/asyncpraw-stubs/models/__init__.pyi index e69de29..c24ae87 100644 --- a/src/asyncpraw-stubs/models/__init__.pyi +++ b/src/asyncpraw-stubs/models/__init__.pyi @@ -0,0 +1,13 @@ +from .listing.domain import DomainListing +from .reddit.comment import Comment +from .reddit.redditor import Redditor +from .reddit.submission import Submission +from .reddit.subreddit import Subreddit + +__all__ = [ + "Comment", + "DomainListing", + "Redditor", + "Submission", + "Subreddit", +] diff --git a/src/asyncpraw-stubs/models/base.pyi b/src/asyncpraw-stubs/models/base.pyi index e69de29..a2dd03c 100644 --- a/src/asyncpraw-stubs/models/base.pyi +++ b/src/asyncpraw-stubs/models/base.pyi @@ -0,0 +1,5 @@ +"""Provide the AsyncPRAWBase superclass.""" + +from __future__ import annotations + +class AsyncPRAWBase: ... diff --git a/src/asyncpraw-stubs/models/listing/__init__.pyi b/src/asyncpraw-stubs/models/listing/__init__.pyi new file mode 100644 index 0000000..e69de29 diff --git a/src/asyncpraw-stubs/models/listing/domain.py b/src/asyncpraw-stubs/models/listing/domain.py new file mode 100644 index 0000000..669bfe1 --- /dev/null +++ b/src/asyncpraw-stubs/models/listing/domain.py @@ -0,0 +1,9 @@ +"""Provide the DomainListing class.""" + +from __future__ import annotations + +from .mixins import BaseListingMixin, RisingListingMixin + + +class DomainListing(BaseListingMixin, RisingListingMixin): + ... diff --git a/src/asyncpraw-stubs/models/listing/mixins/__init__.pyi b/src/asyncpraw-stubs/models/listing/mixins/__init__.pyi new file mode 100644 index 0000000..7921837 --- /dev/null +++ b/src/asyncpraw-stubs/models/listing/mixins/__init__.pyi @@ -0,0 +1,6 @@ +"""Package providing models that pertain to listing mixins.""" + +from .base import BaseListingMixin +from .rising import RisingListingMixin + +__all__ = ["BaseListingMixin", "RisingListingMixin"] diff --git a/src/asyncpraw-stubs/models/listing/mixins/base.pyi b/src/asyncpraw-stubs/models/listing/mixins/base.pyi new file mode 100644 index 0000000..9042107 --- /dev/null +++ b/src/asyncpraw-stubs/models/listing/mixins/base.pyi @@ -0,0 +1,7 @@ +"""Provide the BaseListingMixin class.""" + +from __future__ import annotations + +from ...base import AsyncPRAWBase + +class BaseListingMixin(AsyncPRAWBase): ... diff --git a/src/asyncpraw-stubs/models/listing/mixins/rising.pyi b/src/asyncpraw-stubs/models/listing/mixins/rising.pyi new file mode 100644 index 0000000..16336a7 --- /dev/null +++ b/src/asyncpraw-stubs/models/listing/mixins/rising.pyi @@ -0,0 +1,7 @@ +"""Provide the RisingListingMixin class.""" + +from __future__ import annotations + +from ...base import AsyncPRAWBase + +class RisingListingMixin(AsyncPRAWBase): ... diff --git a/src/asyncpraw-stubs/models/reddit/__init__.pyi b/src/asyncpraw-stubs/models/reddit/__init__.pyi new file mode 100644 index 0000000..e69de29 diff --git a/src/asyncpraw-stubs/models/reddit/base.py b/src/asyncpraw-stubs/models/reddit/base.py new file mode 100644 index 0000000..adb5f46 --- /dev/null +++ b/src/asyncpraw-stubs/models/reddit/base.py @@ -0,0 +1,9 @@ +"""Provide the RedditBase class.""" + +from __future__ import annotations + +from asyncpraw.models.base import AsyncPRAWBase + + +class RedditBase(AsyncPRAWBase): + ... diff --git a/src/asyncpraw-stubs/models/reddit/comment.py b/src/asyncpraw-stubs/models/reddit/comment.py new file mode 100644 index 0000000..86e0c15 --- /dev/null +++ b/src/asyncpraw-stubs/models/reddit/comment.py @@ -0,0 +1,7 @@ +"""Provide the Comment class.""" + +from __future__ import annotations + + +class Comment: # incomplete + ... diff --git a/src/asyncpraw-stubs/models/reddit/redditor.pyi b/src/asyncpraw-stubs/models/reddit/redditor.pyi new file mode 100644 index 0000000..528b744 --- /dev/null +++ b/src/asyncpraw-stubs/models/reddit/redditor.pyi @@ -0,0 +1,3 @@ +"""Provide the Redditor class.""" + +class Redditor: ... diff --git a/src/asyncpraw-stubs/models/reddit/submission.pyi b/src/asyncpraw-stubs/models/reddit/submission.pyi new file mode 100644 index 0000000..52089b2 --- /dev/null +++ b/src/asyncpraw-stubs/models/reddit/submission.pyi @@ -0,0 +1 @@ +class Submission: ... diff --git a/src/asyncpraw-stubs/models/reddit/subreddit.pyi b/src/asyncpraw-stubs/models/reddit/subreddit.pyi new file mode 100644 index 0000000..3974981 --- /dev/null +++ b/src/asyncpraw-stubs/models/reddit/subreddit.pyi @@ -0,0 +1 @@ +class Subreddit: ... diff --git a/src/asyncpraw-stubs/models/util.pyi b/src/asyncpraw-stubs/models/util.pyi index e69de29..e6d2899 100644 --- a/src/asyncpraw-stubs/models/util.pyi +++ b/src/asyncpraw-stubs/models/util.pyi @@ -0,0 +1,7 @@ +"""Provide helper classes used by other models.""" + +from __future__ import annotations + +from typing import Any, Callable + +def deprecate_lazy(func: Callable[..., Any]) -> Callable[..., Any]: ... diff --git a/src/asyncpraw-stubs/objector.pyi b/src/asyncpraw-stubs/objector.pyi index f87712a..0cb064e 100644 --- a/src/asyncpraw-stubs/objector.pyi +++ b/src/asyncpraw-stubs/objector.pyi @@ -6,8 +6,7 @@ from .exceptions import RedditAPIException if TYPE_CHECKING: import asyncpraw - - from .models.reddit.base import RedditBase + from asyncpraw.models.reddit.base import RedditBase class Objector: @classmethod diff --git a/src/asyncpraw-stubs/reddit.pyi b/src/asyncpraw-stubs/reddit.pyi index 4b01ea5..7695c9f 100644 --- a/src/asyncpraw-stubs/reddit.pyi +++ b/src/asyncpraw-stubs/reddit.pyi @@ -3,21 +3,36 @@ from __future__ import annotations import re -from typing import TYPE_CHECKING, Any, Optional, TypedDict +from typing import IO, TYPE_CHECKING, Any, AsyncGenerator, Iterable, TypedDict +import asyncprawcore.auth +from asyncpraw import models +from asyncpraw.exceptions import ( + RedditAPIException, +) +from asyncpraw.models.util import deprecate_lazy +from asyncpraw.util.deprecated_args import _deprecate_args +from asyncprawcore.requestor import Requestor from typing_extensions import NotRequired, Unpack if TYPE_CHECKING: + import asyncpraw + import asyncpraw.models import asyncprawcore from .util.token_manager import BaseTokenManager +Comment = models.Comment +Redditor = models.Redditor +Submission = models.Submission +Subreddit = models.Subreddit + class ConfigSettings(TypedDict): """Represents a configuration options that can be passed through initializer of the Reddit class.""" client_id: str """The OAuth client ID associated with your registered Reddit application.""" - client_secret: NotRequired[Optional[str]] + client_secret: NotRequired[str | None] """The OAuth client secret associated with your registered Reddit application. This option is required for all application types, however, the value must be set to `None` for installed applications.""" user_agent: str @@ -60,7 +75,7 @@ class ConfigSettings(TypedDict): class Reddit: update_checked: bool - _ratelimit_regex: re.Pattern + _ratelimit_regex: re.Pattern[str] @property def _next_unique(self) -> int: ... @@ -82,8 +97,126 @@ class Reddit: site_name: str | None = None, *, config_interpolation: str | None = None, - requestor_class: type[asyncprawcore.requestor.Requestor] | None = None, + requestor_class: type[Requestor] | None = None, requestor_kwargs: dict[str, Any] | None = None, token_manager: BaseTokenManager | None = None, **config_settings: Unpack[ConfigSettings], ) -> None: ... + def _check_for_update(self) -> None: ... + def _handle_rate_limit(self, exception: RedditAPIException) -> int | float | None: ... + async def _objectify_request( + self, + *, + data: dict[str, str | Any] | bytes | IO | str | None = None, # type: ignore + files: dict[str, IO] | None = None, # type: ignore + json: dict[Any, Any] | list[Any] | None = None, + method: str = "", + params: str | dict[str, str] | None = None, + path: str = "", + ) -> Any: ... + def _prepare_asyncprawcore( + self, + *, + requestor_class: type[Requestor] | None = None, + requestor_kwargs: Any | None = None, + ) -> Requestor: ... + def _prepare_common_authorizer(self, authenticator: asyncprawcore.auth.BaseAuthenticator) -> None: ... + def _prepare_objector(self) -> None: ... + def _prepare_trusted_asyncprawcore(self, requestor: Requestor) -> None: ... + def _prepare_untrusted_asyncprawcore(self, requestor: Requestor) -> None: ... + async def close(self) -> None: ... + async def _resolve_share_url(self, url: str) -> str: ... + @_deprecate_args("id", "url", "fetch") + @deprecate_lazy + async def comment( + self, + id: str | None = None, + *, + fetch: bool = True, + url: str | None = None, + **_: Any, + ) -> models.Comment: ... + @_deprecate_args("path", "data", "json", "params") + async def delete( + self, + path: str, + *, + data: dict[str, str | Any] | bytes | IO | str | None = None, # type: ignore + json: dict[Any, Any] | list[Any] | None = None, + params: str | dict[str, str] | None = None, + ) -> Any: ... + def domain(self, domain: str) -> models.DomainListing: ... + @_deprecate_args("path", "params") + async def get( + self, + path: str, + *, + params: str | dict[str, str | int] | None = None, + ) -> Any: ... + @_deprecate_args("fullnames", "url", "subreddits") + def info( + self, + *, + fullnames: Iterable[str] | None = None, + subreddits: Iterable[asyncpraw.models.Subreddit | str] | None = None, + url: str | None = None, + ) -> AsyncGenerator[asyncpraw.models.Subreddit | asyncpraw.models.Comment | asyncpraw.models.Submission, None,]: ... + @_deprecate_args("path", "data", "json") + async def patch( + self, + path: str, + *, + data: dict[str, str | Any] | bytes | IO | str | None = None, + json: dict[Any, Any] | list[Any] | None = None, + params: str | dict[str, str] | None = None, + ) -> Any: ... + @_deprecate_args("path", "data", "files", "params", "json") + async def post( + self, + path: str, + *, + data: dict[str, str | Any] | bytes | IO | str | None = None, + files: dict[str, IO] | None = None, + json: dict[Any, Any] | list[Any] | None = None, + params: str | dict[str, str] | None = None, + ) -> Any: ... + @_deprecate_args("path", "data", "json") + async def put( + self, + path: str, + *, + data: dict[str, str | Any] | bytes | IO | str | None = None, + json: dict[Any, Any] | list[Any] | None = None, + ) -> Any: ... + @_deprecate_args("nsfw") + async def random_subreddit(self, *, nsfw: bool = False) -> asyncpraw.models.Subreddit: ... + @_deprecate_args("name", "fullname", "fetch") + async def redditor( + self, + name: str | None = None, + *, + fetch: bool = False, + fullname: str | None = None, + ) -> asyncpraw.models.Redditor: ... + @_deprecate_args("method", "path", "params", "data", "files", "json") + async def request( + self, + *, + data: dict[str, str | Any] | bytes | IO | str | None = None, + files: dict[str, IO] | None = None, + json: dict[Any, Any] | list[Any] | None = None, + method: str, + params: str | dict[str, str | int] | None = None, + path: str, + ) -> Any: ... + @_deprecate_args("id", "url", "fetch") + @deprecate_lazy + async def submission( + self, + id: str | None = None, + *, + fetch: bool = True, + url: str | None = None, + **_, + ) -> asyncpraw.models.Submission: ... + async def username_available(self, name: str) -> bool: ... diff --git a/src/asyncpraw-stubs/util/token_manager.pyi b/src/asyncpraw-stubs/util/token_manager.pyi index 172e65f..cb31f5f 100644 --- a/src/asyncpraw-stubs/util/token_manager.pyi +++ b/src/asyncpraw-stubs/util/token_manager.pyi @@ -19,13 +19,13 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: import aiosqlite import asyncpraw - import asyncprawcore + from asyncprawcore.auth import BaseAuthorizer class BaseTokenManager(ABC): @abstractmethod - def post_refresh_callback(self, authorizer: asyncprawcore.auth.BaseAuthorizer) -> None: ... + async def post_refresh_callback(self, authorizer: BaseAuthorizer) -> None: ... @abstractmethod - def pre_refresh_callback(self, authorizer: asyncprawcore.auth.BaseAuthorizer) -> None: ... + async def pre_refresh_callback(self, authorizer: BaseAuthorizer) -> None: ... @property def reddit(self) -> asyncpraw.Reddit: ... @reddit.setter @@ -33,14 +33,14 @@ class BaseTokenManager(ABC): class FileTokenManager(BaseTokenManager): def __init__(self, filename: str) -> None: ... - async def post_refresh_callback(self, authorizer: asyncprawcore.auth.BaseAuthorizer) -> None: ... - async def pre_refresh_callback(self, authorizer: asyncprawcore.auth.BaseAuthorizer) -> None: ... + async def post_refresh_callback(self, authorizer: BaseAuthorizer) -> None: ... + async def pre_refresh_callback(self, authorizer: BaseAuthorizer) -> None: ... class SQLiteTokenManager(BaseTokenManager): def __init__(self, database: str, key: str) -> None: ... async def close(self) -> None: ... async def connection(self) -> "aiosqlite.Connection": ... async def is_registered(self) -> bool: ... - async def post_refresh_callback(self, authorizer: asyncprawcore.auth.BaseAuthorizer) -> None: ... - async def pre_refresh_callback(self, authorizer: asyncprawcore.auth.BaseAuthorizer) -> None: ... + async def post_refresh_callback(self, authorizer: BaseAuthorizer) -> None: ... + async def pre_refresh_callback(self, authorizer: BaseAuthorizer) -> None: ... async def register(self, refresh_token: str) -> bool: ...