diff --git a/CHANGELOG.md b/CHANGELOG.md index ca98951..0eacd81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.14.4] +### Fixed +* Bug in `agent.get_agents()` when `state_id` is passed as a string. The tests have been modified accordingly. +## [0.14.3] +### Fixed +* Incompatibility with py3.3-3.6 due to ModuleNotFoundError and TypeError in DryRunner ## [0.14.2] ### Fixed * Output path for exporters is now soil_output diff --git a/examples/pubcrawl/pubcrawl.py b/examples/pubcrawl/pubcrawl.py index 27b1eaf..6c8d632 100644 --- a/examples/pubcrawl/pubcrawl.py +++ b/examples/pubcrawl/pubcrawl.py @@ -59,7 +59,7 @@ class Patron(FSM): 2) Look for a bar where the agent and other agents in the same group can get in. 3) While in the bar, patrons only drink, until they get drunk and taken home. ''' - level = logging.INFO + level = logging.DEBUG defaults = { 'pub': None, @@ -113,7 +113,8 @@ class Patron(FSM): @state def at_home(self): '''The end''' - self.debug('Life sucks. I\'m home!') + others = self.get_agents(state_id=Patron.at_home.id, limit_neighbors=True) + self.debug('I\'m home. Just like {} of my friends'.format(len(others))) def drink(self): self['pints'] += 1 diff --git a/soil/VERSION b/soil/VERSION index e867cc2..3393b5f 100644 --- a/soil/VERSION +++ b/soil/VERSION @@ -1 +1 @@ -0.14.2 +0.14.4 diff --git a/soil/agents/__init__.py b/soil/agents/__init__.py index 2584b77..1856b27 100644 --- a/soil/agents/__init__.py +++ b/soil/agents/__init__.py @@ -171,7 +171,7 @@ class BaseAgent(nxsim.BaseAgent): def info(self, *args, **kwargs): return self.log(*args, level=logging.INFO, **kwargs) - + def __getstate__(self): ''' Serializing an agent will lose all its running information (you cannot @@ -476,11 +476,8 @@ class Geo(NetworkAgent): def select(agents, state_id=None, agent_type=None, ignore=None, iterator=False, **kwargs): - if state_id is not None: - try: - state_id = tuple(state_id) - except TypeError: - state_id = tuple([state_id]) + if state_id is not None and not isinstance(state_id, (tuple, list)): + state_id = tuple([state_id]) if agent_type is not None: try: agent_type = tuple(agent_type) diff --git a/soil/serialization.py b/soil/serialization.py index fca71c5..49df7f3 100644 --- a/soil/serialization.py +++ b/soil/serialization.py @@ -186,7 +186,7 @@ def deserializer(type_, known_modules=[]): module = importlib.import_module(modname) cls = getattr(module, tname) return getattr(cls, 'deserialize', cls) - except (ModuleNotFoundError, AttributeError) as ex: + except (ImportError, AttributeError) as ex: errors.append((modname, tname, ex)) raise Exception('Could not find type {}. Tried: {}'.format(type_, errors)) diff --git a/soil/utils.py b/soil/utils.py index a292a50..c3a5caf 100644 --- a/soil/utils.py +++ b/soil/utils.py @@ -46,5 +46,5 @@ def safe_open(path, mode='r', backup=True, **kwargs): def open_or_reuse(f, *args, **kwargs): try: return safe_open(f, *args, **kwargs) - except TypeError: + except (AttributeError, TypeError): return f diff --git a/tests/test_main.py b/tests/test_main.py index 481b08c..cf3ddc9 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -16,10 +16,15 @@ ROOT = os.path.abspath(os.path.dirname(__file__)) EXAMPLES = join(ROOT, '..', 'examples') -class CustomAgent(agents.BaseAgent): - def step(self): - self.state['neighbors'] = self.count_agents(state_id=0, +class CustomAgent(agents.FSM): + @agents.default_state + @agents.state + def normal(self): + self.state['neighbors'] = self.count_agents(state_id='normal', limit_neighbors=True) + @agents.state + def unreachable(self): + return class TestMain(TestCase): @@ -134,8 +139,7 @@ class TestMain(TestCase): }, 'network_agents': [{ 'agent_type': CustomAgent, - 'weight': 1, - 'state': {'id': 0} + 'weight': 1 }], 'max_time': 10, @@ -145,6 +149,9 @@ class TestMain(TestCase): s = simulation.from_config(config) env = s.run_simulation(dry_run=True)[0] assert env.get_agent(0).state['neighbors'] == 1 + assert env.get_agent(0).state['neighbors'] == 1 + assert env.get_agent(1).count_agents(state_id='normal') == 2 + assert env.get_agent(1).count_agents(state_id='normal', limit_neighbors=True) == 1 def test_torvalds_example(self): """A complete example from a documentation should work."""