aioqzone 1.8.1.dev1__tar.gz → 1.8.2.dev3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/PKG-INFO +3 -3
  2. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/README.md +1 -1
  3. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/pyproject.toml +4 -4
  4. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/api/h5/model.py +1 -1
  5. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/api/login/__init__.py +1 -0
  6. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/model/api/__init__.py +2 -0
  7. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/model/api/profile.py +1 -0
  8. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/model/protocol/__init__.py +1 -0
  9. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/model/protocol/config.py +9 -2
  10. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/utils/regex.py +1 -0
  11. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/utils/retry.py +1 -2
  12. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/qr/__init__.py +10 -6
  13. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/captcha/__init__.py +9 -2
  14. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/captcha/capsess.py +5 -4
  15. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/web.py +5 -2
  16. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/utils/iter.py +4 -4
  17. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/utils/jsjson.py +11 -7
  18. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/utils/net.py +2 -2
  19. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/LICENSE +0 -0
  20. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/__init__.py +0 -0
  21. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/api/__init__.py +0 -0
  22. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/api/h5/__init__.py +0 -0
  23. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/api/login/_base.py +0 -0
  24. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/exception.py +0 -0
  25. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/message.py +0 -0
  26. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/model/__init__.py +0 -0
  27. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/model/api/feed.py +0 -0
  28. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/model/api/request.py +0 -0
  29. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/model/api/response.py +0 -0
  30. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/model/protocol/entity.py +0 -0
  31. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/utils/__init__.py +0 -0
  32. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/utils/entity.py +0 -0
  33. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/aioqzone/utils/time.py +0 -0
  34. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/__init__.py +0 -0
  35. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/base.py +0 -0
  36. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/constant.py +0 -0
  37. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/exception.py +0 -0
  38. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/message.py +0 -0
  39. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/py.typed +0 -0
  40. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/qr/type.py +0 -0
  41. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/type.py +0 -0
  42. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/__init__.py +0 -0
  43. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/_model.py +0 -0
  44. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/captcha/_model.py +0 -0
  45. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/captcha/pil_utils.py +0 -0
  46. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/captcha/select/__init__.py +0 -0
  47. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/captcha/select/_types.py +0 -0
  48. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/captcha/slide/__init__.py +0 -0
  49. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/captcha/slide/_types.py +0 -0
  50. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/encrypt.py +0 -0
  51. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/up/h5.py +0 -0
  52. {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev3}/src/qqqr/utils/encrypt.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aioqzone
3
- Version: 1.8.1.dev1
3
+ Version: 1.8.2.dev3
4
4
  Summary: A Python wrapper for Qzone login and H5 APIs.
5
5
  Home-page: https://github.com/aioqzone/aioqzone
6
6
  License: AGPL-3.0
@@ -23,7 +23,7 @@ Provides-Extra: slide-captcha
23
23
  Requires-Dist: aiohttp (>=3.8.5,<4.0.0)
24
24
  Requires-Dist: exceptiongroup (>=1.1.1,<2.0.0)
25
25
  Requires-Dist: pillow (>=10.0.1,<11.0.0)
26
- Requires-Dist: pychaosvm (>=0.3.3,<0.4.0)
26
+ Requires-Dist: pychaosvm (>=0.3.4,<0.5.0)
27
27
  Requires-Dist: pydantic (>=2.0.3,<3.0.0)
28
28
  Requires-Dist: pydantic-settings (>=2.0.2,<3.0.0)
29
29
  Requires-Dist: rsa (>=4.8,<5.0)
@@ -43,7 +43,7 @@ aioqzone封装了一些Qzone接口。
43
43
  [![python](https://img.shields.io/pypi/pyversions/aioqzone?logo=python&logoColor=white)][home]
44
44
  [![version](https://img.shields.io/pypi/v/aioqzone?logo=python)][pypi]
45
45
  [![style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
46
- [![discuss](https://img.shields.io/badge/dynamic/xml?style=social&logo=telegram&label=Discuss&query=%2F%2Fdiv%5B%40class%3D%22tgme_page_extra%22%5D&url=https%3A%2F%2Ft.me%2Faioqzone_chatroom)](https://t.me/aioqzone_chatrooom)
46
+ [![discuss](https://img.shields.io/badge/dynamic/xml?style=social&logo=telegram&label=Discuss&query=%2F%2Fdiv%5B%40class%3D%22tgme_page_extra%22%5D&url=https%3A%2F%2Ft.me%2Faioqzone_chatroom)](https://t.me/aioqzone_chatroom)
47
47
 
48
48
  [English](README_en.md) | 简体中文
49
49
 
@@ -5,7 +5,7 @@ aioqzone封装了一些Qzone接口。
5
5
  [![python](https://img.shields.io/pypi/pyversions/aioqzone?logo=python&logoColor=white)][home]
6
6
  [![version](https://img.shields.io/pypi/v/aioqzone?logo=python)][pypi]
7
7
  [![style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
8
- [![discuss](https://img.shields.io/badge/dynamic/xml?style=social&logo=telegram&label=Discuss&query=%2F%2Fdiv%5B%40class%3D%22tgme_page_extra%22%5D&url=https%3A%2F%2Ft.me%2Faioqzone_chatroom)](https://t.me/aioqzone_chatrooom)
8
+ [![discuss](https://img.shields.io/badge/dynamic/xml?style=social&logo=telegram&label=Discuss&query=%2F%2Fdiv%5B%40class%3D%22tgme_page_extra%22%5D&url=https%3A%2F%2Ft.me%2Faioqzone_chatroom)](https://t.me/aioqzone_chatroom)
9
9
 
10
10
  [English](README_en.md) | 简体中文
11
11
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "aioqzone"
3
- version = "1.8.1.dev1"
3
+ version = "1.8.2.dev3"
4
4
  description = "A Python wrapper for Qzone login and H5 APIs."
5
5
  authors = ["aioqzone <zzzzss990315@gmail.com>"]
6
6
  license = "AGPL-3.0"
@@ -36,7 +36,7 @@ tenacity = "^8.2.3"
36
36
  exceptiongroup = "^1.1.1"
37
37
  tylisten = "^2.1.3"
38
38
  pillow = "^10.0.1"
39
- pychaosvm = { version = "~0.3.3", source = "aioqzone-index" }
39
+ pychaosvm = { version = ">=0.3.4,<0.5.0", source = "aioqzone-index" }
40
40
  slide-tc = {version = "~0.1.1", optional = true, source = "aioqzone-index" }
41
41
 
42
42
  [tool.poetry.extras]
@@ -47,8 +47,8 @@ slide-captcha = ["slide-tc"]
47
47
  optional = false
48
48
 
49
49
  [tool.poetry.group.test.dependencies]
50
- pytest = "^7.4.0"
51
- pytest-asyncio = "~0.21.0"
50
+ pytest = "^8.2.0"
51
+ pytest-asyncio = "~0.21.2"
52
52
 
53
53
  [tool.poetry.group.dev]
54
54
  optional = true
@@ -61,7 +61,7 @@ class QzoneH5API:
61
61
  async for attempt in self._relogin_retry:
62
62
  with attempt:
63
63
  if (gtk := self.login.gtk) == 0:
64
- raise TryAgain
64
+ raise TryAgain("no login state")
65
65
  if api.attach_token:
66
66
  params["g_tk"] = gtk
67
67
  hostuin: int = getattr(api.params, "hostuin", self.login.uin)
@@ -118,6 +118,7 @@ class UpLoginManager(Loginable):
118
118
  client=self.client,
119
119
  uin=self.config.uin,
120
120
  pwd=self.config.pwd.get_secret_value(),
121
+ fake_ip=self.config.fake_ip and str(self.config.fake_ip),
121
122
  h5=enable,
122
123
  )
123
124
  self.sms_code_input = self.uplogin.sms_code_input
@@ -12,6 +12,8 @@ TyHttpMethod = t.Union[t.Literal["GET"], t.Literal["POST"]]
12
12
 
13
13
 
14
14
  class QzoneApi(BaseModel, t.Generic[TyRequest, TyResponse]):
15
+ """The base class for all Qzone APIs below."""
16
+
15
17
  host: t.ClassVar[str] = "https://h5.qzone.qq.com"
16
18
  http_method: t.ClassVar[TyHttpMethod]
17
19
  path: t.ClassVar[str]
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Qzone uses different feed schemes for ``/mqzone/profile``. This module patches :mod:`.feed`.
3
3
  """
4
+
4
5
  import typing as t
5
6
 
6
7
  from pydantic import AliasPath, BaseModel, Field, HttpUrl, field_validator, model_validator
@@ -1,6 +1,7 @@
1
1
  """This module defines types that are used internally by aioqzone and its plugins.
2
2
  These types are not designed to represent responses from Qzone.
3
3
  """
4
+
4
5
  from pydantic import BaseModel
5
6
 
6
7
  from .config import *
@@ -1,6 +1,7 @@
1
- from typing import Literal, Union
1
+ import typing as t
2
+ from ipaddress import IPv4Address
2
3
 
3
- from pydantic import Field, SecretStr
4
+ from pydantic import AnyUrl, Field, SecretStr
4
5
  from pydantic_settings import BaseSettings
5
6
 
6
7
 
@@ -13,6 +14,12 @@ class UpLoginConfig(LoginConfig):
13
14
  pwd: SecretStr = Field(default="")
14
15
  """User password."""
15
16
 
17
+ fake_ip: t.Optional[IPv4Address] = None
18
+ """Fake IP used when collecting network environment.
19
+
20
+ .. versionadded:: 1.8.2
21
+ """
22
+
16
23
 
17
24
  class QrLoginConfig(LoginConfig):
18
25
  max_refresh_times: int = 6
@@ -1,6 +1,7 @@
1
1
  """
2
2
  some patterns for matching html and so on.
3
3
  """
4
+
4
5
  import re
5
6
 
6
7
  # use this to match qzone api response
@@ -14,8 +14,7 @@ class RetryIfCode(retry_if_exception, Generic[_E]):
14
14
 
15
15
  @classmethod
16
16
  @abstractmethod
17
- def get_code(cls, exc: _E) -> int:
18
- ...
17
+ def get_code(cls, exc: _E) -> int: ...
19
18
 
20
19
  def __init__(self, *code: int) -> None:
21
20
  super().__init__(lambda exc: isinstance(exc, self._exc_cls) and self.get_code(exc) in code)
@@ -88,6 +88,10 @@ class QrLogin(LoginBase[QrSession], _QrHookMixin):
88
88
  return QrSession(await self.show(push_qr), login_sig=login_sig)
89
89
 
90
90
  async def show(self, push_qr=False) -> QR:
91
+ """``ptqrshow`` api.
92
+
93
+ :param push_qr: push QR to mobile client.
94
+ """
91
95
  data = {
92
96
  "appid": self.app.appid,
93
97
  "daid": self.app.daid,
@@ -125,7 +129,7 @@ class QrLogin(LoginBase[QrSession], _QrHookMixin):
125
129
  async def poll(self, sess: QrSession) -> PollResp:
126
130
  """Poll QR status.
127
131
 
128
- :raise `httpx.HTTPStatusError`: if response status code != 200
132
+ :raise `aiohttp.ClientResponseError`: if response status code != 200
129
133
 
130
134
  :return: a poll response object
131
135
  """
@@ -168,17 +172,17 @@ class QrLogin(LoginBase[QrSession], _QrHookMixin):
168
172
  poll_freq: float = 3,
169
173
  ):
170
174
  """Loop until cookie is returned or max `refresh_times` exceeds.
171
- - This method will emit :meth:`QrEvent.QrFetched` event if a new qrcode is fetched.
172
- - If qr is not scanned after `refresh_times`, it will raise :exc:`asyncio.TimeoutError`.
173
- - If :obj:`QrEvent.refresh_flag` is set, it will refresh qrcode at once without increasing expire counter.
174
- - If :obj:`QrEvent.cancel_flag` is set, it will raise :exc:`UserBreak` before next polling.
175
+ - This method will emit :obj:`.qr_fetched` event if a new qrcode is fetched.
176
+ - If qr is not scanned after `refresh_times`, it will raise :exc:`UserTimeout`.
177
+ - If :obj:`.refresh` is set, it will refresh qrcode at once without increasing expire counter.
178
+ - If :obj:`.cancel` is set, it will raise :exc:`UserBreak` before next polling.
175
179
 
176
180
  :meta public:
177
181
  :param refresh_times: max qr expire times.
178
182
  :param poll_freq: interval between two status polling, in seconds, default as 3.
179
183
 
180
184
  :raise `UserTimeout`: if qr is not scanned after `refresh_times` expires.
181
- :raise `UserBreak`: if :obj:`QrEvent.cancel_flag` is set.
185
+ :raise `UserBreak`: if :obj:`.cancel` is set.
182
186
  """
183
187
  self.refresh.clear()
184
188
  self.cancel.clear()
@@ -52,7 +52,13 @@ class Captcha(_CaptchaHookMixin):
52
52
  solve_select_captcha: solve_select_captcha.TyInst
53
53
  solve_slide_captcha: solve_slide_captcha.TyInst
54
54
 
55
- def __init__(self, client: ClientAdapter, appid: int, xlogin_url: str):
55
+ def __init__(
56
+ self,
57
+ client: ClientAdapter,
58
+ appid: int,
59
+ xlogin_url: str,
60
+ fake_ip: t.Optional[str] = None,
61
+ ):
56
62
  """
57
63
  :param client: network client
58
64
  :param appid: Specify the appid of the application
@@ -64,6 +70,7 @@ class Captcha(_CaptchaHookMixin):
64
70
  self.appid = appid
65
71
  self.xlogin_url = xlogin_url
66
72
  self.client.headers["Referer"] = "https://xui.ptlogin2.qq.com/"
73
+ self.fake_ip = fake_ip
67
74
 
68
75
  @property
69
76
  def base64_ua(self):
@@ -149,7 +156,7 @@ class Captcha(_CaptchaHookMixin):
149
156
  return await sess.solve_captcha()
150
157
 
151
158
  async def get_tdc_collect(client: ClientAdapter) -> str:
152
- await sess.get_tdc(client)
159
+ await sess.get_tdc(client, ip=self.fake_ip)
153
160
  return unquote(str(sess.tdc.getData(None, True)))
154
161
 
155
162
  ans, collect, _ = await asyncio.gather(
@@ -70,7 +70,9 @@ class BaseTcaptchaSession(ABC):
70
70
  def _vmslide_js_url(self):
71
71
  raise NotImplementedError
72
72
 
73
- async def get_tdc(self, client: ClientAdapter, ua: t.Optional[str] = None):
73
+ async def get_tdc(
74
+ self, client: ClientAdapter, ua: t.Optional[str] = None, ip: t.Optional[str] = None
75
+ ):
74
76
  """
75
77
  .. note:: If :obj:`.mouse_track` should be set, set it before calling this method.
76
78
  """
@@ -80,14 +82,13 @@ class BaseTcaptchaSession(ABC):
80
82
  r.raise_for_status()
81
83
  self.tdc = prepare(
82
84
  await r.text("utf8"),
83
- ip=self.prehandle.uip,
85
+ ip=ip or self.prehandle.uip,
84
86
  ua=ua or client.headers["User-Agent"],
85
87
  mouse_track=await self.mouse_track,
86
88
  )
87
89
 
88
90
  @abstractmethod
89
- async def get_captcha_problem(self, client: ClientAdapter):
90
- ...
91
+ async def get_captcha_problem(self, client: ClientAdapter): ...
91
92
 
92
93
  @abstractmethod
93
94
  async def solve_captcha(self) -> str:
@@ -123,17 +123,20 @@ class UpWebLogin(LoginBase[UpWebSession], _UpHookMixin):
123
123
  app: t.Optional[APPID] = None,
124
124
  proxy: t.Optional[Proxy] = None,
125
125
  info: t.Optional[PT_QR_APP] = None,
126
+ fake_ip: t.Optional[str] = None,
126
127
  ):
127
128
  super().__init__(client, uin=uin, h5=h5, app=app, proxy=proxy, info=info)
128
129
  self.pwd = pwd
129
130
  self.pwder = TeaEncoder(pwd)
130
- self.captcha = Captcha(self.client, self.app.appid, str(self.login_page_url))
131
+ self.captcha = Captcha(
132
+ self.client, self.app.appid, str(self.login_page_url), fake_ip=fake_ip
133
+ )
131
134
 
132
135
  async def new(self):
133
136
  """Create a :class:`UpWebSession`. This will call `check` api of Qzone, and receive result
134
137
  about whether this login needs a captcha, sms verification, etc.
135
138
 
136
- :raise `httpx.HTTPStatusError`:
139
+ :raise `aiohttp.ClientResponseError`: if response status != 200
137
140
 
138
141
  :return: a up login session
139
142
  """
@@ -5,8 +5,9 @@ D = t.TypeVar("D")
5
5
 
6
6
 
7
7
  @t.overload
8
- def first(it: t.Iterable[T], pred: t.Optional[t.Callable[[T], t.Optional[object]]] = None) -> T:
9
- ...
8
+ def first(
9
+ it: t.Iterable[T], pred: t.Optional[t.Callable[[T], t.Optional[object]]] = None
10
+ ) -> T: ...
10
11
 
11
12
 
12
13
  @t.overload
@@ -15,8 +16,7 @@ def first(
15
16
  pred: t.Optional[t.Callable[[T], t.Optional[object]]] = None,
16
17
  *,
17
18
  default: D,
18
- ) -> t.Union[T, D]:
19
- ...
19
+ ) -> t.Union[T, D]: ...
20
20
 
21
21
 
22
22
  def first(
@@ -10,9 +10,13 @@ JsonValue = Union[bool, int, str, JsonDict, JsonList]
10
10
 
11
11
 
12
12
  class AstLoader:
13
- """`AstLoader` uses standard :mod:`ast` module to parse the js/json"""
13
+ """:class:`AstLoader` uses standard :mod:`ast` module to parse the js/json"""
14
14
 
15
15
  class RewriteUndef(ast.NodeTransformer):
16
+ """
17
+ :meta private:
18
+ """
19
+
16
20
  const = {
17
21
  "undefined": ast.Constant(value=None),
18
22
  "null": ast.Constant(value=None),
@@ -28,12 +32,12 @@ class AstLoader:
28
32
  @classmethod
29
33
  def json_loads(cls, js: str, filename: str = "stdin") -> JsonValue:
30
34
  """
31
- The json_loads function loads a JSON object from a js/json string. It uses standard
35
+ The :meth:`~AstLoader.json_loads` function loads a JSON object from a js/json string. It uses standard
32
36
  :mod:`ast` module to parse the js/json.
33
37
 
34
38
  :param js: Used to Pass the js/json string to be parsed.
35
39
  :param filename: Used to Specify the name of the file that is being read. This is only for debug use.
36
- :return: A jsonvalue object.
40
+ :return: A :obj:`JsonValue` object.
37
41
  """
38
42
  js = dedent(js).replace(r"\/", "/")
39
43
  node = ast.parse(js, mode="eval")
@@ -43,14 +47,14 @@ class AstLoader:
43
47
 
44
48
 
45
49
  def json_loads(js: str) -> JsonValue:
46
- """The json_loads function converts a string representation of JS/JSON data into a Python object.
50
+ """The :meth:`json_loads` function converts a string representation of JS/JSON data into a Python object.
47
51
  Current implementation is using :external+python:mod:`ast`.
48
52
 
49
- If you need more parameters or another implementation, call `xxxLoader.json_loads` instead.
50
-
51
53
  .. seealso:: :meth:`.AstLoader.json_loads`
52
54
 
55
+ If you need more parameters or another implementation, call ``xxxLoader.json_loads`` instead.
56
+
53
57
  :param js: Used to Pass the JS/JSON string.
54
- :return: A jsonvalue object.
58
+ :return: A :obj:`JsonValue` object.
55
59
  """
56
60
  return AstLoader.json_loads(js)
@@ -9,12 +9,12 @@ __all__ = ["raise_for_status", "get_all_cookie", "ClientAdapter"]
9
9
 
10
10
 
11
11
  def raise_for_status(response: Response, *accept_code: int):
12
- """A checker more strict than :meth:`~httpx.Response.raise_for_status`.
12
+ """A checker more strict than :meth:`~aiohttp.ClientResponse.raise_for_status`.
13
13
 
14
14
  :param response: Client response to check.
15
15
  :param accept_code: Overwrite codes that can be accepted, If not given, default is `(200, )`
16
16
 
17
- :raise `httpx.HTTPStatusError`: if status not in :obj:`accept_code`
17
+ :raise `aiohttp.ClientResponseError`: if status not in :obj:`accept_code`
18
18
  """
19
19
  response.raise_for_status
20
20
  accept_code = accept_code or (200,)
File without changes