Add 'shell' command to cli (#738)

* Add 'shell' command to cli

* Add test

* Add ptpython as optional dep
This commit is contained in:
Teemu R 2024-02-06 14:48:19 +01:00 committed by GitHub
parent 6ab17d823c
commit 458949157a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 43 additions and 0 deletions

View File

@ -1081,5 +1081,26 @@ async def update_credentials(dev, username, password):
return await dev.update_credentials(username, password) return await dev.update_credentials(username, password)
@cli.command()
@pass_dev
async def shell(dev: Device):
"""Open interactive shell."""
echo("Opening shell for %s" % dev)
from ptpython.repl import embed
logging.getLogger("parso").setLevel(logging.WARNING) # prompt parsing
logging.getLogger("asyncio").setLevel(logging.WARNING)
loop = asyncio.get_event_loop()
try:
await embed(
globals=globals(),
locals=locals(),
return_asyncio_coroutine=True,
patch_stdout=True,
)
except EOFError:
loop.stop()
if __name__ == "__main__": if __name__ == "__main__":
cli() cli()

View File

@ -558,3 +558,21 @@ async def test_type_param(device_type, mocker):
) )
assert res.exit_code == 0 assert res.exit_code == 0
assert isinstance(result_device, expected_type) assert isinstance(result_device, expected_type)
@pytest.mark.skip(
"Skip until pytest-asyncio supports pytest 8.0, https://github.com/pytest-dev/pytest-asyncio/issues/737"
)
async def test_shell(dev: Device, mocker):
"""Test that the shell commands tries to embed a shell."""
mocker.patch("kasa.Discover.discover", return_value=[dev])
# repl = mocker.patch("ptpython.repl")
mocker.patch.dict(
"sys.modules",
{"ptpython": mocker.MagicMock(), "ptpython.repl": mocker.MagicMock()},
)
embed = mocker.patch("ptpython.repl.embed")
runner = CliRunner()
res = await runner.invoke(cli, ["shell"], obj=dev)
assert res.exit_code == 0
embed.assert_called()

View File

@ -40,6 +40,9 @@ sphinxcontrib-programoutput = { version = "^0", optional = true }
myst-parser = { version = "*", optional = true } myst-parser = { version = "*", optional = true }
docutils = { version = ">=0.17", optional = true } docutils = { version = ">=0.17", optional = true }
# shell support
# ptpython = { version = "*", optional = true }
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
pytest = "*" pytest = "*"
pytest-cov = "*" pytest-cov = "*"
@ -57,6 +60,7 @@ coverage = {version = "*", extras = ["toml"]}
[tool.poetry.extras] [tool.poetry.extras]
docs = ["sphinx", "sphinx_rtd_theme", "sphinxcontrib-programoutput", "myst-parser", "docutils"] docs = ["sphinx", "sphinx_rtd_theme", "sphinxcontrib-programoutput", "myst-parser", "docutils"]
speedups = ["orjson", "kasa-crypt"] speedups = ["orjson", "kasa-crypt"]
# shell = ["ptpython"]
[tool.coverage.run] [tool.coverage.run]
source = ["kasa"] source = ["kasa"]