diff --git a/.flake8 b/.flake8 index ddd7b7f..9a423e5 100644 --- a/.flake8 +++ b/.flake8 @@ -1,6 +1,6 @@ [flake8] select = B,B9,C,D,DAR,E,F,N,RST,S,W -ignore = E203,E501,RST201,RST203,RST301,W503,D100,D101,D102,D104 +ignore = E203,E501,RST201,RST203,RST301,W503,D100,D101,D102,D103,D104 max-line-length = 80 max-complexity = 10 per-file-ignores = tests/*:S101 diff --git a/poetry.lock b/poetry.lock index a24c9e6..b90b11b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2302,7 +2302,13 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +[extras] +all = [] +bpython = [] +ipython = [] +ptpython = [] + [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "f3388ad69b555d9840b7b7689d89d729eb50b52f54bc21cf176ddba5ebe37606" +content-hash = "e423e4a8c77c583a5d4729f338f12922f5cc28f4bf8f34f0da516665ae80efc0" diff --git a/pyproject.toml b/pyproject.toml index 422a821..cb4a538 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,12 @@ click = ">=8.0.1" nox-poetry = "^1.0.3" nox = "^2023.4.22" +[tool.poetry.extras] +ipython = ["ipython"] +ptpython = ["ptpython"] +bpython = ["bpython"] +all = ["ipython", "ptpython", "bpython"] + [tool.poetry.scripts] flask-moreshell = "flask_moreshell.__main__:main" @@ -72,6 +78,7 @@ lines_after_imports = 2 [tool.mypy] strict = true +exclude = ["tests"] warn_unreachable = true pretty = true show_column_numbers = true diff --git a/src/flask_moreshell/__main__.py b/src/flask_moreshell/__main__.py index d12aa04..f474eaa 100644 --- a/src/flask_moreshell/__main__.py +++ b/src/flask_moreshell/__main__.py @@ -23,7 +23,7 @@ type=click.Choice(["ipython", "bpython", "ptpython", "python"]), default=None, ) -@with_appcontext +@with_appcontext # type: ignore def shell(shelltype: str) -> None: """Run `flask shell` command with IPython, BPython, PTPython. @@ -38,7 +38,8 @@ def shell(shelltype: str) -> None: def try_load_shell(_shelltype: str) -> None: shell_class = shells.get(_shelltype) - shell_class().load() + assert shell_class is not None # noqa S101 + shell_class().load() # type: ignore # If the user specifies a shell type, try to load it if shelltype: diff --git a/src/flask_moreshell/shells/ipython_shell.py b/src/flask_moreshell/shells/ipython_shell.py index 5cb487e..b2d72e5 100644 --- a/src/flask_moreshell/shells/ipython_shell.py +++ b/src/flask_moreshell/shells/ipython_shell.py @@ -22,9 +22,9 @@ def get_shell_version(self) -> str: def load(self) -> None: config = self._get_config() - config.TerminalInteractiveShell.banner1 = self.get_banner() + config.TerminalInteractiveShell.banner1 = self.get_banner() # type: ignore - IPython.start_ipython( + IPython.start_ipython( # type: ignore argv=[], user_ns=current_app.make_shell_context(), config=config, @@ -34,4 +34,4 @@ def load(self) -> None: def _get_config() -> Any | None: if "IPYTHON_CONFIG" in current_app.config: return Config(current_app.config["IPYTHON_CONFIG"]) - return load_default_config() + return load_default_config() # type: ignore diff --git a/tests/shells/test_bpython_shell.py b/tests/shells/test_bpython_shell.py new file mode 100644 index 0000000..7a6ba96 --- /dev/null +++ b/tests/shells/test_bpython_shell.py @@ -0,0 +1,18 @@ +from importlib.metadata import version + +import pytest + +from flask_moreshell.shells import BPythonShell + + +@pytest.fixture +def bpython_shell(): + return BPythonShell() + + +def test_get_shell_name(bpython_shell): + assert bpython_shell.get_shell_name() == "BPython" + + +def test_get_shell_version(bpython_shell): + assert bpython_shell.get_shell_version() == version("bpython") diff --git a/tests/shells/test_ipython_shell.py b/tests/shells/test_ipython_shell.py new file mode 100644 index 0000000..0e01c66 --- /dev/null +++ b/tests/shells/test_ipython_shell.py @@ -0,0 +1,18 @@ +import pytest + +from flask_moreshell.shells import IpythonShell + + +@pytest.fixture +def ipython_shell(): + return IpythonShell() + + +def test_get_shell_name(ipython_shell): + assert ipython_shell.get_shell_name() == "IPython" + + +def test_get_shell_version(ipython_shell): + from IPython import __version__ + + assert ipython_shell.get_shell_version() == __version__ diff --git a/tests/shells/test_ptpython_shell.py b/tests/shells/test_ptpython_shell.py new file mode 100644 index 0000000..e41e565 --- /dev/null +++ b/tests/shells/test_ptpython_shell.py @@ -0,0 +1,37 @@ +from importlib.metadata import version + +import pytest +from flask import Flask + +from flask_moreshell.shells import PTPythonShell + + +@pytest.fixture +def app(): + app = Flask(__name__) + app.config["TESTING"] = True + return app + + +@pytest.fixture +def ptpython_shell(): + return PTPythonShell() + + +def test_get_shell_name(ptpython_shell): + assert ptpython_shell.get_shell_name() == "PTPython" + + +def test_get_shell_version(ptpython_shell): + assert ptpython_shell.get_shell_version() == version("ptpython") + + +def test_load(ptpython_shell, monkeypatch, capsys, app): + with app.app_context(): + ptpython_shell.load() + + stdout = capsys.readouterr().out + + assert ptpython_shell.get_shell_name() in stdout + assert ptpython_shell.get_shell_version() in stdout + assert "PTPython" in stdout diff --git a/tests/test_main.py b/tests/test_main.py index 1a50361..f7e05a9 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,17 +1,46 @@ -"""Test cases for the __main__ module.""" import pytest from click.testing import CliRunner +from flask import Flask from flask_moreshell import shell @pytest.fixture -def runner() -> CliRunner: - """Fixture for invoking command-line interfaces.""" +def app(): + app = Flask(__name__) + app.config["TESTING"] = True + return app + + +@pytest.fixture +def runner(app): return CliRunner() -def test_main_succeeds(runner: CliRunner) -> None: - """It exits with a status code of zero.""" - result = runner.invoke(shell) +def test_ipython_shell(runner, app): + with app.app_context(): + result = runner.invoke(shell, ["--shelltype", "ipython"]) + assert result.exit_code == 0 + assert "IPython" in result.output + + +# def test_bpython_shell(runner, app): +# with app.app_context(): +# result = runner.invoke(shell, ["--shelltype", "bpython"]) +# assert result.output == "" +# assert result.exit_code == 0 +# assert "BPython" in result.output + + +def test_pypython_shell(runner, app): + with app.app_context(): + result = runner.invoke(shell, ["--shelltype", "ptpython"]) + assert result.exit_code == 0 + assert "PTPython" in result.output + + +def test_python_shell(runner, app): + with app.app_context(): + result = runner.invoke(shell, ["--shelltype", "python"]) assert result.exit_code == 0 + assert "Python" in result.output