diff --git a/openhands/linter/utils/__init__.py b/openhands/linter/utils/__init__.py index 69ee15767821..e48f26f076b5 100644 --- a/openhands/linter/utils/__init__.py +++ b/openhands/linter/utils/__init__.py @@ -1,3 +1,3 @@ -from .cmd import run_cmd, check_tool_installed +from .cmd import check_tool_installed, run_cmd __all__ = ['run_cmd', 'check_tool_installed'] diff --git a/openhands/linter/utils/cmd.py b/openhands/linter/utils/cmd.py index fdd8e5cfa07f..f5c2803c3d77 100644 --- a/openhands/linter/utils/cmd.py +++ b/openhands/linter/utils/cmd.py @@ -1,5 +1,6 @@ -import subprocess import os +import subprocess + def run_cmd(cmd: str, cwd: str | None = None) -> str | None: """Run a command and return the output. diff --git a/openhands/runtime/browser/browser_env.py b/openhands/runtime/browser/browser_env.py index fb652381364b..9ebbc0e1a732 100644 --- a/openhands/runtime/browser/browser_env.py +++ b/openhands/runtime/browser/browser_env.py @@ -16,8 +16,8 @@ from openhands.core.exceptions import BrowserInitException from openhands.core.logger import openhands_logger as logger -from openhands.utils.tenacity_stop import stop_if_should_exit from openhands.runtime.utils.shutdown_listener import should_continue, should_exit +from openhands.utils.tenacity_stop import stop_if_should_exit BROWSER_EVAL_GET_GOAL_ACTION = 'GET_EVAL_GOAL' BROWSER_EVAL_GET_REWARDS_ACTION = 'GET_EVAL_REWARDS' diff --git a/openhands/runtime/builder/remote.py b/openhands/runtime/builder/remote.py index 41596177acd1..a62872c2db8f 100644 --- a/openhands/runtime/builder/remote.py +++ b/openhands/runtime/builder/remote.py @@ -8,7 +8,10 @@ from openhands.core.logger import openhands_logger as logger from openhands.runtime.builder import RuntimeBuilder from openhands.runtime.utils.request import send_request -from openhands.runtime.utils.shutdown_listener import should_exit, sleep_if_should_continue +from openhands.runtime.utils.shutdown_listener import ( + should_exit, + sleep_if_should_continue, +) class RemoteRuntimeBuilder(RuntimeBuilder): diff --git a/openhands/runtime/client/client.py b/openhands/runtime/client/client.py index 43bc7cd15a5e..f0a1a8959d7b 100644 --- a/openhands/runtime/client/client.py +++ b/openhands/runtime/client/client.py @@ -325,7 +325,7 @@ def _continue_bash( _exit_code_output = self.shell.before try: exit_code = int(_exit_code_output.strip().split()[0]) - except: + except Exception: logger.error('Error getting exit code from bash script') # If we try to run an invalid shell script the output sometimes includes error text # rather than the error code - we assume this is an error @@ -628,7 +628,9 @@ async def execute_action(action_request: ActionRequest): observation = await client.run_action(action) return event_to_dict(observation) except Exception as e: - logger.error(f'Error processing command: {str(e)}', exc_info=True, stack_info=True) + logger.error( + f'Error processing command: {str(e)}', exc_info=True, stack_info=True + ) raise HTTPException(status_code=500, detail=str(e)) @app.post('/upload_file') diff --git a/openhands/runtime/remote/runtime.py b/openhands/runtime/remote/runtime.py index 8d8dbd52c339..c121021e869c 100644 --- a/openhands/runtime/remote/runtime.py +++ b/openhands/runtime/remote/runtime.py @@ -36,13 +36,13 @@ from openhands.runtime.builder.remote import RemoteRuntimeBuilder from openhands.runtime.plugins import PluginRequirement from openhands.runtime.runtime import Runtime -from openhands.utils.tenacity_stop import stop_if_should_exit from openhands.runtime.utils.request import ( DEFAULT_RETRY_EXCEPTIONS, is_404_error, send_request, ) from openhands.runtime.utils.runtime_build import build_runtime_image +from openhands.utils.tenacity_stop import stop_if_should_exit class RemoteRuntime(Runtime): diff --git a/openhands/runtime/utils/request.py b/openhands/runtime/utils/request.py index fb9d2a21ec6d..f67faf28f4e5 100644 --- a/openhands/runtime/utils/request.py +++ b/openhands/runtime/utils/request.py @@ -49,7 +49,7 @@ def send_request( if retry_fns is not None: for fn in retry_fns: retry_condition |= retry_if_exception(fn) - kwargs["timeout"] = timeout + kwargs['timeout'] = timeout @retry( stop=stop_after_delay(timeout) | stop_if_should_exit(), diff --git a/openhands/runtime/utils/runtime_build.py b/openhands/runtime/utils/runtime_build.py index ca6e3b0e4236..5d8dde1f1d79 100644 --- a/openhands/runtime/utils/runtime_build.py +++ b/openhands/runtime/utils/runtime_build.py @@ -251,7 +251,9 @@ def build_runtime_image( # Scenario 1: If we already have an image with the exact same hash, then it means the image is already built # with the exact same source code and Dockerfile, so we will reuse it. Building it is not required. - if not force_rebuild and runtime_builder.image_exists(hash_runtime_image_name, False): + if not force_rebuild and runtime_builder.image_exists( + hash_runtime_image_name, False + ): logger.info( f'Image [{hash_runtime_image_name}] already exists so we will reuse it.' ) diff --git a/openhands/runtime/utils/shutdown_listener.py b/openhands/runtime/utils/shutdown_listener.py index 882d532a40f1..9941c9f27372 100644 --- a/openhands/runtime/utils/shutdown_listener.py +++ b/openhands/runtime/utils/shutdown_listener.py @@ -1,6 +1,7 @@ """ This module monitors the app for shutdown signals """ + import asyncio import signal import time @@ -16,7 +17,7 @@ def _register_signal_handler(sig: signal.Signals): def handler(sig_: int, frame: FrameType | None): global _should_exit - _should_exit = True + _should_exit = True if original_handler: original_handler(sig_, frame) # type: ignore[unreachable] @@ -43,7 +44,7 @@ def should_continue() -> bool: def sleep_if_should_continue(timeout: float): - if(timeout <= 1): + if timeout <= 1: time.sleep(timeout) return start_time = time.time() @@ -52,7 +53,7 @@ def sleep_if_should_continue(timeout: float): async def async_sleep_if_should_continue(timeout: float): - if(timeout <= 1): + if timeout <= 1: await asyncio.sleep(timeout) return start_time = time.time() diff --git a/openhands/server/session/session.py b/openhands/server/session/session.py index 3254cf1457fe..f8cc2b581e7f 100644 --- a/openhands/server/session/session.py +++ b/openhands/server/session/session.py @@ -162,7 +162,9 @@ async def dispatch(self, data: dict): 'Model does not support image upload, change to a different model or try without an image.' ) return - asyncio.run_coroutine_threadsafe(self._add_event(event, EventSource.USER), self.agent_session.loop) # type: ignore + asyncio.run_coroutine_threadsafe( + self._add_event(event, EventSource.USER), self.agent_session.loop + ) # type: ignore async def _add_event(self, event, event_source): self.agent_session.event_stream.add_event(event, EventSource.USER) diff --git a/pyproject.toml b/pyproject.toml index 3b9a3bf69b0f..c5fe6ce3ff90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,6 +85,7 @@ reportlab = "*" [tool.coverage.run] concurrency = ["gevent"] + [tool.poetry.group.runtime.dependencies] jupyterlab = "*" notebook = "*" @@ -115,6 +116,7 @@ ignore = ["D1"] [tool.ruff.lint.pydocstyle] convention = "google" + [tool.poetry.group.evaluation.dependencies] streamlit = "*" whatthepatch = "*" diff --git a/tests/unit/linters/conftest.py b/tests/unit/linters/conftest.py index 189f04585369..4a2b51812bb9 100644 --- a/tests/unit/linters/conftest.py +++ b/tests/unit/linters/conftest.py @@ -1,5 +1,6 @@ import pytest + @pytest.fixture def syntax_error_py_file(tmp_path): file_content = """ @@ -8,7 +9,7 @@ def foo(): print("Wrong indent") foo( """ - file_path = tmp_path / "test_file.py" + file_path = tmp_path / 'test_file.py' file_path.write_text(file_content) return str(file_path) @@ -19,52 +20,56 @@ def wrongly_indented_py_file(tmp_path): def foo(): print("Hello, World!") """ - file_path = tmp_path / "test_file.py" + file_path = tmp_path / 'test_file.py' file_path.write_text(file_content) return str(file_path) + @pytest.fixture def simple_correct_py_file(tmp_path): file_content = 'print("Hello, World!")\n' - file_path = tmp_path / "test_file.py" + file_path = tmp_path / 'test_file.py' file_path.write_text(file_content) return str(file_path) + @pytest.fixture def simple_correct_py_func_def(tmp_path): file_content = """def foo(): print("Hello, World!") foo() """ - file_path = tmp_path / "test_file.py" + file_path = tmp_path / 'test_file.py' file_path.write_text(file_content) return str(file_path) + @pytest.fixture def simple_correct_ruby_file(tmp_path): - file_content ="""def foo + file_content = """def foo puts "Hello, World!" end foo """ - file_path = tmp_path / "test_file.rb" + file_path = tmp_path / 'test_file.rb' file_path.write_text(file_content) return str(file_path) @pytest.fixture def simple_incorrect_ruby_file(tmp_path): - file_content ="""def foo(): + file_content = """def foo(): print("Hello, World!") foo() """ - file_path = tmp_path / "test_file.rb" + file_path = tmp_path / 'test_file.rb' file_path.write_text(file_content) return str(file_path) + @pytest.fixture def parenthesis_incorrect_ruby_file(tmp_path): file_content = """def print_hello_world()\n puts 'Hello World'\n""" - file_path = tmp_path / "test_file.rb" + file_path = tmp_path / 'test_file.rb' file_path.write_text(file_content) return str(file_path)