diff --git a/pyproject.toml b/pyproject.toml index 38880aff1..c756663c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -232,8 +232,8 @@ omit = [ "src/reactpy/__init__.py", "src/reactpy/_console/*", "src/reactpy/__main__.py", - "src/reactpy/pyscript/layout_handler.py", - "src/reactpy/pyscript/component_template.py", + "src/reactpy/executors/pyscript/layout_handler.py", + "src/reactpy/executors/pyscript/component_template.py", ] [tool.coverage.report] diff --git a/src/build_scripts/install_playwright.py b/src/build_scripts/install_playwright.py index eb78d2dec..d8d9cee70 100644 --- a/src/build_scripts/install_playwright.py +++ b/src/build_scripts/install_playwright.py @@ -14,4 +14,4 @@ # as *nix systems (such as WSL) return a failure code if there are *any* dependencies # that could be cleaned up via `sudo apt autoremove`. This occurs even if we weren't # the ones to install those dependencies in the first place. -subprocess.run(["playwright", "install-deps"], check=False) # noqa: S607 +subprocess.run(["playwright", "install-deps", "chromium"], check=False) # noqa: S607 diff --git a/src/js/packages/@reactpy/client/src/bind.tsx b/src/js/packages/@reactpy/client/src/bind.tsx index 8feb43c67..93d7fb2ae 100644 --- a/src/js/packages/@reactpy/client/src/bind.tsx +++ b/src/js/packages/@reactpy/client/src/bind.tsx @@ -6,14 +6,11 @@ export async function infer_bind_from_environment() { const React = await import("react"); // @ts-ignore const ReactDOM = await import("react-dom/client"); - - console.log( - "ReactPy detected 'ReactJS' to bind your JavaScript components.", - ); return (node: HTMLElement) => reactjs_bind(node, React, ReactDOM); } catch { - console.debug( - "ReactPy did not detect a component binding function or a suitable 'importmap'. Using ReactPy's internal framework (Preact) to bind your JavaScript components.", + console.error( + "Unknown error occurred: 'react' is missing within this ReactPy environment! \ + Your JavaScript components may not work as expected!", ); return (node: HTMLElement) => local_preact_bind(node); } diff --git a/src/js/packages/@reactpy/client/src/components.tsx b/src/js/packages/@reactpy/client/src/components.tsx index 2fb2debde..f6d06a381 100644 --- a/src/js/packages/@reactpy/client/src/components.tsx +++ b/src/js/packages/@reactpy/client/src/components.tsx @@ -6,13 +6,13 @@ import type { ImportSourceBinding, ReactPyComponent, ReactPyVdom, - ReactPyClientInterface, } from "./types"; import { createAttributes, createChildren, loadImportSource } from "./vdom"; +import type { ReactPyClient } from "./client"; -const ClientContext = createContext(null as any); +const ClientContext = createContext(null as any); -export function Layout(props: { client: ReactPyClientInterface }): JSX.Element { +export function Layout(props: { client: ReactPyClient }): JSX.Element { const currentModel: ReactPyVdom = useState({ tagName: "" })[0]; const forceUpdate = useForceUpdate(); diff --git a/src/js/packages/@reactpy/client/src/vdom.tsx b/src/js/packages/@reactpy/client/src/vdom.tsx index 736683ed6..e57ea4594 100644 --- a/src/js/packages/@reactpy/client/src/vdom.tsx +++ b/src/js/packages/@reactpy/client/src/vdom.tsx @@ -1,4 +1,3 @@ -import type { ReactPyClientInterface } from "./types"; import eventToObject from "event-to-object"; import type { ReactPyVdom, @@ -11,10 +10,11 @@ import type { } from "./types"; import { infer_bind_from_environment } from "./bind"; import log from "./logger"; +import type { ReactPyClient } from "./client"; export async function loadImportSource( vdomImportSource: ReactPyVdomImportSource, - client: ReactPyClientInterface, + client: ReactPyClient, ): Promise { let module: ReactPyModule; if (vdomImportSource.sourceType === "URL") { @@ -61,7 +61,7 @@ export async function loadImportSource( } function createImportSourceElement(props: { - client: ReactPyClientInterface; + client: ReactPyClient; module: ReactPyModule; binding: ReactPyModuleBinding; model: ReactPyVdom; @@ -180,7 +180,7 @@ export function createChildren( export function createAttributes( model: ReactPyVdom, - client: ReactPyClientInterface, + client: ReactPyClient, ): { [key: string]: any } { return Object.fromEntries( Object.entries({ @@ -203,7 +203,7 @@ export function createAttributes( } function createEventHandler( - client: ReactPyClientInterface, + client: ReactPyClient, name: string, { target, preventDefault, stopPropagation }: ReactPyVdomEventHandler, ): [string, () => void] { @@ -262,7 +262,7 @@ function createInlineJavaScript( class ReactPyChild extends HTMLElement { mountPoint: HTMLDivElement; binding: ImportSourceBinding | null = null; - _client: ReactPyClientInterface | null = null; + _client: ReactPyClient | null = null; _model: ReactPyVdom | null = null; currentImportSource: ReactPyVdomImportSource | null = null; @@ -276,7 +276,7 @@ class ReactPyChild extends HTMLElement { this.appendChild(this.mountPoint); } - set client(value: ReactPyClientInterface) { + set client(value: ReactPyClient) { this._client = value; } diff --git a/src/reactpy/__init__.py b/src/reactpy/__init__.py index 27b462d8c..5d1c64d56 100644 --- a/src/reactpy/__init__.py +++ b/src/reactpy/__init__.py @@ -19,11 +19,11 @@ use_state, ) from reactpy.core.vdom import Vdom -from reactpy.pyscript.components import pyscript_component +from reactpy.executors.pyscript.components import pyscript_component from reactpy.utils import Ref, reactpy_to_string, string_to_reactpy __author__ = "The Reactive Python Team" -__version__ = "2.0.0b6" +__version__ = "2.0.0b7" __all__ = [ "Ref", diff --git a/src/reactpy/core/_thread_local.py b/src/reactpy/core/_thread_local.py index 9d4bae99c..4d859b7a8 100644 --- a/src/reactpy/core/_thread_local.py +++ b/src/reactpy/core/_thread_local.py @@ -8,7 +8,7 @@ class ThreadLocal(Generic[_StateType]): # nocov """Utility for managing per-thread state information. This is only used in - environments where ContextVars are not available, such as the `pyodide` + environments where ContextVars are not available, such as the `pyscript` executor.""" def __init__(self, default: Callable[[], _StateType]): diff --git a/src/reactpy/core/hooks.py b/src/reactpy/core/hooks.py index 27fbc1ce4..3692a98b3 100644 --- a/src/reactpy/core/hooks.py +++ b/src/reactpy/core/hooks.py @@ -84,11 +84,7 @@ def __init__( self, initial_value: _Type | Callable[[], _Type], ) -> None: - if callable(initial_value): - self.value = initial_value() - else: - self.value = initial_value - + self.value = initial_value() if callable(initial_value) else initial_value hook = HOOK_STACK.current_hook() def dispatch(new: _Type | Callable[[_Type], _Type]) -> None: @@ -434,10 +430,7 @@ def use_callback( def setup(function: _CallbackFunc) -> _CallbackFunc: return memoize(lambda: function) - if function is not None: - return setup(function) - else: - return setup + return setup(function) if function is not None else setup class _LambdaCaller(Protocol): @@ -553,17 +546,16 @@ def _try_to_infer_closure_values( func: Callable[..., Any] | None, values: Sequence[Any] | ellipsis | None, ) -> Sequence[Any] | None: - if values is ...: - if isinstance(func, FunctionType): - return ( - [cell.cell_contents for cell in func.__closure__] - if func.__closure__ - else [] - ) - else: - return None - else: + if values is not ...: return values + if isinstance(func, FunctionType): + return ( + [cell.cell_contents for cell in func.__closure__] + if func.__closure__ + else [] + ) + else: + return None def strictly_equal(x: Any, y: Any) -> bool: diff --git a/src/reactpy/executors/asgi/pyscript.py b/src/reactpy/executors/asgi/pyscript.py index edae4386d..20a094cb7 100644 --- a/src/reactpy/executors/asgi/pyscript.py +++ b/src/reactpy/executors/asgi/pyscript.py @@ -13,8 +13,11 @@ from reactpy.executors.asgi.middleware import ReactPyMiddleware from reactpy.executors.asgi.standalone import ReactPy, ReactPyApp from reactpy.executors.asgi.types import AsgiWebsocketScope +from reactpy.executors.pyscript.utils import ( + pyscript_component_html, + pyscript_setup_html, +) from reactpy.executors.utils import vdom_head_to_html -from reactpy.pyscript.utils import pyscript_component_html, pyscript_setup_html from reactpy.types import ReactPyConfig, VdomDict diff --git a/src/reactpy/executors/asgi/standalone.py b/src/reactpy/executors/asgi/standalone.py index 35875f606..b16246995 100644 --- a/src/reactpy/executors/asgi/standalone.py +++ b/src/reactpy/executors/asgi/standalone.py @@ -23,8 +23,8 @@ AsgiV3WebsocketApp, AsgiWebsocketScope, ) +from reactpy.executors.pyscript.utils import pyscript_setup_html from reactpy.executors.utils import server_side_component_html, vdom_head_to_html -from reactpy.pyscript.utils import pyscript_setup_html from reactpy.types import ( PyScriptOptions, ReactPyConfig, diff --git a/src/reactpy/pyscript/__init__.py b/src/reactpy/executors/pyscript/__init__.py similarity index 100% rename from src/reactpy/pyscript/__init__.py rename to src/reactpy/executors/pyscript/__init__.py diff --git a/src/reactpy/pyscript/component_template.py b/src/reactpy/executors/pyscript/component_template.py similarity index 90% rename from src/reactpy/pyscript/component_template.py rename to src/reactpy/executors/pyscript/component_template.py index 009ca56f7..71710a42e 100644 --- a/src/reactpy/pyscript/component_template.py +++ b/src/reactpy/executors/pyscript/component_template.py @@ -2,7 +2,7 @@ # type: ignore import asyncio -from reactpy.pyscript.layout_handler import ReactPyLayoutHandler +from reactpy.executors.pyscript.layout_handler import ReactPyLayoutHandler # User component is inserted below by regex replacement diff --git a/src/reactpy/pyscript/components.py b/src/reactpy/executors/pyscript/components.py similarity index 96% rename from src/reactpy/pyscript/components.py rename to src/reactpy/executors/pyscript/components.py index 8fb769eca..54940ad48 100644 --- a/src/reactpy/pyscript/components.py +++ b/src/reactpy/executors/pyscript/components.py @@ -4,7 +4,7 @@ from typing import TYPE_CHECKING from reactpy import component, hooks -from reactpy.pyscript.utils import pyscript_component_html +from reactpy.executors.pyscript.utils import pyscript_component_html from reactpy.types import Component, Key from reactpy.utils import string_to_reactpy diff --git a/src/reactpy/pyscript/layout_handler.py b/src/reactpy/executors/pyscript/layout_handler.py similarity index 100% rename from src/reactpy/pyscript/layout_handler.py rename to src/reactpy/executors/pyscript/layout_handler.py diff --git a/src/reactpy/pyscript/utils.py b/src/reactpy/executors/pyscript/utils.py similarity index 100% rename from src/reactpy/pyscript/utils.py rename to src/reactpy/executors/pyscript/utils.py diff --git a/src/reactpy/executors/utils.py b/src/reactpy/executors/utils.py index b68d56627..291674a8a 100644 --- a/src/reactpy/executors/utils.py +++ b/src/reactpy/executors/utils.py @@ -64,16 +64,41 @@ def server_side_component_html( ) -> str: return ( f'
' + "" '" ) + + +def default_import_map() -> str: + path_prefix = REACTPY_PATH_PREFIX.current.strip("/") + return f"""{{ + "imports": {{ + "react": "/{path_prefix}/static/preact.js", + "react-dom": "/{path_prefix}/static/preact-dom.js", + "react-dom/client": "/{path_prefix}/static/preact-dom.js", + "react/jsx-runtime": "/{path_prefix}/static/preact-jsx-runtime.js" + }} + }}""".replace("\n", "").replace(" ", "") diff --git a/src/reactpy/reactjs/module.py b/src/reactpy/reactjs/module.py index 89f0231f5..d9ce6758d 100644 --- a/src/reactpy/reactjs/module.py +++ b/src/reactpy/reactjs/module.py @@ -4,7 +4,6 @@ from pathlib import Path, PurePosixPath from typing import Any, Literal -from reactpy import config from reactpy.config import REACTPY_DEBUG, REACTPY_WEB_MODULES_DIR from reactpy.core.vdom import Vdom from reactpy.reactjs.types import NAME_SOURCE, URL_SOURCE @@ -15,7 +14,7 @@ resolve_names_from_file, resolve_names_from_url, ) -from reactpy.types import ImportSourceDict, JavaScriptModule, VdomConstructor +from reactpy.types import ImportSourceDict, JavaScriptModule, VdomConstructor, VdomDict logger = logging.getLogger(__name__) @@ -183,7 +182,7 @@ def import_reactjs( framework: Literal["preact", "react"] | None = None, version: str | None = None, use_local: bool = False, -): +) -> VdomDict: """ Return an import map script tag for ReactJS or Preact. Parameters: @@ -205,6 +204,7 @@ def import_reactjs( A VDOM script tag containing the import map. """ from reactpy import html + from reactpy.executors.utils import default_import_map if use_local and (framework or version): # nocov raise ValueError("use_local cannot be used with framework or version") @@ -215,19 +215,9 @@ def import_reactjs( # Import map for ReactPy's local framework (re-exported/bundled/minified version of Preact) if use_local: - prefix = f"/{config.REACTPY_PATH_PREFIX.current.strip('/')}/static/{framework}" return html.script( - {"type": "importmap"}, - f""" - {{ - "imports": {{ - "react": "{prefix}.js", - "react-dom": "{prefix}-dom.js", - "react-dom/client": "{prefix}-dom.js", - "react/jsx-runtime": "{prefix}-jsx-runtime.js" - }} - }} - """, + {"type": "importmap", "id": "reactpy-importmap"}, + default_import_map(), ) # Import map for ReactJS from esm.sh @@ -235,17 +225,15 @@ def import_reactjs( version = version or "19" postfix = "?dev" if REACTPY_DEBUG.current else "" return html.script( - {"type": "importmap"}, - f""" - {{ + {"type": "importmap", "id": "reactpy-importmap"}, + f"""{{ "imports": {{ "react": "https://esm.sh/react@{version}{postfix}", "react-dom": "https://esm.sh/react-dom@{version}{postfix}", "react-dom/client": "https://esm.sh/react-dom@{version}/client{postfix}", "react/jsx-runtime": "https://esm.sh/react@{version}/jsx-runtime{postfix}" }} - }} - """, + }}""".replace("\n", "").replace(" ", ""), ) # Import map for Preact from esm.sh @@ -253,17 +241,15 @@ def import_reactjs( version = version or "10" postfix = "?dev" if REACTPY_DEBUG.current else "" return html.script( - {"type": "importmap"}, - f""" - {{ + {"type": "importmap", "id": "reactpy-importmap"}, + f"""{{ "imports": {{ "react": "https://esm.sh/preact@{version}/compat{postfix}", "react-dom": "https://esm.sh/preact@{version}/compat{postfix}", "react-dom/client": "https://esm.sh/preact@{version}/compat/client{postfix}", "react/jsx-runtime": "https://esm.sh/preact@{version}/compat/jsx-runtime{postfix}" }} - }} - """, + }}""".replace("\n", "").replace(" ", ""), ) diff --git a/src/reactpy/templatetags/jinja.py b/src/reactpy/templatetags/jinja.py index e2cf83489..e7f980dcb 100644 --- a/src/reactpy/templatetags/jinja.py +++ b/src/reactpy/templatetags/jinja.py @@ -3,8 +3,11 @@ from jinja2_simple_tags import StandaloneTag +from reactpy.executors.pyscript.utils import ( + pyscript_component_html, + pyscript_setup_html, +) from reactpy.executors.utils import server_side_component_html -from reactpy.pyscript.utils import pyscript_component_html, pyscript_setup_html class ReactPyJinja(StandaloneTag): # type: ignore diff --git a/src/reactpy/testing/display.py b/src/reactpy/testing/display.py index 33a6e6295..4dc4c53cb 100644 --- a/src/reactpy/testing/display.py +++ b/src/reactpy/testing/display.py @@ -2,6 +2,7 @@ import os from contextlib import AsyncExitStack +from logging import getLogger from types import TracebackType from typing import TYPE_CHECKING, Any @@ -14,6 +15,8 @@ if TYPE_CHECKING: import pytest +_logger = getLogger(__name__) + class DisplayFixture: """A fixture for running web-based tests using ``playwright``""" @@ -77,12 +80,16 @@ async def configure_page(self) -> None: self.page.set_default_timeout(self.timeout * 1000) self.page.on( "requestfailed", - lambda x: print(f"BROWSER LOAD ERROR: {x.url}\n{x.failure}"), # noqa: T201 + lambda x: _logger.error(f"BROWSER LOAD ERROR: {x.url}\n{x.failure}"), + ) + self.page.on( + "console", lambda x: _logger.info(f"BROWSER CONSOLE: {x.text}") ) - self.page.on("console", lambda x: print(f"BROWSER CONSOLE: {x.text}")) # noqa: T201 self.page.on( "pageerror", - lambda x: print(f"BROWSER ERROR: {x.name} - {x.message}\n{x.stack}"), # noqa: T201 + lambda x: _logger.error( + f"BROWSER ERROR: {x.name} - {x.message}\n{x.stack}" + ), ) async def __aexit__( diff --git a/tests/test_asgi/test_middleware.py b/tests/test_asgi/test_middleware.py index 81d7dab88..2c0a5ec58 100644 --- a/tests/test_asgi/test_middleware.py +++ b/tests/test_asgi/test_middleware.py @@ -80,14 +80,15 @@ def Stub(): # Wait for the log record to be populated for _ in range(10): - if len(server.log_records) > 0: + if "Attempting to use an unregistered root component" in " ".join( + x.message for x in server.log_records + ): break await asyncio.sleep(0.25) # Check that the log record was populated with the "unregistered component" message - assert ( - "Attempting to use an unregistered root component" - in server.log_records[-1].message + assert "Attempting to use an unregistered root component" in " ".join( + x.message for x in server.log_records ) @@ -119,7 +120,7 @@ async def app(scope, receive, send): ... assert response.status_code == 404 -async def test_templatetag_bad_kwargs(caplog, browser): +async def test_templatetag_bad_kwargs(browser): """Override for the display fixture that uses ReactPyMiddleware.""" templates = Jinja2Templates( env=JinjaEnvironment( diff --git a/tests/test_core/test_hooks.py b/tests/test_core/test_hooks.py index 93e64a692..804b055c5 100644 --- a/tests/test_core/test_hooks.py +++ b/tests/test_core/test_hooks.py @@ -518,7 +518,7 @@ async def effect(): await asyncio.wait_for(cleanup_ran.wait(), 1) -async def test_use_async_effect_cancel(caplog): +async def test_use_async_effect_cancel(): component_hook = HookCatcher() effect_ran = asyncio.Event() effect_was_cancelled = asyncio.Event() @@ -557,7 +557,7 @@ async def effect(): event_that_never_occurs.set() -async def test_error_in_effect_is_gracefully_handled(caplog): +async def test_error_in_effect_is_gracefully_handled(): @reactpy.component def ComponentWithEffect(): @reactpy.hooks.use_effect diff --git a/tests/test_core/test_layout.py b/tests/test_core/test_layout.py index 07ce0992d..cb017ea70 100644 --- a/tests/test_core/test_layout.py +++ b/tests/test_core/test_layout.py @@ -63,7 +63,7 @@ def test_layout_expects_abstract_component(): Layout(reactpy.html.div()) -async def test_layout_cannot_be_used_outside_context_manager(caplog): +async def test_layout_cannot_be_used_outside_context_manager(): @reactpy.component def Component(): ... @@ -691,7 +691,7 @@ def HasNestedEventHandler(): assert last_event_handler() is None -async def test_duplicate_sibling_keys_causes_error(caplog): +async def test_duplicate_sibling_keys_causes_error(): hook = HookCatcher() should_error = True diff --git a/tests/test_pyscript/test_utils.py b/tests/test_pyscript/test_utils.py index 4ae89d841..14a54ca96 100644 --- a/tests/test_pyscript/test_utils.py +++ b/tests/test_pyscript/test_utils.py @@ -6,7 +6,7 @@ import orjson import pytest -from reactpy.pyscript import utils +from reactpy.executors.pyscript import utils def test_bad_root_name(): @@ -69,8 +69,8 @@ def test_get_reactpy_versions_https_fail_http_success(): # Mock json.load to return data when called with mock_response with ( - mock.patch("reactpy.pyscript.utils.request.urlopen") as mock_urlopen, - mock.patch("reactpy.pyscript.utils.json.load") as mock_json_load, + mock.patch("reactpy.executors.pyscript.utils.request.urlopen") as mock_urlopen, + mock.patch("reactpy.executors.pyscript.utils.json.load") as mock_json_load, ): def side_effect(url, timeout): @@ -97,8 +97,8 @@ def test_get_reactpy_versions_all_fail(): utils.get_reactpy_versions.cache_clear() with ( - mock.patch("reactpy.pyscript.utils.request.urlopen") as mock_urlopen, - mock.patch("reactpy.pyscript.utils._logger") as mock_logger, + mock.patch("reactpy.executors.pyscript.utils.request.urlopen") as mock_urlopen, + mock.patch("reactpy.executors.pyscript.utils._logger") as mock_logger, ): mock_urlopen.side_effect = URLError("Fail") diff --git a/tests/test_reactjs/test_modules_from_npm.py b/tests/test_reactjs/test_modules_from_npm.py index 6e2477518..2a7573955 100644 --- a/tests/test_reactjs/test_modules_from_npm.py +++ b/tests/test_reactjs/test_modules_from_npm.py @@ -6,6 +6,8 @@ from reactpy.reactjs import component_from_npm, import_reactjs from reactpy.testing import GITHUB_ACTIONS, BackendFixture, DisplayFixture +MISSING_IMPORT_MAP_MSG = "ReactPy did not detect a suitable JavaScript import map" + @pytest.fixture(scope="module") async def display(browser): @@ -16,7 +18,7 @@ async def display(browser): @pytest.mark.flaky(reruns=10 if GITHUB_ACTIONS else 1) -async def test_component_from_npm_react_bootstrap(display: DisplayFixture): +async def test_component_from_npm_react_bootstrap(display: DisplayFixture, caplog): Button = component_from_npm("react-bootstrap", "Button", version="2") @reactpy.component @@ -33,9 +35,12 @@ def App(): await expect(button).to_contain_class("btn") await expect(button).to_contain_class("btn-primary") + # Ensure missing import map was NOT logged + assert MISSING_IMPORT_MAP_MSG not in " ".join(x.msg for x in caplog.records) + @pytest.mark.flaky(reruns=10 if GITHUB_ACTIONS else 1) -async def test_component_from_npm_react_bootstrap_with_local_framework(browser): +async def test_component_from_npm_react_bootstrap_with_local_framework(browser, caplog): Button = component_from_npm("react-bootstrap", "Button", version="2") @reactpy.component @@ -56,6 +61,33 @@ def App(): await expect(button).to_contain_class("btn") await expect(button).to_contain_class("btn-primary") + # Ensure missing import map was NOT logged + assert MISSING_IMPORT_MAP_MSG not in " ".join(x.msg for x in caplog.records) + + +@pytest.mark.flaky(reruns=10 if GITHUB_ACTIONS else 1) +async def test_component_from_npm_without_explicit_reactjs_import(browser, caplog): + Button = component_from_npm("react-bootstrap", "Button", version="2") + + @reactpy.component + def App(): + return Button({"variant": "primary", "id": "test-button"}, "Click me") + + async with BackendFixture() as backend: + async with DisplayFixture(backend=backend, browser=browser) as display: + await display.show(App) + + button = display.page.locator("#test-button") + await expect(button).to_have_text("Click me") + + # Check if it has the correct class for primary variant + # React Bootstrap buttons usually have 'btn' and 'btn-primary' classes + await expect(button).to_contain_class("btn") + await expect(button).to_contain_class("btn-primary") + + # Check if missing import map was logged + assert MISSING_IMPORT_MAP_MSG in " ".join(x.msg for x in caplog.records) + @pytest.mark.flaky(reruns=10 if GITHUB_ACTIONS else 1) async def test_component_from_npm_material_ui(display: DisplayFixture): diff --git a/tests/test_reactjs/test_utils.py b/tests/test_reactjs/test_utils.py index 95bac62e6..ecf746af0 100644 --- a/tests/test_reactjs/test_utils.py +++ b/tests/test_reactjs/test_utils.py @@ -36,7 +36,7 @@ def test_module_name_suffix(name, suffix): @responses.activate -def test_resolve_module_exports_from_file(caplog): +def test_resolve_module_exports_from_file(): responses.add( responses.GET, "https://some.external.url",