From b58889f6253cb71511b6da137e20bd39750050f8 Mon Sep 17 00:00:00 2001 From: goodboy Date: Mon, 24 Aug 2026 23:49:09 -0400 Subject: [PATCH] Move `NamespacePath` ref test into `tests.msg` The retained-reference regression exercised generic message pointer behavior but lived in the one-shot actor API suite and combined an unrelated public trampoline alias assertion. Move the pointer regression into a focused message-layer test module and retain the alias contract as its own `to_actor` API test. Review: PR #481 (goodboy) https://github.com/goodboy/tractor/pull/481#pullrequestreview-5012942328 (this patch was generated in some part by `opencode` using `gpt-5.6-sol` (`openai`)) --- tests/msg/test_namespace_path.py | 43 ++++++++++++++++++++++++++++++++ tests/test_to_actor.py | 29 ++++----------------- 2 files changed, 48 insertions(+), 24 deletions(-) create mode 100644 tests/msg/test_namespace_path.py diff --git a/tests/msg/test_namespace_path.py b/tests/msg/test_namespace_path.py new file mode 100644 index 00000000..7dee21eb --- /dev/null +++ b/tests/msg/test_namespace_path.py @@ -0,0 +1,43 @@ +''' +`NamespacePath` Python-object reference tests. + +''' +import pytest + +from tractor.msg import ptr as msgptr +from tractor.msg.ptr import NamespacePath + + +def example_target() -> None: + ''' + Provide a module-addressable reference for pointer tests. + + ''' + + +def test_retains_target_ref( + monkeypatch: pytest.MonkeyPatch, +) -> None: + ''' + Reuse a retained target ref when splitting its namespace path. + + `NamespacePath.from_ref()` previously discarded `example_target`, + so `to_tuple()` imported and resolved the just-created string again. + Replacing `resolve_name()` with a failure proves the retained ref + supplies the tuple without a redundant lookup. + + ''' + target = NamespacePath.from_ref(example_target) + + def fail_resolve(name: str) -> object: + raise AssertionError(f'unexpected lookup for {name!r}') + + monkeypatch.setattr( + msgptr, + 'resolve_name', + fail_resolve, + ) + assert target.to_tuple() == ( + example_target.__module__, + example_target.__name__, + ) diff --git a/tests/test_to_actor.py b/tests/test_to_actor.py index 6970006f..599d6dbf 100644 --- a/tests/test_to_actor.py +++ b/tests/test_to_actor.py @@ -20,7 +20,6 @@ from tractor import ( ) from tractor._testing import tractor_test from tractor._exceptions import ActorTooSlowError -from tractor.msg import ptr as msgptr from tractor.msg.ptr import NamespacePath from tractor.spawn import _mp as mp_spawn from tractor.to_actor import _api as to_actor_api @@ -89,33 +88,15 @@ async def collect_call( return args, kwargs -def test_namespace_path_retains_target_ref( - monkeypatch: pytest.MonkeyPatch, -): +def test_public_module_alias() -> None: ''' - Reuse the client-side target ref when splitting its namespace path. + Keep the public trampoline alias separate from its private module. - `NamespacePath.from_ref()` previously discarded `add_one`, so - `to_tuple()` imported and resolved the just-created string again. - Replacing `resolve_name()` with a failure proves the retained ref - supplies the tuple without a redundant lookup. The public module - alias assertion also keeps internal `_api.__name__` authoritative. + Callers use `to_actor.MODULE` to configure an existing actor's RPC + allowlist, while `_api.__name__` remains the authoritative module + path and does not re-export the alias internally. ''' - target = NamespacePath.from_ref(add_one) - - def fail_resolve(name: str) -> object: - raise AssertionError(f'unexpected lookup for {name!r}') - - monkeypatch.setattr( - msgptr, - 'resolve_name', - fail_resolve, - ) - assert target.to_tuple() == ( - add_one.__module__, - add_one.__name__, - ) assert to_actor.MODULE == to_actor_api.__name__ assert not hasattr(to_actor_api, 'MODULE')