Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/source/_static/ev_soc_netpower.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/source/_static/ev_trajectories.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
author = "mango team"

# The full version, including alpha/beta/rc tags
version = release = "2.2.0"
version = release = "2.2.1"


# -- General configuration ---------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion mango/agent/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ def addr(self):
Returns:
_type_: AgentAddress
"""
if self.context._container is None:
if self.context is None or self.context._container is None:
return None
return AgentAddress(self.context.addr, self.aid)

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "mango-agents"
version = "2.2.0"
version = "2.2.1"
authors = [
{ name="mango Team", email="mango@offis.de" },
]
Expand Down
61 changes: 61 additions & 0 deletions tests/unit_tests/role/test_role_agent_without_container.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from mango.agent.role import Role, RoleAgent
from mango.express.api import agent_composed_of


class AddrAccessingRole(Role):
"""Role that reads self.context.addr during setup — the crash site."""

def __init__(self):
super().__init__()
self.setup_called = False
self.addr_at_setup = "NOT_SET"

def setup(self) -> None:
self.setup_called = True
self.addr_at_setup = self.context.addr


def test_add_role_before_registration_calls_setup():
# GIVEN an agent that has not been registered with any container yet
agent = RoleAgent()
role = AddrAccessingRole()

# WHEN adding a role whose setup() accesses context.addr
# THEN setup() is called immediately, no AttributeError is raised, and addr is None
agent.add_role(role)

assert role.setup_called
assert role.addr_at_setup is None


class CounterModel:
def __init__(self):
self.count = 0


class IncrementRole(Role):
def setup(self):
model = self.context.get_or_create_model(CounterModel)
model.count += 1
self.context.update(model)


class DisplayRole(Role):
def setup(self):
self.context.subscribe_model(self, CounterModel)
self.last_count = 0

def on_change_model(self, model):
self.last_count = model.count


def test_agent_composed_of_initializes_and_updates_synchronously():
# GIVEN two roles that coordinate via shared models during setup()
display = DisplayRole()
increment = IncrementRole()

# WHEN creating a composed agent (which calls add_role() and thus setup() on roles)
agent = agent_composed_of(display, increment)

# THEN setup() ran immediately and display role got notified of increment during setup()
assert display.last_count == 1
Loading