Skip to content
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

Bugfix in agentset to handle addition and removal correctly #1960

Merged
merged 3 commits into from
Jan 13, 2024

Conversation

quaquel
Copy link
Member

@quaquel quaquel commented Jan 13, 2024

Fix for #1959 and additional unittests that test specifically on this

Copy link

codecov bot commented Jan 13, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (36da145) 79.45% compared to head (495d9c3) 79.45%.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1960   +/-   ##
=======================================
  Coverage   79.45%   79.45%           
=======================================
  Files          15       15           
  Lines        1285     1285           
  Branches      285      285           
=======================================
  Hits         1021     1021           
  Misses        225      225           
  Partials       39       39           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

mesa/agent.py Outdated Show resolved Hide resolved
mesa/agent.py Outdated
@@ -251,7 +251,8 @@ def do(
Returns:
AgentSet | list[Any]: The results of the method calls if return_results is True, otherwise the AgentSet itself.
"""
res = [getattr(agent, method_name)(*args, **kwargs) for agent in self._agents]
# we iterate over the actual weakref keys and check if weakref is alive before calling the method
res = [getattr(agent(), method_name)(*args, **kwargs) for agent in self._agents.keyrefs() if agent()]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be clearer to name agent_ref instead of agent. Because the call agent_ref() is the actual agent themselves.

@Corvince
Copy link
Contributor

pre-commit.ci autofix

Copy link
Contributor

@Corvince Corvince left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems good to me! Thanks for investigating. I must admit I haven't wrapped my head around weakrefs completely. This error went a bit above my head

@Corvince Corvince merged commit 9819927 into projectmesa:main Jan 13, 2024
13 checks passed
@quaquel
Copy link
Member Author

quaquel commented Jan 13, 2024

It was a bit of a learning experience for me as well. I am familiar with weakrefs from Java so that helped.

By the way, the code could have been even more elegant by using the walrus operator (first time I came across a reason to use it).

res = [getattr(agent, method_name)(*args, **kwargs) for agentref in self._agents.keyrefs() if (agent := agentref())]

@Corvince
Copy link
Contributor

By the way, the code could have been even more elegant by using the walrus operator (first time I came across a reason to use it).

That's true! I actually stumbled a bit while reading the code thinking about agentref being executed twice. But I didn't think of the walrus! But it's actually used in the space code for a similar list comprehension in get_cell_list_contents

@quaquel
Copy link
Member Author

quaquel commented Jan 13, 2024

Should this result in a 2.2.1 release?

@EwoutH
Copy link
Member

EwoutH commented Jan 13, 2024

In my opinion, yes.

@EwoutH
Copy link
Member

EwoutH commented Jan 13, 2024

To inform you, we're currently blocked on our PyPI pipeline being broken (see #1962). I was supposed to meet with @jackiekazil to resolve that issue, but I unfortunately missed that meeting. Working on it.

@Corvince
Copy link
Contributor

There was another "bug" we should fix first imho. Scheduler.agents_by_type changed its return type, which is a breaking change. This should be reverted for 2.2 and then we should release a bugfix release.

@quaquel
Copy link
Member Author

quaquel commented Jan 13, 2024

There was another "bug" we should fix first imho. Scheduler.agents_by_type changed its return type, which is a breaking change. This should be reverted for 2.2 and then we should release a bugfix release.

To make sure I understand: RandomActivationByType.agents_by_type is now a [type, AgentSet] but it should have been [type, [agent][int]]? So, a simple property solution is all that is needed, and moving the current self.agents_by_type to self._agents_by_type.

@property
def agents_by_type(self):
    agentsbytype = defauldict(dict)
    for k, v in self._agents_by_type.items():
        agentsbytype[k] = {agent:agent.unique_id for agent in v}

    return agentsbytype

@Corvince
Copy link
Contributor

Yes, but you might add a warning that the return type is deprecated and mesa 3.0 will return an Agentset (which imho makes much more sense)

@EwoutH
Copy link
Member

EwoutH commented Jan 13, 2024

add a warning that the return type is deprecated and mesa 3.0 will return an Agentset

Agreed

@EwoutH EwoutH added the bug Release notes label label Jan 16, 2024
@quaquel quaquel deleted the agentset_bugfix branch October 25, 2024 06:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Release notes label
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants