# Path: creamas/logging.py
# class ObjectLogger():
#     '''Base logger for Creamas objects. *Not* a subclass of
#     :class:`logging.Logger`.
# 
#     Generates one file for each attribute to be logged.
#     '''
#     def __init__(self, obj, folder, add_name=False, init=True,
#                  log_level=logging.DEBUG):
#         '''Create new logger instance for *obj* in *folder*. If *add_name*
#         is ``True``, creates subfolder carrying :attr:`obj.name` to *folder*.
#         If *init* is true, sets logger's level to *log_level* and adds basic
#         *StreamHandler* to the logger.
#         '''
#         self._obj = obj
#         self._folder = folder
# 
#         if add_name:
#             import re
#             a = re.split("[:/]", self._obj.name)
#             fold = "_".join([i for i in a if len(i) > 0])
#             obj_folder = os.path.join(self._folder, fold)
#             if not os.path.exists(obj_folder):
#                 os.makedirs(obj_folder)
#             self._folder = obj_folder
# 
#         self.logger = logging.getLogger("creamas.{}".format(self._obj.name))
#         if len(self.logger.handlers) == 0:
#             self.logger.addHandler(logging.NullHandler())
#             if init:
#                 self.logger.setLevel(log_level)
#                 ch = logging.StreamHandler()
#                 ch.setLevel(log_level)
#                 self.logger.addHandler(ch)
# 
#         self.DEBUG = logging.DEBUG
#         self.INFO = logging.INFO
#         self.ERROR = logging.ERROR
#         self.CRITICAL = logging.CRITICAL
#         self.WARNING = logging.WARNING
# 
#     @property
#     def obj(self):
#         '''Object this logger belongs to. Object has to have **name**
#         attribute.'''
#         return self._obj
# 
#     @property
#     def folder(self):
#         '''Root logging folder for this logger.'''
#         return self._folder
# 
#     def add_handler(self, handler):
#         '''Add handler to the logger.
#         '''
#         self.logger.addHandler(handler)
# 
#     def get_file(self, attr_name):
#         '''Return absolute path to logging file for obj's attribute.'''
#         return os.path.abspath(os.path.join(self.folder, "{}.log"
#                                             .format(attr_name)))
# 
#     def log_attr(self, level, attr_name):
#         '''Log attribute to file and pass the message to underlying logger.
# 
#         :param int level: logging level
#         :param str attr_name: attribute's name to be logged
#         '''
#         msg = self.write(attr_name)
#         self.log(level, msg)
# 
#     def log(self, level, msg):
#         self.logger.log(level, "{}: {}".format(self.obj.name, msg))
#         sys.stdout.flush()
# 
#     def write(self, attr_name, prefix=None):
#         '''Write attribute's value to a file.
# 
#         :param str attr_name:
#             Attribute's name to be logged
# 
#         :param str prefix:
#             Optional. Attribute's name that is prefixed to logging message,
#             defaults to ``None``.
# 
#         :returns: message written to file
#         :rtype: str
#         '''
#         if self._folder is None:
#             return
# 
#         separator = "\t"
#         attr = getattr(self.obj, attr_name)
#         if hasattr(attr, '__iter__'):
#             msg = separator.join([str(e) for e in attr])
#         else:
#             msg = str(attr)
# 
#         if prefix is not None:
#             msg = "{}\t{}".format(getattr(self.obj, prefix), msg)
# 
#         path = self.get_file(attr_name)
#         with open(path, 'a') as f:
#             f.write("{}\n".format(msg))
# 
#         return msg
# 
# Path: creamas/util.py
# def run_or_coro(task, as_coro, loop=None):
#     """A shorthand to run the task/future or return it as is.
# 
#     :param task:
#         Optional. Task or Future which is run until complete. If parameter is
#         ``None`` runs the event loop forever.
#     :param bool as_coro:
#         If ``True`` returns the given task as is, otherwise runs it in the
#         event loop.
#     :param loop:
#         Optional. Event loop to use. If the parameter is ``None`` uses
#         asyncio's base event loop.
#     """
#     if as_coro:
#         return task
#     else:
#         return run(task, loop)
# 
# Path: creamas/serializers.py
# def get_serializers():
#     """Get all basic serializers defined in this module as a list.
#     """
#     return [artifact_serializer, array_serializer, ndarray_serializer]


import asyncio
import logging
            import setproctitle as spt
from random import choice, shuffle
from aiomas import Container
from creamas.logging import ObjectLogger
from creamas.util import run_or_coro
from creamas.serializers import get_serializers
This module holds ``Enviroment``-class, an universe where the agents live.
Environment holds methods for inter-agent communication and some utilities that
are usually needed when implementing creative multi-agent systems.

All implementations should subclass ``Environment`` in order to provide basic
functionality for the system to operate.

Environments are used by defining their address at the instantation time, and
adding agents to their container.
"""





__all__ = ['Environment']


class Environment(Container):
    """Base environment class inherited from :py:class:`aiomas.Container`.
    """
    @classmethod
    def create(cls, *args, **kwargs):
        """Create a new environment, see :py:func:`~aiomas.Container.create` for details.

        If ``extra_serializers`` keyword argument is None, serializers returned by
        :func:`~creamas.serializers.get_serializers` are added to it.
        """
        extra_ser = kwargs.pop('extra_serializers', None)
        if extra_ser is None:

# Path: creamas/logging.py
# class ObjectLogger():
#     '''Base logger for Creamas objects. *Not* a subclass of
#     :class:`logging.Logger`.
# 
#     Generates one file for each attribute to be logged.
#     '''
#     def __init__(self, obj, folder, add_name=False, init=True,
#                  log_level=logging.DEBUG):
#         '''Create new logger instance for *obj* in *folder*. If *add_name*
#         is ``True``, creates subfolder carrying :attr:`obj.name` to *folder*.
#         If *init* is true, sets logger's level to *log_level* and adds basic
#         *StreamHandler* to the logger.
#         '''
#         self._obj = obj
#         self._folder = folder
# 
#         if add_name:
#             import re
#             a = re.split("[:/]", self._obj.name)
#             fold = "_".join([i for i in a if len(i) > 0])
#             obj_folder = os.path.join(self._folder, fold)
#             if not os.path.exists(obj_folder):
#                 os.makedirs(obj_folder)
#             self._folder = obj_folder
# 
#         self.logger = logging.getLogger("creamas.{}".format(self._obj.name))
#         if len(self.logger.handlers) == 0:
#             self.logger.addHandler(logging.NullHandler())
#             if init:
#                 self.logger.setLevel(log_level)
#                 ch = logging.StreamHandler()
#                 ch.setLevel(log_level)
#                 self.logger.addHandler(ch)
# 
#         self.DEBUG = logging.DEBUG
#         self.INFO = logging.INFO
#         self.ERROR = logging.ERROR
#         self.CRITICAL = logging.CRITICAL
#         self.WARNING = logging.WARNING
# 
#     @property
#     def obj(self):
#         '''Object this logger belongs to. Object has to have **name**
#         attribute.'''
#         return self._obj
# 
#     @property
#     def folder(self):
#         '''Root logging folder for this logger.'''
#         return self._folder
# 
#     def add_handler(self, handler):
#         '''Add handler to the logger.
#         '''
#         self.logger.addHandler(handler)
# 
#     def get_file(self, attr_name):
#         '''Return absolute path to logging file for obj's attribute.'''
#         return os.path.abspath(os.path.join(self.folder, "{}.log"
#                                             .format(attr_name)))
# 
#     def log_attr(self, level, attr_name):
#         '''Log attribute to file and pass the message to underlying logger.
# 
#         :param int level: logging level
#         :param str attr_name: attribute's name to be logged
#         '''
#         msg = self.write(attr_name)
#         self.log(level, msg)
# 
#     def log(self, level, msg):
#         self.logger.log(level, "{}: {}".format(self.obj.name, msg))
#         sys.stdout.flush()
# 
#     def write(self, attr_name, prefix=None):
#         '''Write attribute's value to a file.
# 
#         :param str attr_name:
#             Attribute's name to be logged
# 
#         :param str prefix:
#             Optional. Attribute's name that is prefixed to logging message,
#             defaults to ``None``.
# 
#         :returns: message written to file
#         :rtype: str
#         '''
#         if self._folder is None:
#             return
# 
#         separator = "\t"
#         attr = getattr(self.obj, attr_name)
#         if hasattr(attr, '__iter__'):
#             msg = separator.join([str(e) for e in attr])
#         else:
#             msg = str(attr)
# 
#         if prefix is not None:
#             msg = "{}\t{}".format(getattr(self.obj, prefix), msg)
# 
#         path = self.get_file(attr_name)
#         with open(path, 'a') as f:
#             f.write("{}\n".format(msg))
# 
#         return msg
# 
# Path: creamas/util.py
# def run_or_coro(task, as_coro, loop=None):
#     """A shorthand to run the task/future or return it as is.
# 
#     :param task:
#         Optional. Task or Future which is run until complete. If parameter is
#         ``None`` runs the event loop forever.
#     :param bool as_coro:
#         If ``True`` returns the given task as is, otherwise runs it in the
#         event loop.
#     :param loop:
#         Optional. Event loop to use. If the parameter is ``None`` uses
#         asyncio's base event loop.
#     """
#     if as_coro:
#         return task
#     else:
#         return run(task, loop)
# 
# Path: creamas/serializers.py
# def get_serializers():
#     """Get all basic serializers defined in this module as a list.
#     """
#     return [artifact_serializer, array_serializer, ndarray_serializer]


# Path: creamas/core/environment.py
import asyncio
import logging
            import setproctitle as spt
from random import choice, shuffle
from aiomas import Container
from creamas.logging import ObjectLogger
from creamas.util import run_or_coro
from creamas.serializers import get_serializers

This module holds ``Enviroment``-class, an universe where the agents live.
Environment holds methods for inter-agent communication and some utilities that
are usually needed when implementing creative multi-agent systems.

All implementations should subclass ``Environment`` in order to provide basic
functionality for the system to operate.

Environments are used by defining their address at the instantation time, and
adding agents to their container.
"""





__all__ = ['Environment']


class Environment(Container):
    """Base environment class inherited from :py:class:`aiomas.Container`.
    """
    @classmethod
    def create(cls, *args, **kwargs):
        """Create a new environment, see :py:func:`~aiomas.Container.create` for details.

        If ``extra_serializers`` keyword argument is None, serializers returned by
        :func:`~creamas.serializers.get_serializers` are added to it.
        """
        extra_ser = kwargs.pop('extra_serializers', None)
        if extra_ser is None:

            extra_ser = get_serializers()