From 88524d786000c0225cc19e04177079e64130eae6 Mon Sep 17 00:00:00 2001 From: Johanna Larsson Date: Tue, 22 Sep 2026 10:53:18 +0100 Subject: [PATCH] Fix async endpoints 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. --- .github/workflows/test.yml | 8 +- .gitignore | 4 + incident_io/api/actions_v1/actions_v1_list.py | 27 ++-- incident_io/api/actions_v1/actions_v1_show.py | 27 ++-- .../api/actions_v2/actions_v2_create.py | 27 ++-- .../api/actions_v2/actions_v2_delete.py | 27 ++-- incident_io/api/actions_v2/actions_v2_list.py | 27 ++-- incident_io/api/actions_v2/actions_v2_show.py | 27 ++-- .../api/actions_v2/actions_v2_update.py | 27 ++-- .../api/catalog_v2/catalog_v2_create_entry.py | 27 ++-- .../api/catalog_v2/catalog_v2_create_type.py | 27 ++-- .../catalog_v2/catalog_v2_destroy_entry.py | 27 ++-- .../api/catalog_v2/catalog_v2_destroy_type.py | 27 ++-- .../api/catalog_v2/catalog_v2_list_entries.py | 27 ++-- .../catalog_v2/catalog_v2_list_resources.py | 27 ++-- .../api/catalog_v2/catalog_v2_list_types.py | 27 ++-- .../api/catalog_v2/catalog_v2_show_entry.py | 27 ++-- .../api/catalog_v2/catalog_v2_show_type.py | 27 ++-- .../api/catalog_v2/catalog_v2_update_entry.py | 27 ++-- .../api/catalog_v2/catalog_v2_update_type.py | 27 ++-- .../catalog_v2_update_type_schema.py | 27 ++-- .../custom_fields_v1_create.py | 27 ++-- .../custom_fields_v1_delete.py | 27 ++-- .../custom_fields_v1/custom_fields_v1_list.py | 27 ++-- .../custom_fields_v1/custom_fields_v1_show.py | 27 ++-- .../custom_fields_v1_update.py | 27 ++-- .../follow_ups_v2_connect_external_issue.py | 27 ++-- .../api/follow_ups_v2/follow_ups_v2_create.py | 27 ++-- .../api/follow_ups_v2/follow_ups_v2_delete.py | 27 ++-- .../api/follow_ups_v2/follow_ups_v2_list.py | 27 ++-- .../api/follow_ups_v2/follow_ups_v2_show.py | 27 ++-- .../api/follow_ups_v2/follow_ups_v2_update.py | 27 ++-- .../incident_roles_v1_create.py | 27 ++-- .../incident_roles_v1_delete.py | 27 ++-- .../incident_roles_v1_list.py | 27 ++-- .../incident_roles_v1_show.py | 27 ++-- .../incident_roles_v1_update.py | 27 ++-- .../api/incidents_v1/incidents_v1_create.py | 27 ++-- .../api/incidents_v1/incidents_v1_list.py | 27 ++-- .../api/incidents_v1/incidents_v1_show.py | 27 ++-- pyproject.toml | 9 ++ scripts/mark_deprecated.py | 41 +++-- tests/test_sdk.py | 153 ++++++++++++++++++ 43 files changed, 887 insertions(+), 354 deletions(-) create mode 100644 tests/test_sdk.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ecaacb5..0343a2c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,6 +14,9 @@ jobs: # Builds the wheel, installs it, byte-compiles the tree and imports every # module. See scripts/verify_import.py. - run: make verify + # Behavioural checks against a stub transport, so they need no API key. + # scripts/smoke_test.py covers the live API and is run by hand. + - run: uv run --group dev pytest tests/ -q # Fail if the committed client is out of date with the committed schema — i.e. # someone changed openapi.json without re-running the generator. Regenerates @@ -26,7 +29,10 @@ jobs: - uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0 # The generator's post_hooks shell out to ruff. Without it on PATH they # are skipped with a warning, and --fail-on-warning then fails the build. - - run: uv tool install ruff + # uv installs tools into ~/.local/bin, which isn't on a runner's PATH. + - run: | + uv tool install ruff + echo "$HOME/.local/bin" >> "$GITHUB_PATH" - run: make generate - name: Check for drift run: | diff --git a/.gitignore b/.gitignore index 49e64a7..423d683 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,7 @@ __pycache__/ *.py[cod] .venv/ .venv-verify/ + +# Dev-only lock. This is a library, so we resolve dependencies fresh rather +# than pinning what consumers get. +uv.lock diff --git a/incident_io/api/actions_v1/actions_v1_list.py b/incident_io/api/actions_v1/actions_v1_list.py index 2858ddc..d4dbd37 100644 --- a/incident_io/api/actions_v1/actions_v1_list.py +++ b/incident_io/api/actions_v1/actions_v1_list.py @@ -277,23 +277,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v1/actions is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v1/actions is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/actions_v1/actions_v1_show.py b/incident_io/api/actions_v1/actions_v1_show.py index e9d78b6..508e0ce 100644 --- a/incident_io/api/actions_v1/actions_v1_show.py +++ b/incident_io/api/actions_v1/actions_v1_show.py @@ -229,23 +229,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v1/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v1/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/actions_v2/actions_v2_create.py b/incident_io/api/actions_v2/actions_v2_create.py index 543db68..121f4af 100644 --- a/incident_io/api/actions_v2/actions_v2_create.py +++ b/incident_io/api/actions_v2/actions_v2_create.py @@ -250,23 +250,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "POST /v2/actions is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "POST /v2/actions is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/actions_v2/actions_v2_delete.py b/incident_io/api/actions_v2/actions_v2_delete.py index 6ca5be6..58789ba 100644 --- a/incident_io/api/actions_v2/actions_v2_delete.py +++ b/incident_io/api/actions_v2/actions_v2_delete.py @@ -239,23 +239,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "DELETE /v2/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "DELETE /v2/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/actions_v2/actions_v2_list.py b/incident_io/api/actions_v2/actions_v2_list.py index 0e0d1cc..9d1343a 100644 --- a/incident_io/api/actions_v2/actions_v2_list.py +++ b/incident_io/api/actions_v2/actions_v2_list.py @@ -274,23 +274,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v2/actions is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v2/actions is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/actions_v2/actions_v2_show.py b/incident_io/api/actions_v2/actions_v2_show.py index a42a670..fcc8530 100644 --- a/incident_io/api/actions_v2/actions_v2_show.py +++ b/incident_io/api/actions_v2/actions_v2_show.py @@ -241,23 +241,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v2/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v2/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/actions_v2/actions_v2_update.py b/incident_io/api/actions_v2/actions_v2_update.py index 303af2a..40bcb87 100644 --- a/incident_io/api/actions_v2/actions_v2_update.py +++ b/incident_io/api/actions_v2/actions_v2_update.py @@ -266,23 +266,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "PUT /v2/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "PUT /v2/actions/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/catalog_v2/catalog_v2_create_entry.py b/incident_io/api/catalog_v2/catalog_v2_create_entry.py index 1be4325..02db7f3 100644 --- a/incident_io/api/catalog_v2/catalog_v2_create_entry.py +++ b/incident_io/api/catalog_v2/catalog_v2_create_entry.py @@ -262,23 +262,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "POST /v2/catalog_entries is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "POST /v2/catalog_entries is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/catalog_v2/catalog_v2_create_type.py b/incident_io/api/catalog_v2/catalog_v2_create_type.py index e83afe4..e7ff4b3 100644 --- a/incident_io/api/catalog_v2/catalog_v2_create_type.py +++ b/incident_io/api/catalog_v2/catalog_v2_create_type.py @@ -254,23 +254,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "POST /v2/catalog_types is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "POST /v2/catalog_types is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/catalog_v2/catalog_v2_destroy_entry.py b/incident_io/api/catalog_v2/catalog_v2_destroy_entry.py index b880209..b42d63c 100644 --- a/incident_io/api/catalog_v2/catalog_v2_destroy_entry.py +++ b/incident_io/api/catalog_v2/catalog_v2_destroy_entry.py @@ -227,23 +227,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "DELETE /v2/catalog_entries/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "DELETE /v2/catalog_entries/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/catalog_v2/catalog_v2_destroy_type.py b/incident_io/api/catalog_v2/catalog_v2_destroy_type.py index 9c93988..cb7d10e 100644 --- a/incident_io/api/catalog_v2/catalog_v2_destroy_type.py +++ b/incident_io/api/catalog_v2/catalog_v2_destroy_type.py @@ -227,23 +227,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "DELETE /v2/catalog_types/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "DELETE /v2/catalog_types/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/catalog_v2/catalog_v2_list_entries.py b/incident_io/api/catalog_v2/catalog_v2_list_entries.py index f8fc91f..03b5bfa 100644 --- a/incident_io/api/catalog_v2/catalog_v2_list_entries.py +++ b/incident_io/api/catalog_v2/catalog_v2_list_entries.py @@ -268,23 +268,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v2/catalog_entries is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v2/catalog_entries is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/catalog_v2/catalog_v2_list_resources.py b/incident_io/api/catalog_v2/catalog_v2_list_resources.py index 7c5aa7d..47b7ca8 100644 --- a/incident_io/api/catalog_v2/catalog_v2_list_resources.py +++ b/incident_io/api/catalog_v2/catalog_v2_list_resources.py @@ -218,23 +218,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v2/catalog_resources is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v2/catalog_resources is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/catalog_v2/catalog_v2_list_types.py b/incident_io/api/catalog_v2/catalog_v2_list_types.py index 22eb88a..1b2459a 100644 --- a/incident_io/api/catalog_v2/catalog_v2_list_types.py +++ b/incident_io/api/catalog_v2/catalog_v2_list_types.py @@ -202,23 +202,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v2/catalog_types is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v2/catalog_types is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/catalog_v2/catalog_v2_show_entry.py b/incident_io/api/catalog_v2/catalog_v2_show_entry.py index 02f1025..2f0458a 100644 --- a/incident_io/api/catalog_v2/catalog_v2_show_entry.py +++ b/incident_io/api/catalog_v2/catalog_v2_show_entry.py @@ -229,23 +229,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v2/catalog_entries/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v2/catalog_entries/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/catalog_v2/catalog_v2_show_type.py b/incident_io/api/catalog_v2/catalog_v2_show_type.py index 237dab7..9ec8aef 100644 --- a/incident_io/api/catalog_v2/catalog_v2_show_type.py +++ b/incident_io/api/catalog_v2/catalog_v2_show_type.py @@ -229,23 +229,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v2/catalog_types/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v2/catalog_types/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/catalog_v2/catalog_v2_update_entry.py b/incident_io/api/catalog_v2/catalog_v2_update_entry.py index a09d671..3066a4d 100644 --- a/incident_io/api/catalog_v2/catalog_v2_update_entry.py +++ b/incident_io/api/catalog_v2/catalog_v2_update_entry.py @@ -266,23 +266,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "PUT /v2/catalog_entries/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "PUT /v2/catalog_entries/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/catalog_v2/catalog_v2_update_type.py b/incident_io/api/catalog_v2/catalog_v2_update_type.py index 05e1775..c6d1a28 100644 --- a/incident_io/api/catalog_v2/catalog_v2_update_type.py +++ b/incident_io/api/catalog_v2/catalog_v2_update_type.py @@ -266,23 +266,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "PUT /v2/catalog_types/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "PUT /v2/catalog_types/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/catalog_v2/catalog_v2_update_type_schema.py b/incident_io/api/catalog_v2/catalog_v2_update_type_schema.py index 384ad71..959f4b1 100644 --- a/incident_io/api/catalog_v2/catalog_v2_update_type_schema.py +++ b/incident_io/api/catalog_v2/catalog_v2_update_type_schema.py @@ -294,23 +294,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "POST /v2/catalog_types/{id}/actions/update_schema is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "POST /v2/catalog_types/{id}/actions/update_schema is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/custom_fields_v1/custom_fields_v1_create.py b/incident_io/api/custom_fields_v1/custom_fields_v1_create.py index 21a8846..98fe68e 100644 --- a/incident_io/api/custom_fields_v1/custom_fields_v1_create.py +++ b/incident_io/api/custom_fields_v1/custom_fields_v1_create.py @@ -246,23 +246,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "POST /v1/custom_fields is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "POST /v1/custom_fields is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/custom_fields_v1/custom_fields_v1_delete.py b/incident_io/api/custom_fields_v1/custom_fields_v1_delete.py index 4c3c012..1cc0995 100644 --- a/incident_io/api/custom_fields_v1/custom_fields_v1_delete.py +++ b/incident_io/api/custom_fields_v1/custom_fields_v1_delete.py @@ -227,23 +227,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "DELETE /v1/custom_fields/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "DELETE /v1/custom_fields/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/custom_fields_v1/custom_fields_v1_list.py b/incident_io/api/custom_fields_v1/custom_fields_v1_list.py index d423b74..8bfee3a 100644 --- a/incident_io/api/custom_fields_v1/custom_fields_v1_list.py +++ b/incident_io/api/custom_fields_v1/custom_fields_v1_list.py @@ -202,23 +202,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v1/custom_fields is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v1/custom_fields is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/custom_fields_v1/custom_fields_v1_show.py b/incident_io/api/custom_fields_v1/custom_fields_v1_show.py index 224f107..154fe93 100644 --- a/incident_io/api/custom_fields_v1/custom_fields_v1_show.py +++ b/incident_io/api/custom_fields_v1/custom_fields_v1_show.py @@ -229,23 +229,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v1/custom_fields/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v1/custom_fields/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/custom_fields_v1/custom_fields_v1_update.py b/incident_io/api/custom_fields_v1/custom_fields_v1_update.py index ee4f2b3..2f61fc4 100644 --- a/incident_io/api/custom_fields_v1/custom_fields_v1_update.py +++ b/incident_io/api/custom_fields_v1/custom_fields_v1_update.py @@ -262,23 +262,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "PUT /v1/custom_fields/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "PUT /v1/custom_fields/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/follow_ups_v2/follow_ups_v2_connect_external_issue.py b/incident_io/api/follow_ups_v2/follow_ups_v2_connect_external_issue.py index 0f35e8a..1738343 100644 --- a/incident_io/api/follow_ups_v2/follow_ups_v2_connect_external_issue.py +++ b/incident_io/api/follow_ups_v2/follow_ups_v2_connect_external_issue.py @@ -278,23 +278,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "POST /v2/follow_ups/{id}/actions/connect_external_issue is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "POST /v2/follow_ups/{id}/actions/connect_external_issue is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/follow_ups_v2/follow_ups_v2_create.py b/incident_io/api/follow_ups_v2/follow_ups_v2_create.py index 9bad0e6..0060922 100644 --- a/incident_io/api/follow_ups_v2/follow_ups_v2_create.py +++ b/incident_io/api/follow_ups_v2/follow_ups_v2_create.py @@ -266,23 +266,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "POST /v2/follow_ups is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "POST /v2/follow_ups is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/follow_ups_v2/follow_ups_v2_delete.py b/incident_io/api/follow_ups_v2/follow_ups_v2_delete.py index 43ac3e5..6c2b310 100644 --- a/incident_io/api/follow_ups_v2/follow_ups_v2_delete.py +++ b/incident_io/api/follow_ups_v2/follow_ups_v2_delete.py @@ -239,23 +239,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "DELETE /v2/follow_ups/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "DELETE /v2/follow_ups/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/follow_ups_v2/follow_ups_v2_list.py b/incident_io/api/follow_ups_v2/follow_ups_v2_list.py index bd72d81..aba51c7 100644 --- a/incident_io/api/follow_ups_v2/follow_ups_v2_list.py +++ b/incident_io/api/follow_ups_v2/follow_ups_v2_list.py @@ -293,23 +293,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v2/follow_ups is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v2/follow_ups is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/follow_ups_v2/follow_ups_v2_show.py b/incident_io/api/follow_ups_v2/follow_ups_v2_show.py index 906c2fb..98a09ee 100644 --- a/incident_io/api/follow_ups_v2/follow_ups_v2_show.py +++ b/incident_io/api/follow_ups_v2/follow_ups_v2_show.py @@ -241,23 +241,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v2/follow_ups/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v2/follow_ups/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/follow_ups_v2/follow_ups_v2_update.py b/incident_io/api/follow_ups_v2/follow_ups_v2_update.py index f6c116d..298337d 100644 --- a/incident_io/api/follow_ups_v2/follow_ups_v2_update.py +++ b/incident_io/api/follow_ups_v2/follow_ups_v2_update.py @@ -278,23 +278,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "PUT /v2/follow_ups/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "PUT /v2/follow_ups/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/incident_roles_v1/incident_roles_v1_create.py b/incident_io/api/incident_roles_v1/incident_roles_v1_create.py index cf4432d..48183dc 100644 --- a/incident_io/api/incident_roles_v1/incident_roles_v1_create.py +++ b/incident_io/api/incident_roles_v1/incident_roles_v1_create.py @@ -246,23 +246,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "POST /v1/incident_roles is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "POST /v1/incident_roles is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/incident_roles_v1/incident_roles_v1_delete.py b/incident_io/api/incident_roles_v1/incident_roles_v1_delete.py index ed97d6b..dea6117 100644 --- a/incident_io/api/incident_roles_v1/incident_roles_v1_delete.py +++ b/incident_io/api/incident_roles_v1/incident_roles_v1_delete.py @@ -227,23 +227,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "DELETE /v1/incident_roles/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "DELETE /v1/incident_roles/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/incident_roles_v1/incident_roles_v1_list.py b/incident_io/api/incident_roles_v1/incident_roles_v1_list.py index f3476c5..807b4b8 100644 --- a/incident_io/api/incident_roles_v1/incident_roles_v1_list.py +++ b/incident_io/api/incident_roles_v1/incident_roles_v1_list.py @@ -202,23 +202,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v1/incident_roles is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v1/incident_roles is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/incident_roles_v1/incident_roles_v1_show.py b/incident_io/api/incident_roles_v1/incident_roles_v1_show.py index 51dd548..92e7bc4 100644 --- a/incident_io/api/incident_roles_v1/incident_roles_v1_show.py +++ b/incident_io/api/incident_roles_v1/incident_roles_v1_show.py @@ -229,23 +229,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v1/incident_roles/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v1/incident_roles/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/incident_roles_v1/incident_roles_v1_update.py b/incident_io/api/incident_roles_v1/incident_roles_v1_update.py index 766bb7a..f13bb29 100644 --- a/incident_io/api/incident_roles_v1/incident_roles_v1_update.py +++ b/incident_io/api/incident_roles_v1/incident_roles_v1_update.py @@ -262,23 +262,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "PUT /v1/incident_roles/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "PUT /v1/incident_roles/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/incidents_v1/incidents_v1_create.py b/incident_io/api/incidents_v1/incidents_v1_create.py index b4af182..0a62172 100644 --- a/incident_io/api/incidents_v1/incidents_v1_create.py +++ b/incident_io/api/incidents_v1/incidents_v1_create.py @@ -282,23 +282,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "POST /v1/incidents is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "POST /v1/incidents is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/incidents_v1/incidents_v1_list.py b/incident_io/api/incidents_v1/incidents_v1_list.py index 67b5af7..1437ed9 100644 --- a/incident_io/api/incidents_v1/incidents_v1_list.py +++ b/incident_io/api/incidents_v1/incidents_v1_list.py @@ -272,23 +272,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v1/incidents is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v1/incidents is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/incident_io/api/incidents_v1/incidents_v1_show.py b/incident_io/api/incidents_v1/incidents_v1_show.py index b472265..0fa796c 100644 --- a/incident_io/api/incidents_v1/incidents_v1_show.py +++ b/incident_io/api/incidents_v1/incidents_v1_show.py @@ -229,23 +229,32 @@ async def asyncio( ).parsed # --- deprecation markers added by scripts/mark_deprecated.py --- -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "GET /v1/incidents/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement." def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "GET /v1/incidents/{id} is deprecated and will be removed. See https://api-docs.incident.io/ for the replacement.", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + sync_detailed = _deprecated(sync_detailed) sync = _deprecated(sync) -asyncio_detailed = _deprecated(asyncio_detailed) -asyncio = _deprecated(asyncio) +asyncio_detailed = _deprecated_async(asyncio_detailed) +asyncio = _deprecated_async(asyncio) diff --git a/pyproject.toml b/pyproject.toml index 0b471d4..ef79bdc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,3 +38,12 @@ packages = ["incident_io"] [tool.hatch.build.targets.sdist] include = ["incident_io", "openapi.json", "LICENSE", "README.md"] + +[dependency-groups] +dev = [ + "pytest>=8", + "pytest-asyncio>=0.24", +] + +[tool.pytest.ini_options] +asyncio_mode = "auto" diff --git a/scripts/mark_deprecated.py b/scripts/mark_deprecated.py index 19bdbc8..db173c2 100755 --- a/scripts/mark_deprecated.py +++ b/scripts/mark_deprecated.py @@ -7,8 +7,13 @@ We find each module by the method and URL it calls, rather than guessing at the generator's file naming, and append a wrapper rather than editing generated code -in place. One wrapper covers both the sync and async entry points, since -awaiting its return value awaits the coroutine underneath. +in place. + +The async entry points need their own wrapper. Wrapping `async def` in a plain +`def` that returns the coroutine still awaits correctly, but the result is no +longer a coroutine function: `inspect.iscoroutinefunction` returns False, and +anything that branches on that — test frameworks, task runners, DI containers — +takes the wrong path. """ from __future__ import annotations @@ -18,29 +23,40 @@ import sys from pathlib import Path -ENTRY_POINTS = ("sync_detailed", "sync", "asyncio_detailed", "asyncio") +SYNC_ENTRY_POINTS = ("sync_detailed", "sync") +ASYNC_ENTRY_POINTS = ("asyncio_detailed", "asyncio") +ENTRY_POINTS = SYNC_ENTRY_POINTS + ASYNC_ENTRY_POINTS METHODS = ("get", "post", "put", "patch", "delete") MARKER = "# --- deprecation markers added by scripts/mark_deprecated.py ---" TEMPLATE = ''' {marker} -import functools as _functools -import warnings as _warnings +import functools as _functools # noqa: E402 +import warnings as _warnings # noqa: E402 + +_DEPRECATION_MESSAGE = "{message}" def _deprecated(_fn): @_functools.wraps(_fn) def _wrapper(*args, **kwargs): - _warnings.warn( - "{message}", - DeprecationWarning, - stacklevel=2, - ) + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) return _fn(*args, **kwargs) return _wrapper + +def _deprecated_async(_fn): + # `async def`, so the result stays a coroutine function under + # inspect.iscoroutinefunction. See this module's docstring. + @_functools.wraps(_fn) + async def _wrapper(*args, **kwargs): + _warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2) + return await _fn(*args, **kwargs) + + return _wrapper + {rebinds} ''' @@ -79,7 +95,10 @@ def mark(file: Path, method: str, path: str) -> bool: f"{method.upper()} {path} is deprecated and will be removed. " "See https://api-docs.incident.io/ for the replacement." ) - rebinds = "\n".join(f"{name} = _deprecated({name})" for name in present) + rebinds = "\n".join( + f"{name} = {'_deprecated_async' if name in ASYNC_ENTRY_POINTS else '_deprecated'}({name})" + for name in present + ) file.write_text(source.rstrip("\n") + TEMPLATE.format(marker=MARKER, message=message, rebinds=rebinds)) return True diff --git a/tests/test_sdk.py b/tests/test_sdk.py new file mode 100644 index 0000000..434fff1 --- /dev/null +++ b/tests/test_sdk.py @@ -0,0 +1,153 @@ +"""Behavioural tests that need no API key. + +`make verify` proves every generated module imports. These prove the parts we +are responsible for actually behave: the client we hand callers, and the +deprecation wrappers scripts/mark_deprecated.py appends after generation. + +Requests are served by a local httpx transport rather than the real API, so +these run on a pull request. scripts/smoke_test.py covers the live API. +""" + +from __future__ import annotations + +import inspect +import warnings +from pathlib import Path + +import httpx +import pytest + +import incident_io +from incident_io import AuthenticatedClient +from incident_io.api.actions_v1 import actions_v1_list +from incident_io.api.severities_v1 import severities_v1_list + +SEVERITIES_BODY = { + "severities": [ + { + "id": "01FCNDV6P870EA6S7TK1DSYDG0", + "name": "Minor", + "description": "Issues with low impact.", + "rank": 1, + "created_at": "2021-08-17T13:28:57.801578Z", + "updated_at": "2021-08-17T13:28:57.801578Z", + } + ] +} + + +def client_returning(status_code: int, body: dict, record: list[httpx.Request] | None = None): + """An AuthenticatedClient wired to a stub transport instead of the network.""" + + def handler(request: httpx.Request) -> httpx.Response: + if record is not None: + record.append(request) + return httpx.Response(status_code, json=body) + + # Handed to the SDK as an httpx argument rather than via set_httpx_client, + # which would replace the client the SDK builds and so bypass the base_url + # and auth header these tests exist to check. + return AuthenticatedClient( + base_url="https://api.incident.io", + token="test-key", + httpx_args={"transport": httpx.MockTransport(handler)}, + ) + + +def test_sends_bearer_token_and_builds_the_url(): + requests: list[httpx.Request] = [] + client = client_returning(200, SEVERITIES_BODY, requests) + + severities_v1_list.sync_detailed(client=client) + + assert len(requests) == 1 + assert requests[0].headers["Authorization"] == "Bearer test-key" + assert str(requests[0].url) == "https://api.incident.io/v1/severities" + + +def test_deserialises_a_response(): + client = client_returning(200, SEVERITIES_BODY) + + result = severities_v1_list.sync(client=client) + + assert len(result.severities) == 1 + assert result.severities[0].name == "Minor" + # Dates come back parsed, not as strings. + assert result.severities[0].created_at.year == 2021 + + +def test_an_error_status_is_returned_not_raised(): + body = { + "type": "validation_error", + "status": 422, + "request_id": "01FCNDV6P870EA6S7TK1DSYDG0", + "errors": [{"code": "invalid", "message": "Something was wrong"}], + } + client = client_returning(422, body) + + response = severities_v1_list.sync_detailed(client=client) + + assert response.status_code == 422 + + +@pytest.mark.asyncio +async def test_the_async_entry_point_works(): + client = client_returning(200, SEVERITIES_BODY) + + result = await severities_v1_list.asyncio(client=client) + + assert result.severities[0].name == "Minor" + + +# The generated package has no deprecated endpoints of its own — these cover +# what scripts/mark_deprecated.py adds afterwards, which is the part we own. + + +def test_a_deprecated_endpoint_warns(): + client = client_returning(200, {"actions": []}) + + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("always") + actions_v1_list.sync_detailed(client=client) + + messages = [str(w.message) for w in caught if w.category is DeprecationWarning] + assert messages, "no DeprecationWarning was raised" + assert "GET /v1/actions" in messages[0] + + +def test_a_deprecated_async_endpoint_stays_a_coroutine_function(): + """Wrapping `async def` in a plain `def` would break anything that branches + on inspect.iscoroutinefunction, even though `await` still works.""" + assert inspect.iscoroutinefunction(actions_v1_list.asyncio) + assert inspect.iscoroutinefunction(actions_v1_list.asyncio_detailed) + + +@pytest.mark.asyncio +async def test_a_deprecated_async_endpoint_warns_and_still_returns(): + client = client_returning(200, {"actions": []}) + + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("always") + response = await actions_v1_list.asyncio_detailed(client=client) + + assert response.status_code == 200 + assert [w for w in caught if w.category is DeprecationWarning] + + +def test_an_undeprecated_endpoint_does_not_warn(): + client = client_returning(200, SEVERITIES_BODY) + + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("always") + severities_v1_list.sync_detailed(client=client) + + assert not [w for w in caught if w.category is DeprecationWarning] + + +def test_the_package_ships_a_py_typed_marker(): + """Without it, mypy and pyright ignore every annotation in the SDK. `make + generate` removes the package and recreates the marker, so this catches it + going missing.""" + marker = Path(incident_io.__path__[0]) / "py.typed" + + assert marker.exists(), f"{marker} is missing"