Skip to content

Commit 5a20a34

Browse files
ad-mAdam Dobrawyclaude
authored
Add py.typed marker and complete type annotations (#124)
* Add py.typed marker and complete type annotations Add PEP 561 py.typed marker so type checkers (mypy, pyright) recognize the package as typed. Complete type annotations for all public methods missing them: context manager protocol, createTask/createTaskSmee parameter types, and exception subclass constructors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Exclude internal type attribute from Sphinx autodoc The task class `type` attributes conflict with the builtin `type` used in type annotations, causing an ambiguous cross-reference warning that fails the -W docs build. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Adam Dobrawy <naczelnik@jawne.info.pl> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ca02a00 commit 5a20a34

4 files changed

Lines changed: 21 additions & 7 deletions

File tree

docs/conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444
"sphinx.ext.viewcode",
4545
]
4646

47+
autodoc_default_options = {
48+
"exclude-members": "type",
49+
}
50+
4751
# Add any paths that contain templates here, relative to this directory.
4852
templates_path = ["_templates"]
4953

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ async = ["httpx>=0.24"]
3131
tests = ["pytest", "retry", "selenium"]
3232
docs = ["sphinx"]
3333

34+
[tool.setuptools.package-data]
35+
python_anticaptcha = ["py.typed"]
36+
3437
[tool.setuptools-scm]
3538
fallback_version = "0.0.0"
3639

python_anticaptcha/base.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
import time
66
import json
77
import warnings
8+
from types import TracebackType
89
from typing import Any
910

1011
from urllib.parse import urljoin
1112
from .exceptions import AnticaptchaException
13+
from .tasks import BaseTask
1214

1315
SLEEP_EVERY_CHECK_FINISHED = 3
1416
MAXIMUM_JOIN_TIME = 60 * 5
@@ -111,14 +113,19 @@ def __init__(
111113
)
112114
self.session = requests.Session()
113115

114-
def __enter__(self):
116+
def __enter__(self) -> AnticaptchaClient:
115117
return self
116118

117-
def __exit__(self, exc_type, exc_val, exc_tb):
119+
def __exit__(
120+
self,
121+
exc_type: type[BaseException] | None,
122+
exc_val: BaseException | None,
123+
exc_tb: TracebackType | None,
124+
) -> bool:
118125
self.session.close()
119126
return False
120127

121-
def close(self):
128+
def close(self) -> None:
122129
self.session.close()
123130

124131
def __repr__(self) -> str:
@@ -146,7 +153,7 @@ def _check_response(self, response: dict[str, Any]) -> None:
146153
response["errorId"], response["errorCode"], response["errorDescription"]
147154
)
148155

149-
def createTask(self, task: Any) -> Job:
156+
def createTask(self, task: BaseTask) -> Job:
150157
request = {
151158
"clientKey": self.client_key,
152159
"task": task.serialize(),
@@ -161,7 +168,7 @@ def createTask(self, task: Any) -> Job:
161168
self._check_response(response)
162169
return Job(self, response["taskId"])
163170

164-
def createTaskSmee(self, task: Any, timeout: int = MAXIMUM_JOIN_TIME) -> Job:
171+
def createTaskSmee(self, task: BaseTask, timeout: int = MAXIMUM_JOIN_TIME) -> Job:
165172
"""
166173
Beta method to stream response from smee.io
167174
"""

python_anticaptcha/exceptions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def __init__(self, error_id: int | str | None, error_code: int | str, error_desc
1515

1616

1717
class InvalidWidthException(AnticaptchaException):
18-
def __init__(self, width):
18+
def __init__(self, width: int) -> None:
1919
self.width = width
2020
msg = "Invalid width (%s). Can be one of these: 100, 50, 33, 25." % (
2121
self.width,
@@ -24,7 +24,7 @@ def __init__(self, width):
2424

2525

2626
class MissingNameException(AnticaptchaException):
27-
def __init__(self, cls):
27+
def __init__(self, cls: type) -> None:
2828
self.cls = cls
2929
msg = 'Missing name data in {0}. Provide {0}.__init__(name="X") or {0}.serialize(name="X")'.format(
3030
str(self.cls)

0 commit comments

Comments
 (0)