Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-pytest-jupyter for
openSUSE:Factory checked in at 2023-12-25 19:04:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytest-jupyter (Old)
and /work/SRC/openSUSE:Factory/.python-pytest-jupyter.new.28375 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest-jupyter"
Mon Dec 25 19:04:25 2023 rev:4 rq:1134997 version:0.8.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-pytest-jupyter/python-pytest-jupyter.changes
2023-05-01 18:51:10.629353768 +0200
+++
/work/SRC/openSUSE:Factory/.python-pytest-jupyter.new.28375/python-pytest-jupyter.changes
2023-12-25 19:04:29.727721095 +0100
@@ -1,0 +2,8 @@
+Sun Dec 24 14:14:51 UTC 2023 - Ben Greiner <[email protected]>
+
+- Update to 0.8.0
+ * Allow passing request_timeout to client_fetch #67 (@afbarbaro)
+ * code maintenance
+- Disable the -server subpackage for Ring1
+
+-------------------------------------------------------------------
Old:
----
pytest_jupyter-0.7.0.tar.gz
New:
----
pytest_jupyter-0.8.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pytest-jupyter.spec ++++++
--- /var/tmp/diff_new_pack.tnk7BE/_old 2023-12-25 19:04:30.379744874 +0100
+++ /var/tmp/diff_new_pack.tnk7BE/_new 2023-12-25 19:04:30.379744874 +0100
@@ -25,14 +25,18 @@
%bcond_with test
%endif
+# defined at Ring1-MinimalX lettered staging prjconf
+# We do not want jupyter-server in ring1
+%bcond_with ringdisabled
+
Name: python-pytest-jupyter%{psuffix}
-Version: 0.7.0
+Version: 0.8.0
Release: 0
Summary: A pytest plugin for testing Jupyter libraries and extensions
License: BSD-3-Clause AND MIT
URL: https://github.com/jupyter-server/pytest-jupyter
Source:
https://files.pythonhosted.org/packages/source/p/pytest_jupyter/pytest_jupyter-%{version}.tar.gz
-BuildRequires: %{python_module base >= 3.7}
+BuildRequires: %{python_module base >= 3.8}
BuildRequires: %{python_module hatchling}
BuildRequires: %{python_module pip}
BuildRequires: fdupes
@@ -41,10 +45,11 @@
Requires: python-pytest
BuildArch: noarch
%if %{with test}
-BuildRequires: %{python_module nbformat}
BuildRequires: %{python_module pytest-jupyter = %{version}}
BuildRequires: %{python_module pytest-jupyter-client = %{version}}
+%if !%{with ringdisabled}
BuildRequires: %{python_module pytest-jupyter-server = %{version}}
+%endif
BuildRequires: %{python_module pytest-timeout}
%endif
%python_subpackages
@@ -54,8 +59,9 @@
%package client
Summary: A pytest plugin for testing Jupyter libraries and extensions
[client] extra
-Requires: python-ipykernel
-Requires: python-jupyter_client >= 7.4
+Requires: python-ipykernel >= 6.14
+Requires: python-jupyter-client >= 7.4
+Requires: python-nbformat >= 5.3
Requires: python-pytest-jupyter = %{version}
%description client
@@ -64,10 +70,11 @@
%package server
Summary: A pytest plugin for testing Jupyter libraries and extensions
[server] extra
+Requires: python-ipykernel >= 6.14
+Requires: python-jupyter-client >= 7.4
Requires: python-jupyter-server >= 1.21
Requires: python-nbformat >= 5.3
Requires: python-pytest-jupyter = %{version}
-Requires: python-pytest-jupyter-client = %{version}
%description server
A pytest plugin for testing Jupyter libraries and extensions.
@@ -75,7 +82,10 @@
%prep
%setup -q -n pytest_jupyter-%{version}
-sed -i 's/--color=yes//' pyproject.toml
+sed -e 's/ "--color=yes",//' -i pyproject.toml
+%if %{with ringdisabled}
+sed -e "/jupyter_server/d" -i tests/conftest.py
+%endif
%if !%{with test}
%build
@@ -88,7 +98,8 @@
%if %{with test}
%check
-%pytest
+mv pytest_jupyter pytest_jupyter.moved
+%pytest %{?_with_ringdisabled:--ignore tests/test_jupyter_server.py}
%endif
%if !%{with test}
@@ -101,7 +112,9 @@
%files %{python_files client}
%license LICENSE
+%if !%{with ringdisabled}
%files %{python_files server}
%license LICENSE
%endif
+%endif
++++++ pytest_jupyter-0.7.0.tar.gz -> pytest_jupyter-0.8.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_jupyter-0.7.0/PKG-INFO
new/pytest_jupyter-0.8.0/PKG-INFO
--- old/pytest_jupyter-0.7.0/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
+++ new/pytest_jupyter-0.8.0/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pytest-jupyter
-Version: 0.7.0
+Version: 0.8.0
Summary: A pytest plugin for testing Jupyter libraries and extensions.
Project-URL: Homepage, http://jupyter.org
Project-URL: Funding, https://numfocus.org/donate
@@ -101,21 +101,23 @@
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
-Requires-Python: >=3.7
+Requires-Python: >=3.8
Requires-Dist: jupyter-core
Requires-Dist: pytest
Provides-Extra: client
Requires-Dist: ipykernel>=6.14; extra == 'client'
Requires-Dist: jupyter-client>=7.4.0; extra == 'client'
+Requires-Dist: nbformat>=5.3; extra == 'client'
Provides-Extra: docs
Requires-Dist: myst-parser; extra == 'docs'
Requires-Dist: pydata-sphinx-theme; extra == 'docs'
Requires-Dist: sphinx; extra == 'docs'
Requires-Dist: sphinxcontrib-spelling; extra == 'docs'
Provides-Extra: server
+Requires-Dist: ipykernel>=6.14; extra == 'server'
+Requires-Dist: jupyter-client>=7.4.0; extra == 'server'
Requires-Dist: jupyter-server>=1.21; extra == 'server'
Requires-Dist: nbformat>=5.3; extra == 'server'
-Requires-Dist: pytest-jupyter[client]; extra == 'server'
Provides-Extra: test
Requires-Dist: pytest-timeout; extra == 'test'
Description-Content-Type: text/markdown
@@ -125,7 +127,6 @@
A set of pytest plugins for Jupyter libraries and extensions.
[](https://github.com/jupyter-server/pytest-jupyter/actions/workflows/test.yml/badge.svg?query=branch%3Amain++)
-[](https://codecov.io/gh/jupyter-server/pytest-jupyter)
## Basic Usage
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_jupyter-0.7.0/README.md
new/pytest_jupyter-0.8.0/README.md
--- old/pytest_jupyter-0.7.0/README.md 2020-02-02 01:00:00.000000000 +0100
+++ new/pytest_jupyter-0.8.0/README.md 2020-02-02 01:00:00.000000000 +0100
@@ -3,7 +3,6 @@
A set of pytest plugins for Jupyter libraries and extensions.
[](https://github.com/jupyter-server/pytest-jupyter/actions/workflows/test.yml/badge.svg?query=branch%3Amain++)
-[](https://codecov.io/gh/jupyter-server/pytest-jupyter)
## Basic Usage
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_jupyter-0.7.0/pyproject.toml
new/pytest_jupyter-0.8.0/pyproject.toml
--- old/pytest_jupyter-0.7.0/pyproject.toml 2020-02-02 01:00:00.000000000
+0100
+++ new/pytest_jupyter-0.8.0/pyproject.toml 2020-02-02 01:00:00.000000000
+0100
@@ -30,7 +30,7 @@
"pytest",
"jupyter_core"
]
-requires-python = ">=3.7"
+requires-python = ">=3.8"
[project.optional-dependencies]
@@ -42,12 +42,14 @@
]
client = [
"jupyter_client>=7.4.0",
+ "nbformat>=5.3",
"ipykernel>=6.14"
]
server = [
"jupyter_server>=1.21",
+ "jupyter_client>=7.4.0",
"nbformat>=5.3",
- "pytest-jupyter[client]",
+ "ipykernel>=6.14"
]
test = [
"pytest-timeout"
@@ -88,35 +90,31 @@
nowarn = "test -W default {args}"
[tool.hatch.envs.typing]
-features = ["test", "server", "client"]
-dependencies = ["mypy>=0.990"]
+dependencies = ["pre-commit"]
+detached = true
[tool.hatch.envs.typing.scripts]
-test = "mypy --install-types --non-interactive {args:.}"
+test = "pre-commit run --all-files --hook-stage manual mypy"
[tool.hatch.envs.lint]
-dependencies = [
- "black[jupyter]==23.1.0",
- "mdformat>0.7",
- "ruff==0.0.254",
-]
+dependencies = ["pre-commit"]
detached = true
[tool.hatch.envs.lint.scripts]
-style = [
- "ruff {args:.}",
- "black --check --diff {args:.}",
- "mdformat --check {args:docs *.md}"
-]
-fmt = [
- "black {args:.}",
- "ruff --fix {args:.}",
- "mdformat {args:docs *.md}"
+build = [
+ "pre-commit run --all-files ruff",
+ "pre-commit run --all-files ruff-format"
]
[tool.jupyter-releaser.options]
post-version-spec = "dev"
[tool.pytest.ini_options]
-addopts = "-raXs --durations 10 --color=yes --doctest-modules"
+minversion = "6.0"
+xfail_strict = true
+log_cli_level = "info"
+addopts = [
+ "-raXs", "--durations=10", "--color=yes", "--doctest-modules",
+ "--showlocals", "--strict-markers", "--strict-config"
+]
testpaths = [
"tests"
]
@@ -126,6 +124,7 @@
filterwarnings= [
# Fail on warnings
"error",
+ "module:datetime.datetime.utc:DeprecationWarning",
]
[tool.coverage.report]
@@ -142,45 +141,52 @@
"@(abc\\.)?abstractmethod",
]
-[tool.mypy]
-check_untyped_defs = true
-disallow_incomplete_defs = true
-no_implicit_optional = true
-pretty = true
-show_error_context = true
-show_error_codes = true
-strict_equality = true
-warn_unused_configs = true
-warn_unused_ignores = true
-warn_redundant_casts = true
-explicit_package_bases = true
-namespace_packages = true
+[tool.coverage.run]
+relative_files = true
+source = ["pytest_jupyter"]
-[tool.black]
-line-length = 100
-skip-string-normalization = true
-target-version = ["py38"]
+[tool.mypy]
+files = "pytest_jupyter"
+python_version = "3.8"
+strict = true
+enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
+disable_error_code = ["no-untyped-def"]
+warn_unreachable = true
[tool.ruff]
-target-version = "py38"
line-length = 100
-select = [
- "A", "B", "C", "DTZ", "E", "EM", "F", "FBT", "I", "ICN", "ISC", "N",
- "PLC", "PLE", "PLR", "PLW", "Q", "RUF", "S", "SIM", "T", "TID", "UP",
- "W", "YTT",
+
+[tool.ruff.lint]
+extend-select = [
+ "B", # flake8-bugbear
+ "I", # isort
+ "ARG", # flake8-unused-arguments
+ "C4", # flake8-comprehensions
+ "EM", # flake8-errmsg
+ "ICN", # flake8-import-conventions
+ "G", # flake8-logging-format
+ "PGH", # pygrep-hooks
+ "PIE", # flake8-pie
+ "PL", # pylint
+ "PT", # flake8-pytest-style
+ "PTH", # flake8-use-pathlib
+ "RET", # flake8-return
+ "RUF", # Ruff-specific
+ "SIM", # flake8-simplify
+ "T20", # flake8-print
+ "UP", # pyupgrade
+ "YTT", # flake8-2020
+ "EXE", # flake8-executable
+ "NPY", # NumPy specific rules
+ "PD", # pandas-vet
+ "PYI", # flake8-pyi
]
ignore = [
-# Q000 Single quotes found but double quotes preferred
-"Q000",
-# FBT001 Boolean positional arg in function definition
-"FBT001", "FBT002", "FBT003",
-# E501 Line too long (158 > 100 characters)
-"E501",
-# SIM105 Use `contextlib.suppress(...)`
-"SIM105",
-#PLR0913 Too many arguments to function call
-"PLR0913",
-]
+ "PLR", # Design related pylint codes
+ "SIM105", # Use `contextlib.suppress(...)`
+ "RUF012", # Mutable class attributes should be annotated with
+ "ARG001", # Unused function argument:
+ ]
unfixable = [
# Don't touch print statements
"T201",
@@ -188,16 +194,11 @@
"RUF100",
]
-[tool.ruff.per-file-ignores]
+[tool.ruff.lint.per-file-ignores]
# B011 Do not call assert False since python -O removes these calls
-# F841 local variable 'foo' is assigned to but never used
-# C408 Unnecessary `dict` call
-# E402 Module level import not at top of file
# T201 `print` found
# B007 Loop control variable `i` not used within the loop body.
-# N802 Function name `assertIn` should be lowercase
-# S101 Use of `assert` detected
-"tests/*" = ["B011", "F841", "C408", "E402", "T201", "B007", "N802", "S101"]
+"tests/*" = ["B011", "C4", "T201", "B007", "PTH", "ARG"]
[tool.interrogate]
ignore-init-module=true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_jupyter-0.7.0/pytest_jupyter/__init__.py
new/pytest_jupyter-0.8.0/pytest_jupyter/__init__.py
--- old/pytest_jupyter-0.7.0/pytest_jupyter/__init__.py 2020-02-02
01:00:00.000000000 +0100
+++ new/pytest_jupyter-0.8.0/pytest_jupyter/__init__.py 2020-02-02
01:00:00.000000000 +0100
@@ -4,4 +4,4 @@
__all__ = ["__version__"]
from ._version import __version__
-from .jupyter_core import * # noqa
+from .jupyter_core import * # noqa: F403
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_jupyter-0.7.0/pytest_jupyter/_version.py
new/pytest_jupyter-0.8.0/pytest_jupyter/_version.py
--- old/pytest_jupyter-0.7.0/pytest_jupyter/_version.py 2020-02-02
01:00:00.000000000 +0100
+++ new/pytest_jupyter-0.8.0/pytest_jupyter/_version.py 2020-02-02
01:00:00.000000000 +0100
@@ -2,4 +2,4 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
-__version__ = "0.7.0"
+__version__ = "0.8.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_jupyter-0.7.0/pytest_jupyter/echo_kernel.py
new/pytest_jupyter-0.8.0/pytest_jupyter/echo_kernel.py
--- old/pytest_jupyter-0.7.0/pytest_jupyter/echo_kernel.py 2020-02-02
01:00:00.000000000 +0100
+++ new/pytest_jupyter-0.8.0/pytest_jupyter/echo_kernel.py 2020-02-02
01:00:00.000000000 +0100
@@ -1,9 +1,12 @@
"""A simple echo kernel."""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
+from __future__ import annotations
import logging
+import typing
+# mypy: disable-error-code="no-untyped-call"
from ipykernel.kernelapp import IPKernelApp
from ipykernel.kernelbase import Kernel
@@ -22,9 +25,16 @@
}
banner = "Echo kernel - as useful as a parrot"
- def do_execute(
- self, code, silent, store_history=True, user_expressions=None,
allow_stdin=False
- ):
+ def do_execute( # type:ignore[override]
+ self,
+ code: str,
+ silent: bool,
+ store_history=True, # noqa: ARG002
+ user_expressions: typing.Any = None, # noqa: ARG002
+ allow_stdin=False,
+ *,
+ cell_id: str | None = None, # noqa: ARG002
+ ) -> dict[str, typing.Any]:
"""Execute code on the kernel."""
if not silent:
stream_content = {"name": "stdout", "text": code}
@@ -51,7 +61,7 @@
class EchoKernelApp(IPKernelApp):
"""An app for the echo kernel."""
- kernel_class = EchoKernel
+ kernel_class = EchoKernel # type:ignore[assignment]
if __name__ == "__main__":
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_jupyter-0.7.0/pytest_jupyter/jupyter_client.py
new/pytest_jupyter-0.8.0/pytest_jupyter/jupyter_client.py
--- old/pytest_jupyter-0.7.0/pytest_jupyter/jupyter_client.py 2020-02-02
01:00:00.000000000 +0100
+++ new/pytest_jupyter-0.8.0/pytest_jupyter/jupyter_client.py 2020-02-02
01:00:00.000000000 +0100
@@ -5,7 +5,7 @@
import pytest
try:
- import ipykernel # noqa
+ import ipykernel # noqa: F401
from jupyter_client.kernelspec import NATIVE_KERNEL_NAME
from jupyter_client.manager import start_new_async_kernel
except ImportError:
@@ -15,15 +15,16 @@
"The client plugin has not been installed. "
"If you're trying to use this plugin and you've installed "
"`pytest-jupyter`, there is likely one more step "
- "you need. Try: `pip install 'pytest-jupyter[client]'`"
+ "you need. Try: `pip install 'pytest-jupyter[client]'`",
+ stacklevel=2,
)
# Bring in local plugins.
-from pytest_jupyter.jupyter_core import * # noqa
-from pytest_jupyter.pytest_tornasync import * # noqa
+from pytest_jupyter.jupyter_core import * # noqa: F403
+from pytest_jupyter.pytest_tornasync import * # noqa: F403
[email protected]
[email protected]()
def jp_zmq_context():
"""Get a zmq context."""
import zmq
@@ -33,7 +34,7 @@
ctx.term()
[email protected]
[email protected]()
def jp_start_kernel(jp_environ, jp_asyncio_loop):
"""Get a function to a kernel and clean up resources when done."""
kms = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_jupyter-0.7.0/pytest_jupyter/jupyter_core.py
new/pytest_jupyter-0.8.0/pytest_jupyter/jupyter_core.py
--- old/pytest_jupyter-0.7.0/pytest_jupyter/jupyter_core.py 2020-02-02
01:00:00.000000000 +0100
+++ new/pytest_jupyter-0.8.0/pytest_jupyter/jupyter_core.py 2020-02-02
01:00:00.000000000 +0100
@@ -5,6 +5,7 @@
import json
import os
import sys
+import typing
from pathlib import Path
import jupyter_core
@@ -16,7 +17,7 @@
import resource
except ImportError:
# Windows
- resource = None # type: ignore
+ resource = None # type:ignore[assignment]
# Handle resource limit
@@ -34,7 +35,7 @@
resource.setrlimit(resource.RLIMIT_NOFILE, (soft, hard))
[email protected]
[email protected]()
def jp_asyncio_loop():
"""Get an asyncio loop."""
if os.name == "nt":
@@ -52,7 +53,7 @@
"""Override the io_loop for pytest_tornasync. This is a no-op
if tornado is not installed."""
- async def get_tornado_loop():
+ async def get_tornado_loop() -> typing.Any:
"""Asynchronously get a tornado loop."""
try:
from tornado.ioloop import IOLoop
@@ -64,49 +65,49 @@
return jp_asyncio_loop.run_until_complete(get_tornado_loop())
[email protected]
[email protected]()
def jp_home_dir(tmp_path):
"""Provides a temporary HOME directory value."""
return mkdir(tmp_path, "home")
[email protected]
[email protected]()
def jp_data_dir(tmp_path):
"""Provides a temporary Jupyter data dir directory value."""
return mkdir(tmp_path, "data")
[email protected]
[email protected]()
def jp_config_dir(tmp_path):
"""Provides a temporary Jupyter config dir directory value."""
return mkdir(tmp_path, "config")
[email protected]
[email protected]()
def jp_runtime_dir(tmp_path):
"""Provides a temporary Jupyter runtime dir directory value."""
return mkdir(tmp_path, "runtime")
[email protected]
[email protected]()
def jp_system_jupyter_path(tmp_path):
"""Provides a temporary Jupyter system path value."""
return mkdir(tmp_path, "share", "jupyter")
[email protected]
[email protected]()
def jp_env_jupyter_path(tmp_path):
"""Provides a temporary Jupyter env system path value."""
return mkdir(tmp_path, "env", "share", "jupyter")
[email protected]
[email protected]()
def jp_system_config_path(tmp_path):
"""Provides a temporary Jupyter config path value."""
return mkdir(tmp_path, "etc", "jupyter")
[email protected]
[email protected]()
def jp_env_config_path(tmp_path):
"""Provides a temporary Jupyter env config path value."""
return mkdir(tmp_path, "env", "etc", "jupyter")
@@ -118,7 +119,7 @@
return mkdir(jp_data_dir, "kernels")
[email protected]
[email protected]()
def echo_kernel_spec(jp_kernel_dir):
"""Install a kernel spec for the echo kernel."""
test_dir = Path(jp_kernel_dir) / "echo"
@@ -130,8 +131,8 @@
return str(test_dir)
[email protected]
-def jp_environ(
[email protected]()
+def jp_environ( # noqa: PT004
monkeypatch,
tmp_path,
jp_home_dir,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_jupyter-0.7.0/pytest_jupyter/jupyter_server.py
new/pytest_jupyter-0.8.0/pytest_jupyter/jupyter_server.py
--- old/pytest_jupyter-0.7.0/pytest_jupyter/jupyter_server.py 2020-02-02
01:00:00.000000000 +0100
+++ new/pytest_jupyter-0.8.0/pytest_jupyter/jupyter_server.py 2020-02-02
01:00:00.000000000 +0100
@@ -1,6 +1,7 @@
"""Fixtures for use with jupyter server and downstream."""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
+from __future__ import annotations
import asyncio
import importlib
@@ -11,6 +12,7 @@
import shutil
import urllib.parse
from binascii import hexlify
+from pathlib import Path
import jupyter_core.paths
import pytest
@@ -31,31 +33,32 @@
from tornado.websocket import WebSocketHandler
from traitlets.config import Config
- is_v2 = version_info[0] == 2 # noqa
+ is_v2 = version_info[0] == 2
except ImportError:
- Authorizer = object # type:ignore
+ Authorizer = object # type:ignore[assignment, misc]
import warnings
warnings.warn(
"The server plugin has not been installed. "
"If you're trying to use this plugin and you've installed "
"`pytest-jupyter`, there is likely one more step "
- "you need. Try: `pip install 'pytest-jupyter[server]'`"
+ "you need. Try: `pip install 'pytest-jupyter[server]'`",
+ stacklevel=2,
)
# Bring in local plugins.
-from pytest_jupyter.jupyter_core import * # noqa
-from pytest_jupyter.pytest_tornasync import * # noqa
+from pytest_jupyter.jupyter_core import * # noqa: F403
+from pytest_jupyter.pytest_tornasync import * # noqa: F403
from pytest_jupyter.utils import mkdir
# Override some of the fixtures from pytest_tornasync
-# The io_loop fixture is overidden in jupyter_core.py so it
+# The io_loop fixture is overridden in jupyter_core.py so it
# can be shared by other plugins that need it (e.g. jupyter_client.py).
[email protected]
[email protected]()
def http_server(io_loop, http_server_port, jp_web_app):
"""Start a tornado HTTP server that listens on all available interfaces."""
@@ -81,7 +84,7 @@
# End pytest_tornasync overrides
[email protected]
[email protected]()
def jp_server_config():
"""Allows tests to setup their specific configuration values."""
if is_v2:
@@ -95,19 +98,19 @@
return Config(config)
[email protected]
[email protected]()
def jp_root_dir(tmp_path):
"""Provides a temporary Jupyter root directory value."""
return mkdir(tmp_path, "root_dir")
[email protected]
[email protected]()
def jp_template_dir(tmp_path):
"""Provides a temporary Jupyter templates directory value."""
return mkdir(tmp_path, "templates")
[email protected]
[email protected]()
def jp_argv():
"""Allows tests to setup specific argv values."""
return []
@@ -120,14 +123,14 @@
http_server_port[0].close()
[email protected]
-def jp_extension_environ(jp_env_config_path, monkeypatch):
[email protected]()
+def jp_extension_environ(jp_env_config_path, monkeypatch): # noqa: PT004
"""Monkeypatch a Jupyter Extension's config path into each test's
environment variable"""
monkeypatch.setattr(serverextension, "ENV_CONFIG_PATH",
[str(jp_env_config_path)])
[email protected]
-def jp_nbconvert_templates(jp_data_dir):
[email protected]()
+def jp_nbconvert_templates(jp_data_dir): # noqa: PT004
"""Setups up a temporary directory consisting of the nbconvert
templates."""
# Get path to nbconvert template directory *before*
@@ -135,7 +138,7 @@
possible_paths = jupyter_core.paths.jupyter_path("nbconvert", "templates")
nbconvert_path = None
for path in possible_paths:
- if os.path.exists(path):
+ if Path(path).exists():
nbconvert_path = path
break
@@ -146,7 +149,7 @@
shutil.copytree(nbconvert_path, str(nbconvert_target))
[email protected]
[email protected]()
def jp_logging_stream():
"""StringIO stream intended to be used by the core
Jupyter ServerApp logger's default StreamHandler. This
@@ -158,13 +161,13 @@
output = logging_stream.getvalue()
# If output exists, print it.
if output:
- print(output)
+ print(output) # noqa: T201
return output
[email protected](scope="function")
[email protected]()
def jp_configurable_serverapp(
- jp_nbconvert_templates, # this fixture must preceed jp_environ
+ jp_nbconvert_templates, # this fixture must precede jp_environ
jp_environ,
jp_server_config,
jp_argv,
@@ -185,8 +188,8 @@
.. code-block:: python
def my_test(jp_configurable_serverapp):
- app = jp_configurable_serverapp(...)
- ...
+ app = jp_configurable_serverapp(...)
+ ...
"""
ServerApp.clear_instance()
@@ -234,7 +237,7 @@
allow_root=True,
**kwargs,
)
- app.init_signal = lambda: None
+ app.init_signal = lambda: None # type:ignore[method-assign]
app.log.propagate = True
app.log.handlers = []
# Initialize app without httpserver
@@ -245,7 +248,7 @@
async def initialize_app():
app.initialize(argv=argv, new_httpserver=False)
- jp_asyncio_loop.run_until_complete(initialize_app())
+ jp_asyncio_loop.run_until_complete(initialize_app()) #
type:ignore[no-untyped-call]
# Reroute all logging StreamHandlers away from stdin/stdout since
pytest hijacks
# these streams and closes them at unfortunate times.
stream_handlers = [h for h in app.log.handlers if isinstance(h,
logging.StreamHandler)]
@@ -259,19 +262,19 @@
return _configurable_serverapp
[email protected](scope="function")
[email protected]()
def jp_serverapp(jp_server_config, jp_argv, jp_configurable_serverapp):
"""Starts a Jupyter Server instance based on the established configuration
values."""
return jp_configurable_serverapp(config=jp_server_config, argv=jp_argv)
[email protected]
[email protected]()
def jp_web_app(jp_serverapp):
"""app fixture is needed by pytest_tornasync plugin"""
return jp_serverapp.web_app
[email protected]
[email protected]()
def jp_auth_header(jp_serverapp):
"""Configures an authorization header using the token from the serverapp
fixture."""
if not is_v2:
@@ -279,13 +282,13 @@
return {"Authorization": f"token {jp_serverapp.identity_provider.token}"}
[email protected]
[email protected]()
def jp_base_url():
"""Returns the base url to use for the test."""
return "/a%40b/"
[email protected]
[email protected]()
def jp_fetch(jp_serverapp, http_server_client, jp_auth_header, jp_base_url):
"""Sends an (asynchronous) HTTP request to a test server.
The fixture is a factory; it can be called like
@@ -312,13 +315,17 @@
# Add auth keys to header, if not overridden
for key, value in jp_auth_header.items():
headers.setdefault(key, value)
+ # Handle timeout
+ request_timeout = kwargs.pop("request_timeout", 20)
# Make request.
- return http_server_client.fetch(url, headers=headers,
request_timeout=20, **kwargs)
+ return http_server_client.fetch(
+ url, headers=headers, request_timeout=request_timeout, **kwargs
+ )
return client_fetch
[email protected]
[email protected]()
def jp_ws_fetch(jp_serverapp, http_server_client, jp_auth_header,
jp_http_port, jp_base_url):
"""Sends a websocket request to a test server.
The fixture is a factory; it can be called like
@@ -330,21 +337,15 @@
async def my_test(jp_fetch, jp_ws_fetch):
# Start a kernel
r = await jp_fetch(
- 'api', 'kernels',
- method='POST',
- body=json.dumps({
- 'name': "python3"
- })
+ "api", "kernels", method="POST", body=json.dumps({"name":
"python3"})
)
- kid = json.loads(r.body.decode())['id']
+ kid = json.loads(r.body.decode())["id"]
# Open a websocket connection.
- ws = await jp_ws_fetch(
- 'api', 'kernels', kid, 'channels'
- )
+ ws = await jp_ws_fetch("api", "kernels", kid, "channels")
...
"""
- def client_fetch(*parts, headers=None, params=None, **kwargs):
+ def client_fetch(*parts, headers=None, params=None, **kwargs): # noqa: ARG
if not headers:
headers = {}
if not params:
@@ -365,7 +366,7 @@
return client_fetch
[email protected]
[email protected]()
def jp_create_notebook(jp_root_dir):
"""Creates a notebook in the test's home directory."""
@@ -379,8 +380,8 @@
parent = nbpath.parent
parent.mkdir(parents=True, exist_ok=True)
# Create a notebook string and write to file.
- nb = nbformat.v4.new_notebook()
- nbtext = nbformat.writes(nb, version=4)
+ nb = nbformat.v4.new_notebook() # type:ignore[no-untyped-call]
+ nbtext = nbformat.writes(nb, version=4) # type:ignore[no-untyped-call]
nbpath.write_text(nbtext)
return nb
@@ -388,20 +389,20 @@
@pytest.fixture(autouse=True)
-def jp_server_cleanup(jp_asyncio_loop):
+def jp_server_cleanup(jp_asyncio_loop): # noqa: PT004
"""Automatically cleans up server resources."""
yield
app: ServerApp = ServerApp.instance()
try:
jp_asyncio_loop.run_until_complete(app._cleanup())
except (RuntimeError, SystemExit) as e:
- print("ignoring cleanup error", e)
+ print("ignoring cleanup error", e) # noqa: T201
if hasattr(app, "kernel_manager"):
app.kernel_manager.context.destroy()
ServerApp.clear_instance()
[email protected]
[email protected]()
def send_request(jp_fetch, jp_ws_fetch):
"""Send to Jupyter Server and return response code."""
@@ -422,7 +423,7 @@
return _
[email protected]
[email protected]()
def jp_server_auth_core_resources():
"""The core auth resources for use with a server."""
modules = []
@@ -439,7 +440,7 @@
return resource_map
[email protected]
[email protected]()
def jp_server_auth_resources(jp_server_auth_core_resources):
"""The auth resources used by the server."""
return jp_server_auth_core_resources
@@ -451,8 +452,8 @@
# Set these class attributes from within a test
# to verify that they match the arguments passed
# by the REST API.
- permissions: dict = {}
- _default_regex_mapping: dict = {}
+ permissions: dict[str, str] = {}
+ _default_regex_mapping: dict[str, str] = {}
HTTP_METHOD_TO_AUTH_ACTION = {
"GET": "read",
@@ -465,7 +466,9 @@
"WEBSOCKET": "execute",
}
- def match_url_to_resource(self, url, regex_mapping=None):
+ def match_url_to_resource(
+ self, url: str, regex_mapping: dict[str, str] | None = None
+ ) -> str | None:
"""Finds the JupyterHandler regex pattern that would
match the given URL and returns the resource name (str)
of that handler.
@@ -477,9 +480,13 @@
pattern = re.compile(regex)
if pattern.fullmatch(url):
return auth_resource
+ return None
- def normalize_url(self, path):
+ def normalize_url(self, path: str) -> str:
"""Drop the base URL and make sure path leads with a /"""
+ if not self.parent:
+ msg = "Cannot normalize the url without a parent object"
+ raise ValueError(msg)
base_url = self.parent.base_url
# Remove base_url
if path.startswith(base_url):
@@ -489,7 +496,7 @@
path = "/" + path
return path
- def is_authorized(self, handler, user, action, resource):
+ def is_authorized(self, handler, user, action, resource): # noqa: ARG002
"""Test if a request is authorized."""
# Parse Request
method = "WEBSOCKET" if isinstance(handler, WebSocketHandler) else
handler.request.method
@@ -513,7 +520,7 @@
)
[email protected]
[email protected]()
def jp_server_authorizer(jp_server_auth_resources):
"""An authorizer for the server."""
auth_klass = _Authorizer
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pytest_jupyter-0.7.0/pytest_jupyter/pytest_tornasync.py
new/pytest_jupyter-0.8.0/pytest_jupyter/pytest_tornasync.py
--- old/pytest_jupyter-0.7.0/pytest_jupyter/pytest_tornasync.py 2020-02-02
01:00:00.000000000 +0100
+++ new/pytest_jupyter-0.8.0/pytest_jupyter/pytest_tornasync.py 2020-02-02
01:00:00.000000000 +0100
@@ -9,16 +9,19 @@
import tornado.testing
from tornado.simple_httpclient import SimpleAsyncHTTPClient
except ImportError:
- SimpleAsyncHTTPClient = object # type:ignore
+ SimpleAsyncHTTPClient = object # type:ignore[assignment,misc]
import pytest
+# mypy: disable-error-code="no-untyped-call"
+
@pytest.hookimpl(tryfirst=True)
def pytest_pycollect_makeitem(collector, name, obj):
"""Custom pytest collection hook."""
if collector.funcnamefilter(name) and iscoroutinefunction(obj):
return list(collector._genfunctions(name, obj))
+ return None
@pytest.hookimpl(tryfirst=True)
@@ -40,7 +43,7 @@
return True
[email protected]
[email protected]()
def http_server_port():
"""
Port used by `http_server`.
@@ -48,7 +51,7 @@
return tornado.testing.bind_unused_port()
[email protected]
[email protected]()
def http_server_client(http_server, io_loop):
"""
Create an asynchronous HTTP client that can fetch from `http_server`.
@@ -86,6 +89,7 @@
"""Get a port for the client."""
for sock in self._http_server._sockets.values():
return sock.getsockname()[1]
+ return None
def get_url(self, path):
"""Get the url for the client."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_jupyter-0.7.0/pytest_jupyter/utils.py
new/pytest_jupyter-0.8.0/pytest_jupyter/utils.py
--- old/pytest_jupyter-0.7.0/pytest_jupyter/utils.py 2020-02-02
01:00:00.000000000 +0100
+++ new/pytest_jupyter-0.8.0/pytest_jupyter/utils.py 2020-02-02
01:00:00.000000000 +0100
@@ -1,11 +1,12 @@
"""Utilities for pytest-jupyter."""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
+from pathlib import Path
-def mkdir(tmp_path, *parts):
+def mkdir(tmp_path: Path, *parts: str) -> Path:
"""Make a directory given extra path parts."""
- path = tmp_path.joinpath(*parts)
- if not path.exists():
- path.mkdir(parents=True)
- return path
+ new_path = tmp_path.joinpath(*parts)
+ if not new_path.exists():
+ new_path.mkdir(parents=True)
+ return new_path
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_jupyter-0.7.0/tests/test_jupyter_client.py
new/pytest_jupyter-0.8.0/tests/test_jupyter_client.py
--- old/pytest_jupyter-0.7.0/tests/test_jupyter_client.py 2020-02-02
01:00:00.000000000 +0100
+++ new/pytest_jupyter-0.8.0/tests/test_jupyter_client.py 2020-02-02
01:00:00.000000000 +0100
@@ -22,6 +22,6 @@
def test_echo_kernel():
- kernel = EchoKernel()
+ kernel = EchoKernel() # type:ignore[no-untyped-call]
kernel.session = Mock(spec=Session)
kernel.do_execute("foo", False)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pytest_jupyter-0.7.0/tests/test_jupyter_server.py
new/pytest_jupyter-0.8.0/tests/test_jupyter_server.py
--- old/pytest_jupyter-0.7.0/tests/test_jupyter_server.py 2020-02-02
01:00:00.000000000 +0100
+++ new/pytest_jupyter-0.8.0/tests/test_jupyter_server.py 2020-02-02
01:00:00.000000000 +0100
@@ -1,5 +1,6 @@
import json
import os
+from http import HTTPStatus
from unittest.mock import MagicMock
import pytest
@@ -9,6 +10,8 @@
from pytest_jupyter.jupyter_server import _Authorizer
+# mypy: ignore-errors
+
async def test_serverapp(jp_serverapp):
assert isinstance(jp_serverapp, ServerApp)
@@ -20,12 +23,12 @@
async def test_get_api_spec(jp_fetch):
response = await jp_fetch("api", "spec.yaml", method="GET")
- assert response.code == 200 # noqa
+ assert response.code == HTTPStatus.OK
async def test_send_request(send_request):
code = await send_request("api/spec.yaml", method="GET")
- assert code == 200 # noqa
+ assert code == HTTPStatus.OK
async def test_connection(jp_fetch, jp_ws_fetch, jp_http_port, jp_auth_header):