-
Notifications
You must be signed in to change notification settings - Fork 0
Feature/api cleanup #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Introduced new integration tests in `test_actor_list_integration.py` to validate the `pulsing actor list` command, including tests for listing user actors, all actors, and JSON output. - Added a new test file `test_actor_list_same_process.py` to verify actor listing using the Python API within the same process. - Created `test_actor_system.py` to run a system with actors for testing purposes. - Updated documentation to include usage examples for the actor list command and its integration in Python applications. - Added Bash and Python demo scripts to showcase the actor list functionality in practical scenarios. - Implemented tests for the actor list command in `test_actor_list.py`, ensuring correct output for both user and all actors in various formats.
- Updated `TracingConfig` to filter out gossip logs in addition to HTTP request logs, reducing span ID spam. - Introduced a new documentation file summarizing the complete implementation of the `pulsing actor list` feature, detailing local and remote query modes, usage examples, and architectural components. - Added a new Bash script to demonstrate remote querying of actors in a multi-node setup. - Refactored existing demo scripts for clarity and improved logging management. - Removed outdated example script for actor listing to streamline the codebase.
- Cleaned up whitespace in `test_actor_list_integration.py`, `test_actor_list_same_process.py`, and `test_actor_system.py` for better readability. - Enhanced output formatting in the actor listing commands to ensure consistent presentation across different output types. - Updated test cases in `test_actor_list.py` to validate the correct output for user and system actors, including JSON format checks. - Improved logging and error handling in the actor listing implementation to provide clearer feedback during execution.
…t clarity - Modified Bash demo scripts to disable Rust logging during actor list queries, enhancing output readability. - Updated Python implementation to clarify limitations of remote queries, specifying available metadata. - Refactored actor data retrieval methods to streamline the process and improve output formatting in the actor list command.
- Introduced metadata support for named actors, allowing for detailed information such as Python class, module, and file path to be registered and retrieved. - Updated the `GossipCluster` to handle full registration of named actors with metadata. - Enhanced the `ActorSystem` to provide detailed instance information, including metadata, when querying named actors. - Added new HTTP API endpoints for retrieving cluster members and detailed actor lists, improving usability for CLI tools. - Refactored Python actor implementation to extract and include metadata during actor creation, ensuring consistency across local and remote queries. - Updated Bash and Python demo scripts to showcase the new functionality and improve output clarity.
- Added comprehensive tests for REST API endpoints related to actor listing and cluster member information, ensuring correct functionality and response structure. - Implemented tests for querying single endpoints and clusters, validating both successful responses and error handling. - Enhanced output verification for actor metadata, ensuring accurate representation in various formats (table and JSON). - Included tests for internal functions to ensure robustness and reliability of the API interactions.
- Updated variable names in `test_actor_system.py` for clarity and consistency. - Simplified path handling in `system.rs` by using `strip_prefix` for better readability. - Enhanced formatting in `test_rest_api.py` to improve code clarity and maintainability.
| try: | ||
| source_file = inspect.getfile(cls) | ||
| metadata["python_file"] = source_file | ||
| except (TypeError, OSError): |
Check notice
Code scanning / CodeQL
Empty except Note
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
In general, empty except blocks should either be removed (if exceptions should propagate), narrowed, or augmented with at least logging or a comment explaining why it is safe to ignore them. Here, we want to preserve existing behavior: exceptions from inspect.getfile(cls) should not break registration, but should be visible for debugging.
The best fix is to keep the try/except but add a debug-level log entry in the except block explaining that the source file could not be determined, including the exception details. This keeps the code running exactly as before (no new exceptions are raised; metadata remains optional) while satisfying the static analysis rule and improving debuggability. Concretely, in python/pulsing/actor/remote.py, lines 78–82 inside _register_actor_metadata, replace the bare pass in the except (TypeError, OSError): block with a call to the module-level logger (already defined at line 38). No new imports are needed, since logging is already imported and logger is initialized.
-
Copy modified lines R81-R83
| @@ -78,8 +78,9 @@ | ||
| try: | ||
| source_file = inspect.getfile(cls) | ||
| metadata["python_file"] = source_file | ||
| except (TypeError, OSError): | ||
| pass | ||
| except (TypeError, OSError) as exc: | ||
| # Source file may not be available for some classes (e.g. builtins, dynamically created) | ||
| logger.debug("Could not determine source file for actor %s (%s): %s", name, cls, exc) | ||
|
|
||
| _actor_metadata_registry[name] = metadata | ||
|
|
|
|
||
| import asyncio | ||
| import subprocess | ||
| import time |
Check notice
Code scanning / CodeQL
Unused import Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix an unused import, remove the import statement for the unused module. This eliminates an unnecessary dependency, cleans up the code, and resolves the static analysis warning.
In this file (test_actor_list_integration.py), the best fix is to delete the import time line (line 6) and leave the rest of the file unchanged. No additional code, imports, or definitions are required, because all timing behavior is already handled through asyncio.sleep, and time is never referenced. The only region to edit is the import block at the top of the file: remove the import time line and keep the other imports (asyncio, subprocess, init, remote) as-is.
| @@ -3,7 +3,6 @@ | ||
|
|
||
| import asyncio | ||
| import subprocess | ||
| import time | ||
| from pulsing.actor import init, remote | ||
|
|
||
|
|
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), "python")) | ||
|
|
||
| from pulsing.actor import init, remote, get_system | ||
| from pulsing.admin import list_actors |
Check notice
Code scanning / CodeQL
Unused import Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the unused import problem, remove the import of list_actors since it is not referenced anywhere in this test. In general, unused imports should be deleted unless they are required for module-level side effects, which is not the case here.
Specifically, in test_actor_list_same_process.py, delete line 12: from pulsing.admin import list_actors. No other code needs to change, because all functionality (creating actors, listing them via system.local_actor_names(), and printing them) does not depend on list_actors. The remaining imports (asyncio, sys, os, and from pulsing.actor import init, remote, get_system) are still required by the existing code.
| @@ -9,7 +9,6 @@ | ||
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), "python")) | ||
|
|
||
| from pulsing.actor import init, remote, get_system | ||
| from pulsing.admin import list_actors | ||
|
|
||
|
|
||
| @remote |
| print("Actor system started on 0.0.0.0:8888") | ||
|
|
||
| # Create some named actors | ||
| _counter1 = await Counter.remote(name="counter-1") |
Check notice
Code scanning / CodeQL
Unused local variable Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
In general, to fix an unused local variable where the right-hand side has important side effects, you remove just the variable binding and keep evaluating the expression, or rename the variable to an accepted “intentionally unused” pattern. Here, the side effects we care about are the creation/registration of remote actors via Counter.remote and Calculator.remote. The variables _counter1, _counter2, and _calc are never used after creation, so the simplest behavior-preserving fix is to await those calls without assigning the results.
Concretely, in test_actor_system.py, lines 29–31 should be updated to drop the variable names and just await the remote calls. This keeps the actor-creation side effects (and the naming of the actors via name="...") exactly as before, while eliminating the unused local variables that CodeQL reports. No additional imports, methods, or definitions are required.
-
Copy modified lines R29-R31
| @@ -26,9 +26,9 @@ | ||
| print("Actor system started on 0.0.0.0:8888") | ||
|
|
||
| # Create some named actors | ||
| _counter1 = await Counter.remote(name="counter-1") | ||
| _counter2 = await Counter.remote(name="counter-2") | ||
| _calc = await Calculator.remote(name="calculator") | ||
| await Counter.remote(name="counter-1") | ||
| await Counter.remote(name="counter-2") | ||
| await Calculator.remote(name="calculator") | ||
|
|
||
| print("Created actors: counter-1, counter-2, calculator") | ||
| print("Actor system is running. Press Ctrl+C to stop.") |
|
|
||
| # Create some named actors | ||
| _counter1 = await Counter.remote(name="counter-1") | ||
| _counter2 = await Counter.remote(name="counter-2") |
Check notice
Code scanning / CodeQL
Unused local variable Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
In general, to fix an unused local variable warning when the assignment’s right-hand side has important side effects, you should remove the unused variable binding while keeping the expression that causes the side effect. Alternatively, if the variable is intentionally unused for clarity or documentation purposes, you can rename it to match an accepted “intentionally unused” pattern so static analysis tools ignore it.
Here, the best way without changing functionality is to drop the unused target _counter2 and keep the awaited call to Counter.remote. That means replacing _counter2 = await Counter.remote(...) with simply await Counter.remote(...). This preserves the creation and registration of the counter-2 actor while removing the unused local variable altogether. We should apply the same treatment consistently to _counter1 and _calc, since they are equally unused in this snippet, but per the prompt we must at least address _counter2. No new imports, methods, or definitions are required.
Concretely in test_actor_system.py, within main() at lines 29–31, we will change:
- Line 29:
_counter1 = await Counter.remote(name="counter-1")→await Counter.remote(name="counter-1") - Line 30:
_counter2 = await Counter.remote(name="counter-2")→await Counter.remote(name="counter-2") - Line 31:
_calc = await Calculator.remote(name="calculator")→await Calculator.remote(name="calculator")
This keeps all actors being created as before while eliminating unused locals.
-
Copy modified lines R29-R31
| @@ -26,9 +26,9 @@ | ||
| print("Actor system started on 0.0.0.0:8888") | ||
|
|
||
| # Create some named actors | ||
| _counter1 = await Counter.remote(name="counter-1") | ||
| _counter2 = await Counter.remote(name="counter-2") | ||
| _calc = await Calculator.remote(name="calculator") | ||
| await Counter.remote(name="counter-1") | ||
| await Counter.remote(name="counter-2") | ||
| await Calculator.remote(name="calculator") | ||
|
|
||
| print("Created actors: counter-1, counter-2, calculator") | ||
| print("Actor system is running. Press Ctrl+C to stop.") |
| # Create some named actors | ||
| _counter1 = await Counter.remote(name="counter-1") | ||
| _counter2 = await Counter.remote(name="counter-2") | ||
| _calc = await Calculator.remote(name="calculator") |
Check notice
Code scanning / CodeQL
Unused local variable Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
In general, to fix an unused local variable where the right-hand side has important side effects, remove or rename the left-hand side binding while preserving the expression evaluation. If the variable is truly needed later, instead use it somewhere meaningful; if it is intentionally unused, rename it to an accepted “unused” pattern.
Here, the right-hand side await Calculator.remote(name="calculator") likely has side effects (creating/registering the actor), so we should not remove the call. The variable _calc itself is never used, so the simplest and safest fix is to remove the assignment target and just await the call as a standalone statement. Concretely, in test_actor_system.py line 31, change:
_calc = await Calculator.remote(name="calculator")to:
await Calculator.remote(name="calculator")This keeps existing functionality (actors get created) while eliminating the unused local variable and satisfying CodeQL. No new imports, methods, or definitions are needed.
-
Copy modified line R31
| @@ -28,7 +28,7 @@ | ||
| # Create some named actors | ||
| _counter1 = await Counter.remote(name="counter-1") | ||
| _counter2 = await Counter.remote(name="counter-2") | ||
| _calc = await Calculator.remote(name="calculator") | ||
| await Calculator.remote(name="calculator") | ||
|
|
||
| print("Created actors: counter-1, counter-2, calculator") | ||
| print("Actor system is running. Press Ctrl+C to stop.") |
|
|
||
| if _global_system is not None: | ||
| await shutdown() | ||
| except Exception: |
Check notice
Code scanning / CodeQL
Empty except Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
In general, empty except blocks should either be removed, narrowed to specific expected exceptions, or should handle/log the exception in a meaningful way. In test teardown/cleanup code, a common pattern is to log the exception while allowing the test suite to proceed.
The best fix here without changing intended functionality is to keep catching Exception (so teardown failures don’t break tests) but to log the exception with a clear message. Pytest’s logging integration works with the standard library logging module, which is widely used and already available. We will:
- Add an
import loggingalongside the existing imports at the top oftests/python/conftest.py. - Replace the bare
except Exception: passwith anexcept Exception as exc:block that useslogging.getLogger(__name__).warning(..., exc_info=True)to record the failure and stack trace. This preserves the behavior of “don’t raise” while no longer silently discarding information.
Concretely:
- Modify lines around the imports to add
import logging. - Modify lines 29–30 so that instead of
except Exception:\n pass, we log the exception and do not re-raise.
-
Copy modified line R8 -
Copy modified lines R31-R34
| @@ -5,6 +5,7 @@ | ||
| Actor system tests use standalone mode and don't need external services. | ||
| """ | ||
|
|
||
| import logging | ||
| import pytest | ||
|
|
||
|
|
||
| @@ -27,4 +28,7 @@ | ||
| if _global_system is not None: | ||
| await shutdown() | ||
| except Exception: | ||
| pass | ||
| logging.getLogger(__name__).warning( | ||
| "Failed to clean up global actor system during test teardown", | ||
| exc_info=True, | ||
| ) |
| @@ -0,0 +1,119 @@ | |||
| """Test actor list command""" | |||
|
|
|||
| import asyncio | |||
Check notice
Code scanning / CodeQL
Unused import Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix the problem, remove the unused import statement for asyncio from the top of tests/python/test_actor_list.py. This resolves the unused import without changing any behavior, because the module and its contents were never referenced.
Concretely, in tests/python/test_actor_list.py, delete line 3 (import asyncio) and leave the remaining imports (pytest, pulsing.actor, pulsing.cli.actor_list, io, sys) unchanged. No new methods, imports, or definitions are required.
| @@ -1,6 +1,5 @@ | ||
| """Test actor list command""" | ||
|
|
||
| import asyncio | ||
| import pytest | ||
| from pulsing.actor import init, remote, get_system | ||
| from pulsing.cli.actor_list import list_actors_impl |
| @@ -0,0 +1,292 @@ | |||
| """Test REST API endpoints for actor list and cluster info""" | |||
|
|
|||
| import asyncio | |||
Check notice
Code scanning / CodeQL
Unused import Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix an unused import, remove the import statement for the module that is not referenced anywhere in the file. This reduces unnecessary dependencies and makes the code clearer without altering behavior.
In this case, the only change needed is to delete the import asyncio line near the top of tests/python/test_rest_api.py. No other code adjustments are required because nothing in the file references asyncio. Specifically, remove line 3 (import asyncio) and leave the remaining imports (pytest, unittest.mock, json, subprocess, and the pulsing.cli.actor_list items) unchanged. This will not affect test functionality since those imports are the ones actually used by the tests.
| @@ -1,6 +1,5 @@ | ||
| """Test REST API endpoints for actor list and cluster info""" | ||
|
|
||
| import asyncio | ||
| import pytest | ||
| from unittest.mock import patch, MagicMock | ||
| import json |
| import pytest | ||
| from unittest.mock import patch, MagicMock | ||
| import json | ||
| import subprocess |
Check notice
Code scanning / CodeQL
Unused import Note test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 1 day ago
To fix an unused import, remove the import statement for the unused module. This eliminates an unnecessary dependency and has no effect on runtime behavior as long as the module is truly unused.
In this case, the best fix is to delete the import subprocess line near the top of tests/python/test_rest_api.py. All mocking of subprocess behavior is already done via unittest.mock.patch with the fully qualified target string "subprocess.run", which does not require the subprocess name to be imported into this module. No other code in the shown regions refers to subprocess, and CodeQL confirms that there are no references elsewhere in the file.
Concretely, in tests/python/test_rest_api.py, remove line 7 containing import subprocess and leave all other imports and code unchanged. No additional methods, imports, or definitions are needed.
| @@ -4,7 +4,6 @@ | ||
| import pytest | ||
| from unittest.mock import patch, MagicMock | ||
| import json | ||
| import subprocess | ||
|
|
||
| from pulsing.cli.actor_list import ( | ||
| query_single_endpoint, |
Overview:
Details:
Where should the reviewer start?
Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)