Skip to content

Feature/refactor api#44

Merged
reiase merged 24 commits intomainfrom
feature/refactor_api
Jan 24, 2026
Merged

Feature/refactor api#44
reiase merged 24 commits intomainfrom
feature/refactor_api

Conversation

@reiase
Copy link
Contributor

@reiase reiase commented Jan 24, 2026

Overview:

Details:

Where should the reviewer start?

Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)

  • closes GitHub issue: #xxx

reiase added 22 commits January 18, 2026 21:42
…tructure and remove deprecated features

- Updated README files to clarify the usage of the `pulsing actor` command, now requiring full class paths for actor types.
- Enhanced documentation for starting actors, including examples for the new Router and worker classes.
- Removed references to the deprecated `pulsing actor list` command, replacing it with `pulsing inspect` for actor system observation.
- Updated various examples and guides to align with the new command structure and improve user understanding.
…onality

- Introduced `pulsing_pingpong.py` demonstrating a simple ping-pong interaction using the @Remote decorator.
- Added `pulsing_research.py` showcasing a multi-agent research workflow with Researcher, Analyst, and Reporter agents.
- Created `chaos_proof.py` to illustrate actor resilience with automatic restarts on failure, simulating task completion despite crashes.
- Implemented `function_to_fleet.py` to demonstrate scaling functions into a fleet of workers for improved throughput.
- Updated README with new examples and usage instructions for enhanced clarity and user guidance.
- Updated actor spawning calls across multiple files to use named parameters for better readability, ensuring the actor name is explicitly defined.
- Adjusted print statements in various examples to enhance formatting consistency.
- Enhanced the `spawn` method in the actor system to support anonymous actors and custom options, improving flexibility in actor management.
- Refactored tests to align with the new actor spawning structure, ensuring comprehensive coverage and reliability in functionality.
- Introduced a new documentation file `llms.binding.md` detailing the Pulsing API reference for LLMs, including Python interface examples for Actor System and queue operations.
- Updated existing API reference documentation (`api_reference.md` and `api_reference.zh.md`) to reflect the new `pul.actor_system` usage and provide clearer examples.
- Revised example scripts for distributed counter and ping-pong interactions to align with the new API structure, enhancing clarity and usability.
- Refactored queue documentation to standardize the usage of `system.queue.write` and `system.queue.read` methods, improving consistency across examples and guides.
- Enhanced the README files to include updated usage instructions and examples for the new queue API, ensuring comprehensive user guidance.
- Replaced instances of create_actor_system with pul.actor_system across multiple benchmark and test files for consistency.
- Updated actor system configuration to utilize named parameters for address and seed nodes, enhancing clarity in system setup.
- Improved documentation and test cases to reflect the new actor system initialization method, ensuring comprehensive coverage and usability.
- Introduced `ray.shutdown()` to close the system gracefully.
- Added `ray.is_initialized()` to check if the system is initialized.
- Updated `ray.get()` to support both single and list ObjectRefs for result retrieval.
- Introduced `ray.put()` for wrapping values as ObjectRefs for API compatibility.
- Added `ray.wait()` to wait for multiple ObjectRefs to complete, enhancing functionality and usability.
- Added a `public` parameter to the `ActorClass` methods for actor visibility control.
- Updated method signatures and documentation to reflect the new `public` argument.
- Introduced new test files for API coverage, including tests for actor system creation, spawning, and resolving.
- Created tests for both Ray-compatible and Ray-like APIs, ensuring robust functionality and compatibility.
- Added fixtures and comprehensive test cases to validate actor behavior and interactions.
- Introduced detailed examples for basic and advanced Actor usage, including synchronous and asynchronous methods.
- Added explanations for the @pul.remote decorator, message passing patterns, and Actor lifecycle management.
- Included guidance on supervision and restart strategies, as well as streaming responses for Actors.
- Enhanced clarity on method definitions and usage scenarios to improve user understanding of the Pulsing API.
- Introduced a new `Generator` variant in `PyActorResponse` to handle both synchronous and asynchronous Python generators.
- Implemented logic to iterate over generators in the `Actor` trait, utilizing channels for streaming values.
- Enhanced error handling for generator iteration, including checks for `StopIteration` and `StopAsyncIteration`.
- Updated the actor's response handling to accommodate the new generator functionality, improving the API's versatility.
- Added `_SyncGeneratorStreamReader` to handle synchronous generator responses in the Actor framework.
- Enhanced `_MethodCaller` to recognize stream messages and return appropriate stream readers.
- Introduced `_handle_generator_result` method in `_WrappedActor` to manage generator results and provide streaming responses.
- Removed outdated test files and added new tests for actor behavior, including comprehensive coverage for synchronous and asynchronous methods, message passing, and actor lifecycle management.
- Updated documentation to reflect changes in actor behavior and streaming capabilities.
- Converted WorkerActor, DispatcherActor, CacheActor, and EchoActor to standalone classes, eliminating the need for the Actor base class.
- Updated message handling to use dictionaries instead of Message objects for improved simplicity and clarity.
- Enhanced the receive methods to support action-based message processing, allowing for more flexible interactions.
- Adjusted example scripts to reflect the new class structures and message patterns, ensuring consistency across the codebase.
…ion and API usage

- Removed references to `resolve()` in favor of `ClassName.resolve()` for clarity and consistency across documentation.
- Updated example scripts to demonstrate the new actor resolution method, ensuring users can easily find and interact with existing actors.
- Enhanced README and guide sections to provide clearer instructions on using the `@remote` decorator and actor spawning.
- Adjusted code snippets to reflect the latest API changes, improving overall usability and understanding of the Pulsing framework.
- Introduced a new section in the API reference documentation detailing the user-facing contract for Pulsing's Python API, derived from `llms.binding.md`.
- Added explanations for concurrency models, streaming, error handling, and trust boundaries to enhance user understanding.
- Updated the Chinese API reference to include the same contract and semantics information, ensuring consistency across languages.
- Made minor adjustments to the queue manager to support backward compatibility with node status checks.
- Introduced new traits for Actor System extensions: `ActorSystemCoreExt`, `ActorSystemAdvancedExt`, and `ActorSystemOpsExt`, providing core operations, factory-based spawning, and lifecycle management.
- Updated the Rust API documentation to reflect the new trait structure, enhancing clarity on spawning, resolving, and actor management.
- Added comprehensive examples for the new API methods in both English and Chinese documentation, ensuring consistency and usability.
- Made minor adjustments to existing code and documentation for improved readability and backward compatibility.
- Updated the Actor System API to streamline actor spawning, introducing `spawn_named` for named actors and `spawn_anonymous` for anonymous actors.
- Enhanced documentation to clarify the usage of new spawning methods and their implications for actor resolution.
- Removed the `public` parameter from `SpawnOptions`, as all named actors are now resolvable by default.
- Adjusted existing code and tests to reflect the new API structure, ensuring consistency and backward compatibility.
- Improved examples in documentation to demonstrate the updated spawning and resolution patterns.
- Introduced a new `ResolveBuilder` for advanced actor resolution options, allowing users to specify load balancing policies, target specific nodes, and filter for alive instances.
- Added `resolve_all_instances` method to retrieve all instances of a named actor, with optional filtering for alive actors.
- Updated documentation in `llms.binding.md` to include new resolution methods and examples in both English and Chinese, improving clarity and usability.
- Enhanced existing traits and methods to support the new resolution patterns, ensuring consistency across the API.
- Updated actor naming logic to ensure names follow the namespace/name format, improving consistency across the API.
- Adjusted the Python actor service name to align with the new naming convention.
- Enhanced tests to validate the new naming structure and ensure proper registration of system actors.
- Updated documentation and test assertions to reflect changes in actor naming and resolution behavior.
- Introduced the `IntoActor` trait, allowing seamless integration of `Behavior<M>` with existing actor spawning methods (`spawn` and `spawn_named`).
- Updated documentation and examples to reflect the new behavior spawning capabilities, ensuring clarity on usage patterns.
- Refactored actor context and system references to support named actors, improving supervision and resolution mechanisms.
- Enhanced tests to validate the new behavior functionality and ensure consistent actor interactions across the API.
- Updated actor naming conventions to use the `SYSTEM_ACTOR_PATH` instead of the deprecated `SYSTEM_ACTOR_LOCAL_NAME`, enhancing clarity in the API.
- Adjusted tests and documentation to reflect the new naming structure, ensuring accurate references to system actors.
- Improved formatting in code examples for better readability and consistency across the codebase.
…down capabilities

- Implemented double-checked locking in `LazyActorRef` to prevent resolution storms during concurrent cache refreshes.
- Introduced a cancellation token in `LocalActorHandle` for graceful actor shutdown, allowing actors to stop processing messages cleanly.
- Added methods for cleaning up stale node load trackers in `ActorSystem`, improving memory management and preventing leaks.
- Updated actor resolution method to `resolve_address` for clarity and consistency across the API.
- Enhanced documentation and tests to reflect these changes, ensuring better understanding and usability of the actor system.
- Introduced new error variants in `AddressParseError` for path length and reserved namespace violations.
- Implemented validation rules in `ActorPath::new` to enforce maximum path and segment lengths, and to prevent the use of reserved system namespaces.
- Updated `ActorPath::new_system` to bypass namespace checks for internal use.
- Enhanced tests to cover new validation scenarios, ensuring robust error handling for actor paths.
async def run_workflow():
async with runtime():
# Spawn agents with names
researcher = await ResearcherAgent.spawn(name="researcher")

Check warning

Code scanning / CodeQL

Variable defined multiple times Warning

This assignment to 'researcher' is unnecessary as it is
redefined
before this value is used.

Copilot Autofix

AI 26 days ago

In general, to fix “variable defined multiple times” when the first value is never used, you either remove the first assignment entirely or, if its right-hand side has important side effects, keep the call but drop the unused variable binding. The second assignment then becomes the only definition of the variable prior to its use.

For this specific code in comparison_examples/pulsing_research.py, we want to preserve any potential side effects of ResearcherAgent.spawn, AnalystAgent.spawn, and ReporterAgent.spawn while removing the redundant initial bindings. The best minimal-change fix is:

  • On lines 39–41, remove the variable targets (researcher =, analyst =, reporter =) and just call the asynchronous spawn methods with await, discarding the return values.
  • Leave the resolve(...) assignments on lines 44–46 unchanged so that researcher, analyst, and reporter are defined once, right before use.

No new imports or additional methods/definitions are needed; we only adjust these three lines within run_workflow.

Suggested changeset 1
comparison_examples/pulsing_research.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/comparison_examples/pulsing_research.py b/comparison_examples/pulsing_research.py
--- a/comparison_examples/pulsing_research.py
+++ b/comparison_examples/pulsing_research.py
@@ -36,9 +36,9 @@
 async def run_workflow():
     async with runtime():
         # Spawn agents with names
-        researcher = await ResearcherAgent.spawn(name="researcher")
-        analyst = await AnalystAgent.spawn(name="analyst")
-        reporter = await ReporterAgent.spawn(name="reporter")
+        await ResearcherAgent.spawn(name="researcher")
+        await AnalystAgent.spawn(name="analyst")
+        await ReporterAgent.spawn(name="reporter")
 
         # Resolve by name (automatic load balancing)
         researcher = await resolve("researcher")
EOF
@@ -36,9 +36,9 @@
async def run_workflow():
async with runtime():
# Spawn agents with names
researcher = await ResearcherAgent.spawn(name="researcher")
analyst = await AnalystAgent.spawn(name="analyst")
reporter = await ReporterAgent.spawn(name="reporter")
await ResearcherAgent.spawn(name="researcher")
await AnalystAgent.spawn(name="analyst")
await ReporterAgent.spawn(name="reporter")

# Resolve by name (automatic load balancing)
researcher = await resolve("researcher")
Copilot is powered by AI and may make mistakes. Always verify output.
async with runtime():
# Spawn agents with names
researcher = await ResearcherAgent.spawn(name="researcher")
analyst = await AnalystAgent.spawn(name="analyst")

Check warning

Code scanning / CodeQL

Variable defined multiple times Warning

This assignment to 'analyst' is unnecessary as it is
redefined
before this value is used.

Copilot Autofix

AI 26 days ago

In general, to fix “variable defined multiple times” where the first value is never used, you either remove the first assignment entirely (if it has no side effects) or keep the expression for its side effects and drop the unused variable binding.

Here, researcher, analyst, and reporter are each assigned twice: first via *.spawn(...) and then via resolve(...). The second assignments (from resolve) are the ones actually used later in the workflow. The spawn calls, however, may be necessary to create/register the agents, so they should likely remain, but their return values do not need to be stored since they are never used. The minimal, behavior-preserving fix is:

  • Keep the three spawn calls but do not assign their results to variables.
  • Leave the resolve assignments as they are, since those variables are used in the subsequent workflow.

Concretely, in comparison_examples/pulsing_research.py inside run_workflow, lines 39–41:

  • Replace:
    • researcher = await ResearcherAgent.spawn(name="researcher")
    • analyst = await AnalystAgent.spawn(name="analyst")
    • reporter = await ReporterAgent.spawn(name="reporter")
  • With:
    • await ResearcherAgent.spawn(name="researcher")
    • await AnalystAgent.spawn(name="analyst")
    • await ReporterAgent.spawn(name="reporter")

No new methods or imports are needed.

Suggested changeset 1
comparison_examples/pulsing_research.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/comparison_examples/pulsing_research.py b/comparison_examples/pulsing_research.py
--- a/comparison_examples/pulsing_research.py
+++ b/comparison_examples/pulsing_research.py
@@ -36,9 +36,9 @@
 async def run_workflow():
     async with runtime():
         # Spawn agents with names
-        researcher = await ResearcherAgent.spawn(name="researcher")
-        analyst = await AnalystAgent.spawn(name="analyst")
-        reporter = await ReporterAgent.spawn(name="reporter")
+        await ResearcherAgent.spawn(name="researcher")
+        await AnalystAgent.spawn(name="analyst")
+        await ReporterAgent.spawn(name="reporter")
 
         # Resolve by name (automatic load balancing)
         researcher = await resolve("researcher")
EOF
@@ -36,9 +36,9 @@
async def run_workflow():
async with runtime():
# Spawn agents with names
researcher = await ResearcherAgent.spawn(name="researcher")
analyst = await AnalystAgent.spawn(name="analyst")
reporter = await ReporterAgent.spawn(name="reporter")
await ResearcherAgent.spawn(name="researcher")
await AnalystAgent.spawn(name="analyst")
await ReporterAgent.spawn(name="reporter")

# Resolve by name (automatic load balancing)
researcher = await resolve("researcher")
Copilot is powered by AI and may make mistakes. Always verify output.
# Spawn agents with names
researcher = await ResearcherAgent.spawn(name="researcher")
analyst = await AnalystAgent.spawn(name="analyst")
reporter = await ReporterAgent.spawn(name="reporter")

Check warning

Code scanning / CodeQL

Variable defined multiple times Warning

This assignment to 'reporter' is unnecessary as it is
redefined
before this value is used.

Copilot Autofix

AI 26 days ago

In general, to fix “variable defined multiple times” when the first definition is never used, you either remove the earlier assignment entirely or keep the expression as a standalone call if you still need its side effects, without assigning its result to the same variable.

In this file, the safest fix that preserves all possible side effects of spawn is:

  • Keep the three await <Agent>.spawn(name=...) calls.
  • Stop assigning their return values to researcher, analyst, and reporter, since those names are immediately rebound via resolve(...).
  • Optionally, one could remove the spawn calls entirely if the framework guarantees that resolve will implicitly spawn missing agents, but we cannot assume that from the snippet.

Concretely, in comparison_examples/pulsing_research.py:

  • On lines 39–41, remove the left-hand-side variables and the = so that they become simple awaited calls:
    • Change researcher = await ResearcherAgent.spawn(name="researcher") to await ResearcherAgent.spawn(name="researcher"), and similarly for analyst and reporter.
  • Leave the resolve(...) assignments on lines 44–46 unchanged.

No new imports or helper methods are required.

Suggested changeset 1
comparison_examples/pulsing_research.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/comparison_examples/pulsing_research.py b/comparison_examples/pulsing_research.py
--- a/comparison_examples/pulsing_research.py
+++ b/comparison_examples/pulsing_research.py
@@ -36,9 +36,9 @@
 async def run_workflow():
     async with runtime():
         # Spawn agents with names
-        researcher = await ResearcherAgent.spawn(name="researcher")
-        analyst = await AnalystAgent.spawn(name="analyst")
-        reporter = await ReporterAgent.spawn(name="reporter")
+        await ResearcherAgent.spawn(name="researcher")
+        await AnalystAgent.spawn(name="analyst")
+        await ReporterAgent.spawn(name="reporter")
 
         # Resolve by name (automatic load balancing)
         researcher = await resolve("researcher")
EOF
@@ -36,9 +36,9 @@
async def run_workflow():
async with runtime():
# Spawn agents with names
researcher = await ResearcherAgent.spawn(name="researcher")
analyst = await AnalystAgent.spawn(name="analyst")
reporter = await ReporterAgent.spawn(name="reporter")
await ResearcherAgent.spawn(name="researcher")
await AnalystAgent.spawn(name="analyst")
await ReporterAgent.spawn(name="reporter")

# Resolve by name (automatic load balancing)
researcher = await resolve("researcher")
Copilot is powered by AI and may make mistakes. Always verify output.

from pulsing.actor import Actor, StreamMessage, SystemConfig, create_actor_system
import pulsing as pul
from pulsing.actor import Actor, StreamMessage, SystemConfig

Check notice

Code scanning / CodeQL

Unused import Note test

Import of 'SystemConfig' is not used.

Copilot Autofix

AI 26 days ago

To fix an unused import, the general approach is to remove the unused name from the import statement (or delete the entire import if nothing in it is used). This preserves all existing functionality while cleaning up unnecessary dependencies.

In this case, in benchmarks/large_scale_stress_test.py, the line from pulsing.actor import Actor, StreamMessage, SystemConfig should be modified so that it only imports the names that are actually used: Actor and StreamMessage. Specifically, on line 21, remove SystemConfig from the imported names, resulting in from pulsing.actor import Actor, StreamMessage. No other code changes are required, and no additional methods, imports, or definitions are needed, since SystemConfig is not referenced elsewhere in the provided snippet.

Suggested changeset 1
benchmarks/large_scale_stress_test.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/benchmarks/large_scale_stress_test.py b/benchmarks/large_scale_stress_test.py
--- a/benchmarks/large_scale_stress_test.py
+++ b/benchmarks/large_scale_stress_test.py
@@ -18,7 +18,7 @@
 from dataclasses import dataclass, field
 
 import pulsing as pul
-from pulsing.actor import Actor, StreamMessage, SystemConfig
+from pulsing.actor import Actor, StreamMessage
 
 
 # ============================================================================
EOF
@@ -18,7 +18,7 @@
from dataclasses import dataclass, field

import pulsing as pul
from pulsing.actor import Actor, StreamMessage, SystemConfig
from pulsing.actor import Actor, StreamMessage


# ============================================================================
Copilot is powered by AI and may make mistakes. Always verify output.

from pulsing.actor import Actor, StreamMessage, SystemConfig, create_actor_system
import pulsing as pul
from pulsing.actor import Actor, StreamMessage, SystemConfig

Check notice

Code scanning / CodeQL

Unused import Note test

Import of 'SystemConfig' is not used.

Copilot Autofix

AI 26 days ago

To fix an unused import in Python, you remove the unused name from the import statement (or delete the entire import if none of its names are used). This decreases unnecessary dependencies and slightly improves readability.

In this case, we should edit benchmarks/large_scale_stress_test_pulsing_single.py at the import line currently reading from pulsing.actor import Actor, StreamMessage, SystemConfig. The detailed, minimal change is to remove SystemConfig from the imported names, leaving Actor and StreamMessage intact, as both are used by the worker classes shown. No additional methods, imports, or definitions are needed; we are only simplifying the existing import list. The rest of the file’s functionality remains unchanged.

Suggested changeset 1
benchmarks/large_scale_stress_test_pulsing_single.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/benchmarks/large_scale_stress_test_pulsing_single.py b/benchmarks/large_scale_stress_test_pulsing_single.py
--- a/benchmarks/large_scale_stress_test_pulsing_single.py
+++ b/benchmarks/large_scale_stress_test_pulsing_single.py
@@ -17,7 +17,7 @@
 from dataclasses import dataclass, field
 
 import pulsing as pul
-from pulsing.actor import Actor, StreamMessage, SystemConfig
+from pulsing.actor import Actor, StreamMessage
 
 
 # ============================================================================
EOF
@@ -17,7 +17,7 @@
from dataclasses import dataclass, field

import pulsing as pul
from pulsing.actor import Actor, StreamMessage, SystemConfig
from pulsing.actor import Actor, StreamMessage


# ============================================================================
Copilot is powered by AI and may make mistakes. Always verify output.
"""

import pytest
import time

Check notice

Code scanning / CodeQL

Unused import Note test

Import of 'time' is not used.

Copilot Autofix

AI 26 days ago

In general, unused imports should be removed to keep the code clean and avoid unnecessary dependencies. Here, the time module is not referenced anywhere in the visible tests, so the best fix is simply to delete the import time line.

Concretely, in tests/python/apis/ray_compat/test_ray_compat_api.py, remove line 16 containing import time, leaving the pytest and ray imports unchanged. No other code changes, new methods, or additional imports are required, since the tests do not rely on time.

Suggested changeset 1
tests/python/apis/ray_compat/test_ray_compat_api.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/tests/python/apis/ray_compat/test_ray_compat_api.py b/tests/python/apis/ray_compat/test_ray_compat_api.py
--- a/tests/python/apis/ray_compat/test_ray_compat_api.py
+++ b/tests/python/apis/ray_compat/test_ray_compat_api.py
@@ -13,7 +13,6 @@
 """
 
 import pytest
-import time
 
 from pulsing.compat import ray
 
EOF
@@ -13,7 +13,6 @@
"""

import pytest
import time

from pulsing.compat import ray

Copilot is powered by AI and may make mistakes. Always verify output.
# Setup in background loop
async def setup():
from pulsing.actor import SystemConfig, create_actor_system
import pulsing as pul

Check notice

Code scanning / CodeQL

Module is imported more than once Note test

This import of module pulsing is redundant, as it was previously imported
on line 26
.

Copilot Autofix

AI 26 days ago

In general, to fix "module is imported more than once" issues, you remove redundant imports and rely on the existing import, unless you need a different alias or import style. Here, the file already imports pulsing as pul at the top (line 26), and the inner setup coroutine in test_sync_queue_standalone re-imports it with the same alias, which is unnecessary.

The best fix without changing functionality is to delete the inner import pulsing as pul inside the setup coroutine (around line 1013) and keep using pul as defined by the top-level import. The rest of the code in setup already uses pul and write_queue, read_queue exactly as imported at the top of the file, so no further changes are required. We must leave the from pulsing.queue import write_queue, read_queue inside setup intact, because write_queue and read_queue are not directly imported at the top level of the snippet’s function scope; however, even that is arguably redundant given the module-level import, but the static analysis complaint is specifically about pulsing, so we only remove that line.

Suggested changeset 1
tests/python/test_queue.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/tests/python/test_queue.py b/tests/python/test_queue.py
--- a/tests/python/test_queue.py
+++ b/tests/python/test_queue.py
@@ -1010,7 +1010,6 @@
         try:
             # Setup in background loop
             async def setup():
-                import pulsing as pul
                 from pulsing.queue import write_queue, read_queue
 
                 system = await pul.actor_system()
EOF
@@ -1010,7 +1010,6 @@
try:
# Setup in background loop
async def setup():
import pulsing as pul
from pulsing.queue import write_queue, read_queue

system = await pul.actor_system()
Copilot is powered by AI and may make mistakes. Always verify output.

async def setup():
from pulsing.actor import SystemConfig, create_actor_system
import pulsing as pul

Check notice

Code scanning / CodeQL

Module is imported more than once Note test

This import of module pulsing is redundant, as it was previously imported
on line 26
.

Copilot Autofix

AI 26 days ago

To fix the problem, remove the redundant imports inside the setup() coroutine and use the already imported names from the module scope. In general, a single import of a module or symbol per file is sufficient; additional imports of the same module/symbol in inner scopes should be removed unless they serve a specific purpose (e.g., conditional or optional dependency loading).

Concretely, in tests/python/test_queue.py, within test_sync_writer_reader_standalone, there is an inner coroutine:

async def setup():
    import pulsing as pul
    from pulsing.queue import write_queue, read_queue
    ...

You should delete the two import lines inside setup(), leaving the body to use pul, write_queue, and read_queue from the module-level imports defined on lines 26–34. No other code changes are necessary: the names are already available in the function scope as they are defined at module level. This preserves all existing functionality while eliminating redundant imports.

Suggested changeset 1
tests/python/test_queue.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/tests/python/test_queue.py b/tests/python/test_queue.py
--- a/tests/python/test_queue.py
+++ b/tests/python/test_queue.py
@@ -1077,8 +1077,6 @@
         try:
 
             async def setup():
-                import pulsing as pul
-                from pulsing.queue import write_queue, read_queue
 
                 system = await pul.actor_system()
                 writer = await write_queue(
EOF
@@ -1077,8 +1077,6 @@
try:

async def setup():
import pulsing as pul
from pulsing.queue import write_queue, read_queue

system = await pul.actor_system()
writer = await write_queue(
Copilot is powered by AI and may make mistakes. Always verify output.

async def setup():
from pulsing.actor import SystemConfig, create_actor_system
import pulsing as pul

Check notice

Code scanning / CodeQL

Module is imported more than once Note test

This import of module pulsing is redundant, as it was previously imported
on line 26
.

Copilot Autofix

AI 26 days ago

In general, to fix a “module imported more than once” issue in Python, remove the redundant import and rely on the existing import that already brings the module or symbols into scope. If the inner code genuinely needs an import and there is no existing one, move that import to the top of the file; otherwise, just delete the duplicate.

For this specific file, we should remove the inner imports inside the setup coroutine within test_sync_reader_offset_standalone. At the top of tests/python/test_queue.py, the module already imports import pulsing as pul (line 26) and from pulsing.queue import (..., read_queue, write_queue) (lines 27–34). Therefore, inside setup, we can safely delete:

                import pulsing as pul
                from pulsing.queue import write_queue, read_queue

and rely on the already-imported pul, write_queue, and read_queue. No other functional changes are required; the rest of the code will continue to work as before, since names defined by top-level imports are accessible inside nested functions in the same module.

Suggested changeset 1
tests/python/test_queue.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/tests/python/test_queue.py b/tests/python/test_queue.py
--- a/tests/python/test_queue.py
+++ b/tests/python/test_queue.py
@@ -1144,8 +1144,6 @@
         try:
 
             async def setup():
-                import pulsing as pul
-                from pulsing.queue import write_queue, read_queue
 
                 system = await pul.actor_system()
                 writer = await write_queue(
EOF
@@ -1144,8 +1144,6 @@
try:

async def setup():
import pulsing as pul
from pulsing.queue import write_queue, read_queue

system = await pul.actor_system()
writer = await write_queue(
Copilot is powered by AI and may make mistakes. Always verify output.
assert count == 0

# Wait for slow operation to complete
await slow_task

Check notice

Code scanning / CodeQL

Statement has no effect Note test

This statement has no effect.

Copilot Autofix

AI 26 days ago

In general, to fix a “statement has no effect” issue where an awaited coroutine result is intentionally unused, either capture the result in a variable (optionally asserting/inspecting it) or explicitly assign it to _ to signal that it is intentionally ignored. This makes the side effect of “waiting for completion” explicit and resolves the static analysis warning.

For this specific test in tests/python/test_remote_decorator.py, the best minimal change without altering behavior is to bind the awaited value of slow_task to a variable. Optionally, we can assert on it, but that’s not required to preserve existing behavior. The key is to show that the awaited expression is being used.

Concretely:

  • In test_async_method_does_not_block_actor, at line 228, change await slow_task to something like result = await slow_task. This preserves all functionality (we still wait for completion), makes the use of the expression explicit, and eliminates the “no effect” warning. No new imports or helper methods are required.
Suggested changeset 1
tests/python/test_remote_decorator.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/tests/python/test_remote_decorator.py b/tests/python/test_remote_decorator.py
--- a/tests/python/test_remote_decorator.py
+++ b/tests/python/test_remote_decorator.py
@@ -225,7 +225,7 @@
         assert count == 0
 
         # Wait for slow operation to complete
-        await slow_task
+        result = await slow_task
         await asyncio.sleep(0.01)  # Let the count update propagate
 
         count = await service.get_call_count()
EOF
@@ -225,7 +225,7 @@
assert count == 0

# Wait for slow operation to complete
await slow_task
result = await slow_task
await asyncio.sleep(0.01) # Let the count update propagate

count = await service.get_call_count()
Copilot is powered by AI and may make mistakes. Always verify output.
…ookup

- Changed local actor storage from a string-based index to a u64 local_id for O(1) lookups, enhancing performance.
- Introduced a mapping from actor names to local_ids to facilitate name-based lookups.
- Updated methods for finding and managing actors to utilize the new indexing scheme, ensuring consistency and efficiency.
- Enhanced documentation and tests to reflect the changes in actor management and lookup behavior.
- Updated the `stop_with_reason` method in `ActorSystem` to support actor names without a "/" by attempting to resolve them with an "actors/" prefix for better compatibility with Python API conventions.
- Improved logging to reflect the actual name used for stopping the actor, ensuring accurate debugging information.
- Enhanced documentation to clarify the new behavior and its implications for actor management.
@reiase reiase merged commit c6b647e into main Jan 24, 2026
12 of 13 checks passed
@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 60.31746% with 75 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
python/pulsing/actors/router.py 0.00% 31 Missing ⚠️
python/pulsing/actor/remote.py 77.04% 14 Missing ⚠️
python/pulsing/actor/helpers.py 12.50% 7 Missing ⚠️
python/pulsing/autogen/runtime.py 0.00% 7 Missing ⚠️
python/pulsing/langgraph/executor.py 0.00% 7 Missing ⚠️
python/pulsing/langgraph/wrapper.py 0.00% 6 Missing ⚠️
python/pulsing/__init__.py 94.87% 2 Missing ⚠️
python/pulsing/actors/__init__.py 0.00% 1 Missing ⚠️
Files with missing lines Coverage Δ
python/pulsing/actor/__init__.py 85.71% <100.00%> (-0.57%) ⬇️
python/pulsing/cli/__main__.py 76.59% <ø> (ø)
python/pulsing/cli/inspect.py 52.94% <100.00%> (ø)
python/pulsing/compat/ray.py 89.02% <100.00%> (+2.86%) ⬆️
python/pulsing/queue/__init__.py 100.00% <100.00%> (ø)
python/pulsing/queue/manager.py 67.08% <100.00%> (-0.42%) ⬇️
python/pulsing/queue/queue.py 90.58% <100.00%> (ø)
python/pulsing/topic/topic.py 90.47% <ø> (ø)
python/pulsing/actors/__init__.py 0.00% <0.00%> (ø)
python/pulsing/__init__.py 95.00% <94.87%> (-5.00%) ⬇️
... and 6 more

... and 51 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments