mirror of
https://github.com/python-kasa/python-kasa.git
synced 2025-08-06 10:44:04 +00:00
Add tutorial doctest module and enable top level await (#919)
Add a tutorial module with examples that can be tested with `doctest`. In order to simplify the examples they can be run with doctest allowing top level await statements by adding a fixture to patch the builtins that xdoctest uses to test code. --------- Co-authored-by: Teemu R. <tpr@iki.fi>
This commit is contained in:
@@ -175,7 +175,7 @@
|
||||
"longitude": 0,
|
||||
"mac": "5C-E9-31-00-00-00",
|
||||
"model": "L530",
|
||||
"nickname": "I01BU0tFRF9OQU1FIw==",
|
||||
"nickname": "TGl2aW5nIFJvb20=",
|
||||
"oem_id": "00000000000000000000000000000000",
|
||||
"overheated": false,
|
||||
"region": "Europe/Berlin",
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import asyncio
|
||||
|
||||
import pytest
|
||||
import xdoctest
|
||||
|
||||
from kasa import Discover
|
||||
from kasa.tests.conftest import get_device_for_fixture_protocol
|
||||
|
||||
|
||||
@@ -67,3 +69,61 @@ def test_discovery_examples(mocker):
|
||||
mocker.patch("kasa.discover.Discover.discover", return_value=[p])
|
||||
res = xdoctest.doctest_module("kasa.discover", "all")
|
||||
assert not res["failed"]
|
||||
|
||||
|
||||
def test_tutorial_examples(mocker, top_level_await):
|
||||
"""Test discovery examples."""
|
||||
a = asyncio.run(
|
||||
get_device_for_fixture_protocol("L530E(EU)_3.0_1.1.6.json", "SMART")
|
||||
)
|
||||
b = asyncio.run(get_device_for_fixture_protocol("HS110(EU)_1.0_1.2.5.json", "IOT"))
|
||||
a.host = "127.0.0.1"
|
||||
b.host = "127.0.0.2"
|
||||
|
||||
# Note autospec does not work for staticmethods in python < 3.12
|
||||
# https://github.com/python/cpython/issues/102978
|
||||
mocker.patch(
|
||||
"kasa.discover.Discover.discover_single", return_value=a, autospec=True
|
||||
)
|
||||
mocker.patch.object(Discover, "discover", return_value=[a, b], autospec=True)
|
||||
res = xdoctest.doctest_module("docs/tutorial.py", "all")
|
||||
assert not res["failed"]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def top_level_await(mocker):
|
||||
"""Fixture to enable top level awaits in doctests.
|
||||
|
||||
Uses the async exec feature of python to patch the builtins xdoctest uses.
|
||||
See https://github.com/python/cpython/issues/78797
|
||||
"""
|
||||
import ast
|
||||
from inspect import CO_COROUTINE
|
||||
|
||||
orig_exec = exec
|
||||
orig_eval = eval
|
||||
orig_compile = compile
|
||||
|
||||
def patch_exec(source, globals=None, locals=None, /, **kwargs):
|
||||
if source.co_flags & CO_COROUTINE == CO_COROUTINE:
|
||||
asyncio.run(orig_eval(source, globals, locals))
|
||||
else:
|
||||
orig_exec(source, globals, locals, **kwargs)
|
||||
|
||||
def patch_eval(source, globals=None, locals=None, /, **kwargs):
|
||||
if source.co_flags & CO_COROUTINE == CO_COROUTINE:
|
||||
return asyncio.run(orig_eval(source, globals, locals, **kwargs))
|
||||
else:
|
||||
return orig_eval(source, globals, locals, **kwargs)
|
||||
|
||||
def patch_compile(
|
||||
source, filename, mode, flags=0, dont_inherit=False, optimize=-1, **kwargs
|
||||
):
|
||||
flags |= ast.PyCF_ALLOW_TOP_LEVEL_AWAIT
|
||||
return orig_compile(
|
||||
source, filename, mode, flags, dont_inherit, optimize, **kwargs
|
||||
)
|
||||
|
||||
mocker.patch("builtins.eval", side_effect=patch_eval)
|
||||
mocker.patch("builtins.exec", side_effect=patch_exec)
|
||||
mocker.patch("builtins.compile", side_effect=patch_compile)
|
||||
|
Reference in New Issue
Block a user