<commit_before># -*- coding: utf-8 -*-

# Copyright (c) 2015-2016 Ericsson AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import wrapt
import functools
import time
from calvin.utilities import calvinuuid
from calvin.utilities.security import Security
from calvin.actor import actorport
from calvin.utilities.calvinlogger import get_logger
from calvin.utilities.utils import enum
from calvin.runtime.north.calvin_token import Token, ExceptionToken
# from calvin.runtime.north import calvincontrol
# from calvin.runtime.north import metering
from calvin.runtime.north.replicationmanager import ReplicationData
import calvin.requests.calvinresponse as response
from calvin.runtime.south.plugins.async import async
from calvin.runtime.north.plugins.authorization_checks import check_authorization_plugin_list
from calvin.utilities.calvin_callback import CalvinCB
from calvin.csparser.port_property_syntax import get_port_property_capabilities, get_port_property_runtime

_log = get_logger(__name__)


# Tests in test_manage_decorator.py
def manage(include=None, exclude=None):

    """
    Decorator for Actor::init() providing automatic management of state variables.
    Usage:
        @manage()                     # Manage every instance variable known upon completion of __init__
        @manage(include = [])         # Manage nothing
        @manage(include = [foo, bar]) # Manage self.foo and self.bar only. Equivalent to @manage([foo, bar])
        @manage(exclude = [foo, bar]) # Manage everything except self.foo and self.bar
        @manage(exclude = [])         # Same as @manage()
        @manage(<list>)               # Same as @manage(include = <list>)

    N.B. If include and exclude are both present, exclude will be disregarded.

    """

    if include and type(include) is not list or exclude and type(exclude) is not list:
        raise Exception("@manage decorator: Must use list as argument")

    include = set(include) if include else set()
    exclude = set(exclude) if exclude else set()

    # Using wrapt since we need to preserve the signature of the wrapped signature.
    # See http://wrapt.readthedocs.org/en/latest/index.html
    # FIXME: Since we use wrapt here, we might as well use it in guard and condition too.
    @wrapt.decorator
    def wrapper(wrapped, instance, args, kwargs):
        # Exclude the instance variables added by superclasses
        exclude.update(instance.__dict__)
        x = wrapped(*args, **kwargs)
        if not include:
            # include set not given, so construct the implicit include set
            include.update(instance.__dict__)
            include.remove('_managed')
            include.difference_update(exclude)
        instance._managed.update(include)
        return x
    return wrapper


def condition(action_input=[], action_output=[]):
    """
    Decorator condition specifies the required input data and output space.
    Both parameters are lists of port names
    Return value is an ActionResult object

    FIXME:
    - Modify ActionResult to specify how many tokens were read/written from/to each port
      E.g. ActionResult.tokens_consumed/produced are dicts: {'port1':4, 'port2':1, ...}
      Since reading is done in the wrapper, tokens_consumed is fixed and given by action_input.
      The action fills in tokens_produced and the wrapper uses that info when writing to ports.
    - We can keep the @condition syntax by making the change in the normalize step below.
    """
    # #
    # # Normalize argument list (fill in a default repeat of 1 if not stated)
    # #
    #
    # action_input = [p if isinstance(p, (list, tuple)) else (p, 1) for p in action_input]
    # action_output = [p if isinstance(p, (list, tuple)) else (p, 1) for p in action_output]
    # contract_output = tuple(n for _, n in action_output)
    tokens_produced = len(action_output)
    tokens_consumed = len(action_input)

    def wrap(action_method):

        @functools.wraps(action_method)
        def condition_wrapper(self):
            #
            # Check if input ports have enough tokens. Note that all([]) evaluates to True
            #
            input_ok = all([self.inports[portname].tokens_available(1) for portname in action_input])
            #
            # Check if output port have enough free token slots
            #
            output_ok = all([self.outports[portname].tokens_available(1) for portname in action_output])

            if not input_ok or not output_ok:
                _log.debug("\t%s.%s Fired:N In:%s, Out:%s, Guard:X" % (self._name, action_method.__name__, "Y" if input_ok else "N", "Y" if output_ok else "N"))
                return ActionResult(did_fire=False, input_ok=input_ok, output_ok=output_ok)
            #
            # Build the arguments for the action from the input port(s)
            #
            args = []
            ex = {}
            for portname in action_input:
                port = self.inports[portname]
                    token = port.peek_token()
                    is_exception = isinstance(token, ExceptionToken)
                    if is_exception:
                    ex.setdefault(portname, []).append(0)
                args.append(token if is_exception else token.value)

            #
            # Check for exceptional conditions
            #
            if ex:
                action_result = self.exception_handler(action_method, args, {'exceptions': ex})
            else:
                #
                # Perform the action (N.B. the method may be wrapped in a guard)
                #
                action_result = action_method(self, *args)
                # guard_str = "X" if action_result.guard_ok is None else ("Y" if action_result.guard_ok else "N")
                # _log.debug("\t%s.%s Fired:%s In:Y, Out:Y, Guard:%s" % (
                #     self._name, action_method.__name__, "Y" if action_result.did_fire else "N", guard_str))<commit_msg>Whitespace change.<commit_after># -*- coding: utf-8 -*-

# Copyright (c) 2015-2016 Ericsson AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import wrapt
import functools
import time
from calvin.utilities import calvinuuid
from calvin.utilities.security import Security
from calvin.actor import actorport
from calvin.utilities.calvinlogger import get_logger
from calvin.utilities.utils import enum
from calvin.runtime.north.calvin_token import Token, ExceptionToken
# from calvin.runtime.north import calvincontrol
# from calvin.runtime.north import metering
from calvin.runtime.north.replicationmanager import ReplicationData
import calvin.requests.calvinresponse as response
from calvin.runtime.south.plugins.async import async
from calvin.runtime.north.plugins.authorization_checks import check_authorization_plugin_list
from calvin.utilities.calvin_callback import CalvinCB
from calvin.csparser.port_property_syntax import get_port_property_capabilities, get_port_property_runtime

_log = get_logger(__name__)


# Tests in test_manage_decorator.py
def manage(include=None, exclude=None):

    """
    Decorator for Actor::init() providing automatic management of state variables.
    Usage:
        @manage()                     # Manage every instance variable known upon completion of __init__
        @manage(include = [])         # Manage nothing
        @manage(include = [foo, bar]) # Manage self.foo and self.bar only. Equivalent to @manage([foo, bar])
        @manage(exclude = [foo, bar]) # Manage everything except self.foo and self.bar
        @manage(exclude = [])         # Same as @manage()
        @manage(<list>)               # Same as @manage(include = <list>)

    N.B. If include and exclude are both present, exclude will be disregarded.

    """

    if include and type(include) is not list or exclude and type(exclude) is not list:
        raise Exception("@manage decorator: Must use list as argument")

    include = set(include) if include else set()
    exclude = set(exclude) if exclude else set()

    # Using wrapt since we need to preserve the signature of the wrapped signature.
    # See http://wrapt.readthedocs.org/en/latest/index.html
    # FIXME: Since we use wrapt here, we might as well use it in guard and condition too.
    @wrapt.decorator
    def wrapper(wrapped, instance, args, kwargs):
        # Exclude the instance variables added by superclasses
        exclude.update(instance.__dict__)
        x = wrapped(*args, **kwargs)
        if not include:
            # include set not given, so construct the implicit include set
            include.update(instance.__dict__)
            include.remove('_managed')
            include.difference_update(exclude)
        instance._managed.update(include)
        return x
    return wrapper


def condition(action_input=[], action_output=[]):
    """
    Decorator condition specifies the required input data and output space.
    Both parameters are lists of port names
    Return value is an ActionResult object

    FIXME:
    - Modify ActionResult to specify how many tokens were read/written from/to each port
      E.g. ActionResult.tokens_consumed/produced are dicts: {'port1':4, 'port2':1, ...}
      Since reading is done in the wrapper, tokens_consumed is fixed and given by action_input.
      The action fills in tokens_produced and the wrapper uses that info when writing to ports.
    - We can keep the @condition syntax by making the change in the normalize step below.
    """
    # #
    # # Normalize argument list (fill in a default repeat of 1 if not stated)
    # #
    #
    # action_input = [p if isinstance(p, (list, tuple)) else (p, 1) for p in action_input]
    # action_output = [p if isinstance(p, (list, tuple)) else (p, 1) for p in action_output]
    # contract_output = tuple(n for _, n in action_output)
    tokens_produced = len(action_output)
    tokens_consumed = len(action_input)

    def wrap(action_method):

        @functools.wraps(action_method)
        def condition_wrapper(self):
            #
            # Check if input ports have enough tokens. Note that all([]) evaluates to True
            #
            input_ok = all([self.inports[portname].tokens_available(1) for portname in action_input])
            #
            # Check if output port have enough free token slots
            #
            output_ok = all([self.outports[portname].tokens_available(1) for portname in action_output])

            if not input_ok or not output_ok:
                _log.debug("\t%s.%s Fired:N In:%s, Out:%s, Guard:X" % (self._name, action_method.__name__, "Y" if input_ok else "N", "Y" if output_ok else "N"))
                return ActionResult(did_fire=False, input_ok=input_ok, output_ok=output_ok)
            #
            # Build the arguments for the action from the input port(s)
            #
            args = []
            ex = {}
            for portname in action_input:
                port = self.inports[portname]
                token = port.peek_token()
                is_exception = isinstance(token, ExceptionToken)
                if is_exception:
                    ex.setdefault(portname, []).append(0)
                args.append(token if is_exception else token.value)

            #
            # Check for exceptional conditions
            #
            if ex:
                action_result = self.exception_handler(action_method, args, {'exceptions': ex})
            else:
                #
                # Perform the action (N.B. the method may be wrapped in a guard)
                #
                action_result = action_method(self, *args)
                # guard_str = "X" if action_result.guard_ok is None else ("Y" if action_result.guard_ok else "N")
                # _log.debug("\t%s.%s Fired:%s In:Y, Out:Y, Guard:%s" % (
                #     self._name, action_method.__name__, "Y" if action_result.did_fire else "N", guard_str))
{'fraction_non_alphanumeric': 0.08353444920202413, 'fraction_numerical': 0.003581159984429739, 'mean_word_length': 2.7137901127493493, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3354365', 'n_tokens_mistral': 3574, 'n_tokens_neox': 3421, 'n_words': 1230}