Skip to content

Commit c61c7ef

Browse files
authored
Fix async endpoints (#2)
The deprecation warning was bolted onto async endpoints in a way that stopped Python recognising them as async, so code that checks for that would take the wrong path.
1 parent c3d6f41 commit c61c7ef

43 files changed

Lines changed: 887 additions & 354 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/test.yml‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ jobs:
1414
# Builds the wheel, installs it, byte-compiles the tree and imports every
1515
# module. See scripts/verify_import.py.
1616
- run: make verify
17+
# Behavioural checks against a stub transport, so they need no API key.
18+
# scripts/smoke_test.py covers the live API and is run by hand.
19+
- run: uv run --group dev pytest tests/ -q
1720

1821
# Fail if the committed client is out of date with the committed schema — i.e.
1922
# someone changed openapi.json without re-running the generator. Regenerates
@@ -26,7 +29,10 @@ jobs:
2629
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
2730
# The generator's post_hooks shell out to ruff. Without it on PATH they
2831
# are skipped with a warning, and --fail-on-warning then fails the build.
29-
- run: uv tool install ruff
32+
# uv installs tools into ~/.local/bin, which isn't on a runner's PATH.
33+
- run: |
34+
uv tool install ruff
35+
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
3036
- run: make generate
3137
- name: Check for drift
3238
run: |

‎.gitignore‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ __pycache__/
66
*.py[cod]
77
.venv/
88
.venv-verify/
9+
10+
# Dev-only lock. This is a library, so we resolve dependencies fresh rather
11+
# than pinning what consumers get.
12+
uv.lock

‎incident_io/api/actions_v1/actions_v1_list.py‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -277,23 +277,32 @@ async def asyncio(
277277
).parsed
278278

279279
# --- deprecation markers added by scripts/mark_deprecated.py ---
280-
import functools as _functools
281-
import warnings as _warnings
280+
import functools as _functools # noqa: E402
281+
import warnings as _warnings # noqa: E402
282+
283+
_DEPRECATION_MESSAGE = "GET /v1/actions is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement."
282284

283285

284286
def _deprecated(_fn):
285287
@_functools.wraps(_fn)
286288
def _wrapper(*args, **kwargs):
287-
_warnings.warn(
288-
"GET /v1/actions is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.",
289-
DeprecationWarning,
290-
stacklevel=2,
291-
)
289+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
292290
return _fn(*args, **kwargs)
293291

294292
return _wrapper
295293

294+
295+
def _deprecated_async(_fn):
296+
# `async def`, so the result stays a coroutine function under
297+
# inspect.iscoroutinefunction. See this module's docstring.
298+
@_functools.wraps(_fn)
299+
async def _wrapper(*args, **kwargs):
300+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
301+
return await _fn(*args, **kwargs)
302+
303+
return _wrapper
304+
296305
sync_detailed = _deprecated(sync_detailed)
297306
sync = _deprecated(sync)
298-
asyncio_detailed = _deprecated(asyncio_detailed)
299-
asyncio = _deprecated(asyncio)
307+
asyncio_detailed = _deprecated_async(asyncio_detailed)
308+
asyncio = _deprecated_async(asyncio)

‎incident_io/api/actions_v1/actions_v1_show.py‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -229,23 +229,32 @@ async def asyncio(
229229
).parsed
230230

231231
# --- deprecation markers added by scripts/mark_deprecated.py ---
232-
import functools as _functools
233-
import warnings as _warnings
232+
import functools as _functools # noqa: E402
233+
import warnings as _warnings # noqa: E402
234+
235+
_DEPRECATION_MESSAGE = "GET /v1/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement."
234236

235237

236238
def _deprecated(_fn):
237239
@_functools.wraps(_fn)
238240
def _wrapper(*args, **kwargs):
239-
_warnings.warn(
240-
"GET /v1/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.",
241-
DeprecationWarning,
242-
stacklevel=2,
243-
)
241+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
244242
return _fn(*args, **kwargs)
245243

246244
return _wrapper
247245

246+
247+
def _deprecated_async(_fn):
248+
# `async def`, so the result stays a coroutine function under
249+
# inspect.iscoroutinefunction. See this module's docstring.
250+
@_functools.wraps(_fn)
251+
async def _wrapper(*args, **kwargs):
252+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
253+
return await _fn(*args, **kwargs)
254+
255+
return _wrapper
256+
248257
sync_detailed = _deprecated(sync_detailed)
249258
sync = _deprecated(sync)
250-
asyncio_detailed = _deprecated(asyncio_detailed)
251-
asyncio = _deprecated(asyncio)
259+
asyncio_detailed = _deprecated_async(asyncio_detailed)
260+
asyncio = _deprecated_async(asyncio)

‎incident_io/api/actions_v2/actions_v2_create.py‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -250,23 +250,32 @@ async def asyncio(
250250
).parsed
251251

252252
# --- deprecation markers added by scripts/mark_deprecated.py ---
253-
import functools as _functools
254-
import warnings as _warnings
253+
import functools as _functools # noqa: E402
254+
import warnings as _warnings # noqa: E402
255+
256+
_DEPRECATION_MESSAGE = "POST /v2/actions is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement."
255257

256258

257259
def _deprecated(_fn):
258260
@_functools.wraps(_fn)
259261
def _wrapper(*args, **kwargs):
260-
_warnings.warn(
261-
"POST /v2/actions is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.",
262-
DeprecationWarning,
263-
stacklevel=2,
264-
)
262+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
265263
return _fn(*args, **kwargs)
266264

267265
return _wrapper
268266

267+
268+
def _deprecated_async(_fn):
269+
# `async def`, so the result stays a coroutine function under
270+
# inspect.iscoroutinefunction. See this module's docstring.
271+
@_functools.wraps(_fn)
272+
async def _wrapper(*args, **kwargs):
273+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
274+
return await _fn(*args, **kwargs)
275+
276+
return _wrapper
277+
269278
sync_detailed = _deprecated(sync_detailed)
270279
sync = _deprecated(sync)
271-
asyncio_detailed = _deprecated(asyncio_detailed)
272-
asyncio = _deprecated(asyncio)
280+
asyncio_detailed = _deprecated_async(asyncio_detailed)
281+
asyncio = _deprecated_async(asyncio)

‎incident_io/api/actions_v2/actions_v2_delete.py‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -239,23 +239,32 @@ async def asyncio(
239239
).parsed
240240

241241
# --- deprecation markers added by scripts/mark_deprecated.py ---
242-
import functools as _functools
243-
import warnings as _warnings
242+
import functools as _functools # noqa: E402
243+
import warnings as _warnings # noqa: E402
244+
245+
_DEPRECATION_MESSAGE = "DELETE /v2/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement."
244246

245247

246248
def _deprecated(_fn):
247249
@_functools.wraps(_fn)
248250
def _wrapper(*args, **kwargs):
249-
_warnings.warn(
250-
"DELETE /v2/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.",
251-
DeprecationWarning,
252-
stacklevel=2,
253-
)
251+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
254252
return _fn(*args, **kwargs)
255253

256254
return _wrapper
257255

256+
257+
def _deprecated_async(_fn):
258+
# `async def`, so the result stays a coroutine function under
259+
# inspect.iscoroutinefunction. See this module's docstring.
260+
@_functools.wraps(_fn)
261+
async def _wrapper(*args, **kwargs):
262+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
263+
return await _fn(*args, **kwargs)
264+
265+
return _wrapper
266+
258267
sync_detailed = _deprecated(sync_detailed)
259268
sync = _deprecated(sync)
260-
asyncio_detailed = _deprecated(asyncio_detailed)
261-
asyncio = _deprecated(asyncio)
269+
asyncio_detailed = _deprecated_async(asyncio_detailed)
270+
asyncio = _deprecated_async(asyncio)

‎incident_io/api/actions_v2/actions_v2_list.py‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -274,23 +274,32 @@ async def asyncio(
274274
).parsed
275275

276276
# --- deprecation markers added by scripts/mark_deprecated.py ---
277-
import functools as _functools
278-
import warnings as _warnings
277+
import functools as _functools # noqa: E402
278+
import warnings as _warnings # noqa: E402
279+
280+
_DEPRECATION_MESSAGE = "GET /v2/actions is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement."
279281

280282

281283
def _deprecated(_fn):
282284
@_functools.wraps(_fn)
283285
def _wrapper(*args, **kwargs):
284-
_warnings.warn(
285-
"GET /v2/actions is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.",
286-
DeprecationWarning,
287-
stacklevel=2,
288-
)
286+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
289287
return _fn(*args, **kwargs)
290288

291289
return _wrapper
292290

291+
292+
def _deprecated_async(_fn):
293+
# `async def`, so the result stays a coroutine function under
294+
# inspect.iscoroutinefunction. See this module's docstring.
295+
@_functools.wraps(_fn)
296+
async def _wrapper(*args, **kwargs):
297+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
298+
return await _fn(*args, **kwargs)
299+
300+
return _wrapper
301+
293302
sync_detailed = _deprecated(sync_detailed)
294303
sync = _deprecated(sync)
295-
asyncio_detailed = _deprecated(asyncio_detailed)
296-
asyncio = _deprecated(asyncio)
304+
asyncio_detailed = _deprecated_async(asyncio_detailed)
305+
asyncio = _deprecated_async(asyncio)

‎incident_io/api/actions_v2/actions_v2_show.py‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -241,23 +241,32 @@ async def asyncio(
241241
).parsed
242242

243243
# --- deprecation markers added by scripts/mark_deprecated.py ---
244-
import functools as _functools
245-
import warnings as _warnings
244+
import functools as _functools # noqa: E402
245+
import warnings as _warnings # noqa: E402
246+
247+
_DEPRECATION_MESSAGE = "GET /v2/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement."
246248

247249

248250
def _deprecated(_fn):
249251
@_functools.wraps(_fn)
250252
def _wrapper(*args, **kwargs):
251-
_warnings.warn(
252-
"GET /v2/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.",
253-
DeprecationWarning,
254-
stacklevel=2,
255-
)
253+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
256254
return _fn(*args, **kwargs)
257255

258256
return _wrapper
259257

258+
259+
def _deprecated_async(_fn):
260+
# `async def`, so the result stays a coroutine function under
261+
# inspect.iscoroutinefunction. See this module's docstring.
262+
@_functools.wraps(_fn)
263+
async def _wrapper(*args, **kwargs):
264+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
265+
return await _fn(*args, **kwargs)
266+
267+
return _wrapper
268+
260269
sync_detailed = _deprecated(sync_detailed)
261270
sync = _deprecated(sync)
262-
asyncio_detailed = _deprecated(asyncio_detailed)
263-
asyncio = _deprecated(asyncio)
271+
asyncio_detailed = _deprecated_async(asyncio_detailed)
272+
asyncio = _deprecated_async(asyncio)

‎incident_io/api/actions_v2/actions_v2_update.py‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -266,23 +266,32 @@ async def asyncio(
266266
).parsed
267267

268268
# --- deprecation markers added by scripts/mark_deprecated.py ---
269-
import functools as _functools
270-
import warnings as _warnings
269+
import functools as _functools # noqa: E402
270+
import warnings as _warnings # noqa: E402
271+
272+
_DEPRECATION_MESSAGE = "PUT /v2/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement."
271273

272274

273275
def _deprecated(_fn):
274276
@_functools.wraps(_fn)
275277
def _wrapper(*args, **kwargs):
276-
_warnings.warn(
277-
"PUT /v2/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.",
278-
DeprecationWarning,
279-
stacklevel=2,
280-
)
278+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
281279
return _fn(*args, **kwargs)
282280

283281
return _wrapper
284282

283+
284+
def _deprecated_async(_fn):
285+
# `async def`, so the result stays a coroutine function under
286+
# inspect.iscoroutinefunction. See this module's docstring.
287+
@_functools.wraps(_fn)
288+
async def _wrapper(*args, **kwargs):
289+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
290+
return await _fn(*args, **kwargs)
291+
292+
return _wrapper
293+
285294
sync_detailed = _deprecated(sync_detailed)
286295
sync = _deprecated(sync)
287-
asyncio_detailed = _deprecated(asyncio_detailed)
288-
asyncio = _deprecated(asyncio)
296+
asyncio_detailed = _deprecated_async(asyncio_detailed)
297+
asyncio = _deprecated_async(asyncio)

‎incident_io/api/catalog_v2/catalog_v2_create_entry.py‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -262,23 +262,32 @@ async def asyncio(
262262
).parsed
263263

264264
# --- deprecation markers added by scripts/mark_deprecated.py ---
265-
import functools as _functools
266-
import warnings as _warnings
265+
import functools as _functools # noqa: E402
266+
import warnings as _warnings # noqa: E402
267+
268+
_DEPRECATION_MESSAGE = "POST /v2/catalog_entries is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement."
267269

268270

269271
def _deprecated(_fn):
270272
@_functools.wraps(_fn)
271273
def _wrapper(*args, **kwargs):
272-
_warnings.warn(
273-
"POST /v2/catalog_entries is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.",
274-
DeprecationWarning,
275-
stacklevel=2,
276-
)
274+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
277275
return _fn(*args, **kwargs)
278276

279277
return _wrapper
280278

279+
280+
def _deprecated_async(_fn):
281+
# `async def`, so the result stays a coroutine function under
282+
# inspect.iscoroutinefunction. See this module's docstring.
283+
@_functools.wraps(_fn)
284+
async def _wrapper(*args, **kwargs):
285+
_warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
286+
return await _fn(*args, **kwargs)
287+
288+
return _wrapper
289+
281290
sync_detailed = _deprecated(sync_detailed)
282291
sync = _deprecated(sync)
283-
asyncio_detailed = _deprecated(asyncio_detailed)
284-
asyncio = _deprecated(asyncio)
292+
asyncio_detailed = _deprecated_async(asyncio_detailed)
293+
asyncio = _deprecated_async(asyncio)

0 commit comments

Comments
 (0)